Jacky's blog
首页
  • Android
  • Web
  • Server
  • Python
  • iOS
  • Java
  • Vue
  • 计算机基础
  • AI
  • 全部工具
  • CLI 工具
  • 编辑器
  • 开发工具
  • 构建工具
  • 版本控制
  • 调试工具
  • 网络工具
  • 个人成长
  • 博客
  • 分类
  • 标签
  • 归档
收藏
GitHub (opens new window)

Jack Yang

编程; 随笔
首页
  • Android
  • Web
  • Server
  • Python
  • iOS
  • Java
  • Vue
  • 计算机基础
  • AI
  • 全部工具
  • CLI 工具
  • 编辑器
  • 开发工具
  • 构建工具
  • 版本控制
  • 调试工具
  • 网络工具
  • 个人成长
  • 博客
  • 分类
  • 标签
  • 归档
收藏
GitHub (opens new window)
  • 基础

  • AI 工具

  • 本地大模型

    • Ollama 本地大模型
    • LangChain + Ollama 本地 Agent
      • 环境准备
      • 核心代码结构
        • 1. 初始化本地模型
        • 2. 定义工具(@tool 装饰器)
        • 3. 创建 Agent(带记忆)
        • 4. 流式运行
      • 调试技巧
        • 查看完整事件流
      • 常见问题
        • Agent 不调用工具
        • 输出截断
        • 内存压力大
        • 记忆不生效
      • 依赖版本参考
  • NLP 基础

  • ai
  • local_llm
Jacky
2026-08-12
目录

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

确保 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. 定义工具(@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

# 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

# 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

# 调试技巧

# 查看完整事件流

用 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

# 常见问题

# 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

create_agent 的用法按 LangChain Agents 文档 (opens new window) 维护;ChatOllama 的模型接入与工具调用见 官方集成说明 (opens new window)。实际安装版本应锁定后验证,不能把包名清单当作可复现的版本锁。

#AI#agent#tutorial
上次更新: 2026/10/18, 22:14:48
Ollama 本地大模型
分词与 Token

← Ollama 本地大模型 分词与 Token→

最近更新
01
Codex 使用与会话管理指南
10-17
02
Tailscale 入门:让自己的设备跨网络互联
10-15
03
GitHub CLI(gh)工作流与 CI 排查
10-08
更多文章>
Theme by Vdoing | Copyright © 2019-2026 Jacky | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式