LangChain + Ollama 本地 Agent
# LangChain + Ollama 本地 Agent
本页维护 LangChain 1.x 风格的工具编排、事件与记忆示例。Ollama 安装和模型资源排查见 Ollama,概念见 AI 应用指南。示例已做 Python 语法检查,未在所有模型和硬件上验证效果。
# 环境准备
# 创建虚拟环境
python -m venv .venv
source .venv/bin/activate
# 安装依赖
pip install langchain-ollama langchain langgraph
1
2
3
4
5
6
2
3
4
5
6
确保 Ollama 服务已启动并拉取了模型:
ollama pull qwen3:8b
1
# 核心代码结构
# 1. 初始化本地模型
from langchain_ollama import ChatOllama
llm = ChatOllama(
model="qwen3:8b",
temperature=0,
base_url="http://localhost:11434",
num_ctx=8192, # 上下文窗口,内存小可设 4096
num_predict=2048 # 最大输出长度
)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 2. 定义工具(@tool 装饰器)
from langchain_core.tools import tool
@tool
def calculator(a: float, b: float, operation: str) -> str:
"""对两个数做运算,operation 可为 add、subtract、multiply、divide。"""
import operator
operations = {"add": operator.add, "subtract": operator.sub,
"multiply": operator.mul, "divide": operator.truediv}
if operation not in operations:
return "不支持的运算"
try:
return str(operations[operation](a, b))
except ZeroDivisionError:
return "除数不能为零"
@tool
def get_current_time() -> str:
"""获取当前日期和时间"""
from datetime import datetime
return f"当前时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
tools = [calculator, get_current_time]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 3. 创建 Agent(带记忆)
from langchain.agents import create_agent
from langgraph.checkpoint.memory import InMemorySaver
memory = InMemorySaver()
agent = create_agent(
model=llm,
tools=tools,
system_prompt="你是一个有用的AI助手,使用工具来帮助用户完成任务。",
checkpointer=memory
)
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 4. 流式运行
user_input = "请用工具计算 2 加 3,再告诉我当前时间"
config = {"configurable": {"thread_id": "local-demo"}}
for event in agent.stream(
{"messages": [{"role": "user", "content": user_input}]},
config,
stream_mode="values"
):
last_message = event["messages"][-1]
if last_message.type == "ai":
content = last_message.content or ""
# 过滤 deepseek-r1 思考过程
if "</think>" in content:
content = content.split("</think>")[-1].strip()
print(content, end="", flush=True)
# 显示工具调用
if hasattr(last_message, 'tool_calls') and last_message.tool_calls:
for tc in last_message.tool_calls:
print(f"\n [调用工具: {tc['name']}({tc['args']})]")
elif last_message.type == "tool":
print(f"\n [工具返回: {str(last_message.content)[:100]}]")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 调试技巧
# 查看完整事件流
用 debug_agent.py 思路,打印每个事件的详细信息:
event_count = 0
for event in agent.stream(
{"messages": [{"role": "user", "content": "计算 2+3"}]},
config,
stream_mode="values"
):
event_count += 1
messages = event.get("messages", [])
last_msg = messages[-1] if messages else None
print(f"--- 事件 {event_count} ---")
print(f"消息类型: {type(last_msg).__name__}")
print(f"role: {getattr(last_msg, 'role', 'N/A')}")
print(f"内容前100字: {str(getattr(last_msg, 'content', ''))[:100]}")
if hasattr(last_msg, 'tool_calls') and last_msg.tool_calls:
print(f"工具调用: {last_msg.tool_calls}")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 常见问题
# Agent 不调用工具
- 核对具体模型与 Ollama 版本的工具调用支持,不根据模型系列名称推断能力
- 检查工具 schema、参数和服务返回;低 temperature 不能保证会调用工具
- tool 的 docstring 要写清楚用途和参数
- system_prompt 明确告知"使用工具来完成任务"
# 输出截断
- 增大
num_predict参数 - 检查
num_ctx是否足够容纳历史消息
# 内存压力大
num_ctx从 8192 降到 4096- 换更小的模型(7B 代替 14B)
# 记忆不生效
- 确保传入了
checkpointer=memory - 同一对话复用
thread_id,不同对话使用不同值 - 内存 checkpointer 只在进程存活期间保存状态,需要跨重启恢复时使用持久化存储
这里的 thread_id 属于你自己的 LangGraph 应用,与 Codex 的 Thread ID 没有自动关联。
# 依赖版本参考
langchain-ollama
langchain
langgraph
1
2
3
2
3
create_agent 的用法按 LangChain Agents 文档 (opens new window) 维护;ChatOllama 的模型接入与工具调用见 官方集成说明 (opens new window)。实际安装版本应锁定后验证,不能把包名清单当作可复现的版本锁。
上次更新: 2026/10/18, 22:14:48