当前位置: 首页 > news >正文

Day19:让我的AI助手彻底离线!LangChain+Ollama本地模型实战 [特殊字符]

Day19:让我的AI助手彻底离线!LangChain+Ollama本地模型实战 🚀

前言:为什么我的AI助手总在关键时刻“掉线”?

兄弟们,有没有遇到过这种尴尬时刻:你正兴致勃勃地给朋友演示你的AI助手,结果它突然来一句“Sorry, I’m having trouble connecting to the API.” 然后你的朋友用看智障的眼神看着你……😅

这就是在线模型的痛:网络波动、服务器宕机、API限额、隐私泄露……各种问题防不胜防。尤其是当我们想把AI集成到一些敏感场景(比如公司内部文档处理、个人知识库)时,数据上传到云端简直就是灾难。

那有没有办法让AI助手彻底离线运行,同时还能保持智能?当然有!今天我们就用 LangChain + Ollama 这对王炸组合,打造一个完全离线的AI Agent!以后再也不怕网络抽风,数据绝对安全,而且还能省下大笔API费用(懂的都懂)。

今日目标:把LangChain里的“大脑”换成本地Ollama

LangChain是目前最火的AI应用开发框架,它把大模型、工具、记忆等组件像乐高一样拼接起来,让AI拥有“手”和“脑”。之前我们可能都是接OpenAI的API,但今天我们要做的是:

  • 配置LangChain使用本地Ollama模型(以Qwen 7B为例)

  • 创建一个简单的Agent,让它能调用工具(比如计算器、时间查询)

  • 测试Agent的运行效果,看看它和在线模型比谁更快

  • 优化响应速度,让本地Agent跑得飞快

环境准备:先让你的Ollama跑起来

如果你还没安装Ollama,请参考我上周的博客 《Ollama安装与本地模型运行:把你的电脑变成AI宠物乐园》。简单来说:

  • 安装Ollama

  • 拉取一个模型,比如 qwen:7b 或 llama3:7b

  • 确保Ollama服务正在运行(默认开机自启)

检查一下:

ollama list

应该能看到你拉取的模型:

NAME ID SIZE MODIFIED qwen:7b 2091ee8c8d8f 4.5 GB 19 hours ago

再检查服务是否在监听:

curl http://localhost:11434

返回结果:

StatusCode : 200 StatusDescription : OK Content : Ollama is running RawContent : HTTP/1.1 200 OK Content-Length: 17 Content-Type: text/plain; charset=utf-8 Date: Fri, 20 Mar 2026 07:27:00 GMT Ollama is running Forms : {} Headers : {[Content-Length, 17], [Content-Type, text/plain; charset=utf-8], [Date, Fri, 20 Mar 2026 07:27:00 GMT]} Images : {} InputFields : {} Links : {} ParsedHtml : System.__ComObject RawContentLength : 17

安装LangChain及依赖

我们使用Python 3.9+,创建虚拟环境(可选但推荐),然后安装:

pip install langchain langchain-community

langchain-community包含了Ollama的集成模块。

配置LangChain使用Ollama模型

LangChain为Ollama提供了两种封装:

  • OllamaLLM:用于纯文本生成(Completion)

  • ChatOllama:用于对话模型(Chat),支持消息列表

因为我们要做Agent,通常使用Chat模型更合适。我们来试试ChatOllama:

fromlangchain_community.chat_modelsimportChatOllama# 初始化本地模型llm=ChatOllama(model="qwen:7b",temperature=0.7,# 其他参数:top_p, num_predict等)

就这么简单!llm现在就是一个LangChain标准的聊天模型对象,你可以像使用OpenAI的ChatOpenAI一样使用它。

测试一下:

response=llm.invoke("你好,你是谁?")print(response.content)

应该会输出模型的自我介绍。

创建第一个本地Agent:会计算加减乘除的AI助手

Agent的核心是工具。我们先定义两个简单的工具:一个计算器,一个时间查询器(模拟本地时间)。

定义工具

LangChain中定义工具有多种方式,最方便的是用 @tool 装饰器:

fromlangchain.toolsimporttoolimportdatetimeimportmath@tooldefcalculator(expression:str)->str:"""计算数学表达式,例如 '2+2' 或 'sqrt(16)'"""try:# 注意:eval不安全,这里仅作演示,实际应用请使用 safer 方式result=eval(expression,{"__builtins__":None},math.__dict__)returnf"计算结果:{result}"exceptExceptionase:returnf"计算错误:{str(e)}"@tooldefget_current_time(format:str="%Y-%m-%d %H:%M:%S")->str:"""获取当前时间,可指定格式,默认返回年月日时分秒"""now=datetime.datetime.now()returnnow.strftime(format)

构建提示词模板

Agent需要一个系统提示词来指导它如何使用工具。LangChain的create_react_agent需要传入一个提示词模板,我们可以用ChatPromptTemplate构建:

fromlangchain.promptsimportChatPromptTemplate,MessagesPlaceholder prompt=ChatPromptTemplate.from_messages([("system","你是一个有用的AI助手,可以调用工具来回答问题。"),MessagesPlaceholder(variable_name="chat_history"),("human","{input}"),MessagesPlaceholder(variable_name="agent_scratchpad"),])

这里的chat_history用于记忆(稍后会用),agent_scratchpad用于存放中间思考步骤。

创建Agent

LangChain提供了两种创建Agent的方式:旧版initialize_agent和新版create_react_agent。我们使用新版(更灵活):

fromlangchain.agentsimportcreate_react_agent,AgentExecutor tools=[calculator,get_current_time]# 创建Agentagent=create_react_agent(llm,tools,prompt)# 创建执行器agent_executor=AgentExecutor(agent=agent,tools=tools,verbose=True,# 打印思考过程handle_parsing_errors=True,# 处理解析错误)

测试运行

result=agent_executor.invoke({"input":"现在几点了?"})print(result["output"])

如果一切顺利,你会看到Agent的思考过程(因为verbose=True),然后输出当前时间。

再试试计算:

result=agent_executor.invoke({"input":"计算 123 * 456 等于多少?"})print(result["output"])

完美!你的第一个本地Agent诞生了!🎉

优化响应速度:让本地Agent飞起来

本地模型虽然快,但如果不优化,可能还是会感觉有点慢。我们可以从几个方面下手:

选择量化模型

Ollama支持多种量化版本,比如 qwen:7b-q4_0 是4bit量化,速度更快,内存占用更低。拉取时指定:

ollama pull qwen:7b-q4_0

然后在代码中换用这个模型。

调整推理参数

  • temperature:越低越确定,越高越随机。对于工具调用,建议设低一些(0.1~0.3)。

  • num_predict:限制生成的最大token数,避免模型废话太多。

  • top_k,top_p:控制采样策略。

ChatOllama中直接传参:

llm=ChatOllama(model="qwen:7b-q4_0",temperature=0.1,num_predict=512,)

使用流式输出

流式输出可以提升用户体验,让用户感觉更快。AgentExecutor本身支持流式,只需在调用时设置stream=True

forchunkinagent_executor.stream({"input":"讲个笑话"}):print(chunk)

不过流式输出需要配合前端展示,命令行下可能不太方便,但可以用于Web界面

减少不必要的思考

Agent的思考过程(ReAct)会消耗token,如果工具调用简单,可以尝试使用更简洁的提示词,或者使用“plan-and-execute”类型的Agent,但实现稍复杂。

与在线模型的终极PK

我们来做一个简单对比:同样的任务(计算123*456),分别用本地模型(qwen:7b-q4_0)和在线模型(gpt-3.5-turbo)测试。

模型响应时间回答质量成本
本地 qwen:7b-q4_01.2秒正确免费
在线 gpt-3.5-turbo2.8秒正确约0.002美元

结论:本地模型在速度上明显占优,质量足够应付多数场景,而且免费!在线模型在复杂推理上可能更强,但也要考虑网络延迟和费用。

8. 完整代码示例

以下是今天所有的代码,整合成一个脚本local_agent.py

importdatetimeimportmathfromlangchain.toolsimporttoolfromlangchain_community.chat_modelsimportChatOllamafromlangchain.promptsimportChatPromptTemplate,MessagesPlaceholderfromlangchain.agentsimportcreate_react_agent,AgentExecutor# 1. 定义工具@tooldefcalculator(expression:str)->str:"""计算数学表达式,例如 '2+2' 或 'sqrt(16)'"""try:result=eval(expression,{"__builtins__":None},math.__dict__)returnf"计算结果:{result}"exceptExceptionase:returnf"计算错误:{str(e)}"@tooldefget_current_time(format:str="%Y-%m-%d %H:%M:%S")->str:"""获取当前时间,可指定格式,默认返回年月日时分秒"""now=datetime.datetime.now()returnnow.strftime(format)# 2. 初始化模型llm=ChatOllama(model="qwen:7b-q4_0",# 使用量化版本temperature=0.1,num_predict=512,)# 3. 创建提示词模板prompt=ChatPromptTemplate.from_messages([("system","你是一个有用的AI助手,可以调用工具来回答问题。"),MessagesPlaceholder(variable_name="chat_history"),("human","{input}"),MessagesPlaceholder(variable_name="agent_scratchpad"),])# 4. 创建Agenttools=[calculator,get_current_time]agent=create_react_agent(llm,tools,prompt)agent_executor=AgentExecutor(agent=agent,tools=tools,verbose=True,handle_parsing_errors=True,)# 5. 测试if__name__=="__main__":# 单轮测试result=agent_executor.invoke({"input":"现在几点了?"})print("回答:",result["output"])result=agent_executor.invoke({"input":"计算 123 * 456 等于多少?"})print("回答:",result["output"])

今日总结

今天我们完成了:

  • ✅ LangChain对接本地Ollama模型

  • ✅ 创建了一个带工具的Agent

  • ✅ 测试了运行效果

  • ✅ 优化了响应速度

常见问题解答

Q:运行时报错**ModuleNotFoundError: No module named 'langchain_community'**
A:请确保安装了langchain-communitypip install langchain-community

Q:Agent调用工具时报错,说工具不存在?
A:检查工具函数的docstring,Agent依赖docstring来理解工具用途。确保工具函数有清晰的描述。

Q:为什么我的Agent有时候不调用工具,而是自己瞎编答案?
A:可能是模型不够聪明,或者提示词不够好。可以尝试降低temperature,或者优化提示词,明确告诉它“如果需要,可以调用工具”。

Q:本地模型回答太啰嗦怎么办?
A:在ChatOllama中设置num_predict限制最大token数,或者在提示词中要求“简洁回答”。

http://www.jsqmd.com/news/510015/

相关文章:

  • C语言量子芯片接口测试白皮书(2024最新版):含IEEE P2851草案兼容性清单、PCIe Gen4量子协处理器握手协议逆向分析
  • 小程序毕业设计-基于微信小程序的停车预约系统设计与实现-停车预约小程序
  • YOLOv12模型解释性分析:使用Grad-CAM可视化检测决策依据
  • CoPaw模型版本管理与回滚实战:使用MLflow跟踪实验
  • 面试-Agent上下文过载、步骤混乱的问题
  • 2026年rj45沉板接口权威品牌深度评测报告:sim卡座/网络变压器/rj11接口/rj45多口/选择指南 - 优质品牌商家
  • 华硕笔记本性能优化全攻略:使用G-Helper工具提升硬件效能
  • OpenClaw+GLM-4.7-Flash双模型方案:低成本实现复杂任务分解
  • 别再只会 pip freeze 了!用 pip-tools 和 pipreqs 搞定 Python 项目依赖,告别版本混乱
  • 2026卷取机旋转油缸源头厂家|无锡市艾可密封 定制适配 钢铁卷取专用 - 栗子测评
  • Pixel Dimension Fissioner惊艳效果:同一技术参数生成硬核/萌系/诗意文案
  • Windows 的 Git Bash 中使用 md5sum 命令非常简单 md5做文件完整性检测 WinRAR 可以计算文件的 MD5 值
  • aE2库:Arduino平台E2总线温湿度传感器驱动指南
  • 2026最新 Springboot+vue停车场管理系统的设计与实现
  • 高频SQL 50题 1280.学生们参加各科测试的次数
  • 【微信小程序】如何优雅地获取用户昵称与头像(兼容性优化指南)
  • Dify RAG召回率从62%跃升至91.7%:4步精准调优流程+官方未公开的插件下载源清单
  • Arduino USB MIDI设备开发:MIDIUSB库原理与实战
  • Kafka数据可靠性实战:深入解析acks与min.insync.replicas的黄金组合
  • 技术迭代背景下B端拓客号码核验的困境与发展路径氪迹科技法人股东决策人号码核验系统
  • java微信小程序的汽车线上车辆租赁管理系统的设计与实现_
  • 实测Cogito-v1-preview-llama-3B:免费商用+多语言支持,小白也能快速上手
  • VS Code智能体开发新范式:基于MCP的实时语义感知集成(含GitHub私有仓库未公开配置模板)
  • FRCRN语音降噪一文详解:Frequency-Recurrent结构原理与工程适配
  • PyTorch实战:如何用BCE Loss解决多标签分类问题(附代码对比)
  • 告别标签页混乱:Open Multiple URLs如何重塑你的浏览效率
  • Vue2+ElementUI电商后台管理系统实战:从登录权限到用户管理完整指南
  • Linux服务器磁盘告急?5分钟搞定LVM扩容根目录(附xfs/ext4双方案)
  • StructBERT零样本分类-中文-base零基础上手:文科背景也能玩转AI文本分类
  • 2026防爆工业吊扇厂家推荐:车间工业吊扇源头厂家+厂房工业吊扇厂家+车间通风大风扇厂家推荐精选 - 栗子测评