LangChain Agent 入门实战:从报错到跑通带记忆的交互式智能体(初学者保姆级教程)

LangChain Agent 入门实战:从报错到跑通带记忆的交互式智能体(初学者保姆级教程)

作者:风吹夏回

适合人群:零基础接触 LangChain Agent 的初学者,全程附可运行代码 + 踩坑解决方案

写在前面

大家好,我是风吹夏回。今天正式开始学习 LangChain 中的 Agent 智能体,从最开始的配置报错、无输出,一步步踩坑调试,最终跑通了带记忆能力的交互式对话 Agent

这篇文章完全以初学者视角记录整个学习过程,所有代码都经过实测可直接运行,同时把我踩过的坑全部标注了出来,大家跟着抄代码就能复现效果,不用再走弯路。

本次学习使用的技术栈:

  • 大模型:火山方舟豆包 doubao-seed-2.0-lite
  • 框架:LangChain + LangGraph
  • 运行环境:Python 虚拟环境 + Windows 系统

一、前置准备:环境与依赖

先把基础环境搭好,建议全程用虚拟环境,避免依赖冲突。

1. 安装核心依赖包

bash 复制代码
pip install langchain langchain-openai langchain-core langgraph python-dotenv

2. 配置 .env 文件

在项目根目录新建 .env 文件,填入你的模型配置:

env 复制代码
# 你的火山方舟API密钥
DEEPSEEK_API_KEY=ark-你的密钥
# 注意!必须是标准大模型接口,不能用coding接口
DEEPSEEK_BASE_URL=https://ark.cn-beijing.volces.com/api/v3

⚠️ 第一个坑预警:火山方舟的 api/coding/v3 是代码专属接口,不支持工具调用(Function Calling) ,一定要用 /api/v3 标准路径,否则Agent会没有任何输出。


二、第一阶段:第一个Agent的诞生

最开始我直接照着教程写,一运行就报错,先带大家把坑踩完,再跑通最简版本。

踩坑1:TavilySearch 密钥缺失报错

最开始的代码里加了 Tavily 搜索工具,运行直接报 Pydantic 校验错误:

复制代码
ValidationError: Did not find tavily_api_key, please add an environment variable `TAVILY_API_KEY`

原因 :Tavily 是第三方联网搜索工具,必须单独注册申请密钥。

初学者解决方案:先不用第三方工具,用自定义的本地工具先把 Agent 主流程跑通,获得正反馈最重要。

最简可运行 Agent 完整代码

我们先实现一个「天气查询工具」,让 Agent 自主判断什么时候调用它。

python 复制代码
from langchain.agents import create_agent
from langchain_openai import ChatOpenAI
from langchain_core.tools import tool
from dotenv import load_dotenv, find_dotenv
import os

# 加载环境变量
dotenv_path = find_dotenv()
load_dotenv(dotenv_path, override=True)

api_key = os.getenv("DEEPSEEK_API_KEY")
base_url = os.getenv("DEEPSEEK_BASE_URL")

# 1. 初始化大模型
llm = ChatOpenAI(
    model="doubao-seed-2.0-lite",
    api_key=api_key,
    base_url=base_url,
    temperature=0.7,
)

# 2. 定义自定义工具:天气查询
@tool
def get_weather(city: str) -> str:
    """查询指定城市的实时天气情况,输入为城市名称,如北京、上海"""
    return f"{city}今日天气:晴转多云,24-31℃,东南风2级"

# 工具列表
tools = [get_weather]

# 3. 创建 Agent
agent = create_agent(
    model=llm,
    tools=tools,
    system_prompt="你是一个智能助手,请根据用户的需求调用合适的工具来帮助他们。",
)

if __name__ == "__main__":
    print("开始测试Agent...")
    # 一次性调用,查看完整执行链路
    result = agent.invoke({
        "messages": [{"role": "user", "content": "北京今天天气怎么样?"}]
    })
    
    print("\n=== 完整执行链路 ===")
    for msg in result["messages"]:
        print(f"[{msg.type}]: {msg.content}")
        if hasattr(msg, "tool_calls") and msg.tool_calls:
            print(f"  工具调用: {msg.tool_calls}")

运行后你会看到

输出会清晰展示 Agent 的完整工作循环:

  1. user:用户提问
  2. ai:模型推理,决定调用 get_weather 工具,参数为 北京
  3. tool:工具执行,返回天气结果
  4. ai:模型根据工具结果,生成自然语言最终回答

这就是 Agent 最核心的「感知→推理→行动→回复」循环,全程没有我们手动控制流程,完全是模型自主决策。


三、第二阶段:给Agent加上记忆

跑通基础版后你会发现:每次调用都是"失忆"的,上一轮说过的话下一轮就忘了。这显然不符合真实使用场景,接下来我们给 Agent 加上记忆能力。

核心概念

  • Checkpointer:记忆存储器,自动保存每一轮的对话消息
  • Thread ID:会话标识,同一个ID对应同一份记忆,不同ID完全隔离,用来区分不同用户

带记忆的 Agent 完整代码

只需要在之前的代码上新增3行核心代码即可:

python 复制代码
from langchain.agents import create_agent
from langchain_openai import ChatOpenAI
from langchain_core.tools import tool
from dotenv import load_dotenv, find_dotenv
import os
# 新增:导入内存存储器
from langgraph.checkpoint.memory import InMemorySaver

dotenv_path = find_dotenv()
load_dotenv(dotenv_path, override=True)

api_key = os.getenv("DEEPSEEK_API_KEY")
base_url = os.getenv("DEEPSEEK_BASE_URL")

llm = ChatOpenAI(
    model="doubao-seed-2.0-lite",
    api_key=api_key,
    base_url=base_url,
    temperature=0.7,
)

@tool
def get_weather(city: str) -> str:
    """查询指定城市的实时天气情况,输入为城市名称,如北京、上海"""
    return f"{city}今日天气:晴转多云,24-31℃,东南风2级"

tools = [get_weather]

# 新增:创建记忆存储器
checkpointer = InMemorySaver()

agent = create_agent(
    model=llm,
    tools=tools,
    system_prompt="你是一个智能助手,请根据用户的需求调用合适的工具来帮助他们。",
    # 新增:传入记忆存储器
    checkpointer=checkpointer,
)

if __name__ == "__main__":
    # 同一个 thread_id 代表同一场对话
    config = {"configurable": {"thread_id": "user_001"}}

    print("="*50)
    print("第1轮对话")
    print("="*50)
    result1 = agent.invoke(
        {"messages": [{"role": "user", "content": "你好,我叫小明,在北京"}]},
        config=config
    )
    print("AI回复:", result1["messages"][-1].content)

    print("\n" + "="*50)
    print("第2轮对话(相同thread_id,有记忆)")
    print("="*50)
    result2 = agent.invoke(
        {"messages": [{"role": "user", "content": "我叫什么名字?我所在的城市今天天气怎么样?"}]},
        config=config
    )
    print("AI回复:", result2["messages"][-1].content)

    print("\n" + "="*50)
    print("第3轮对话(换thread_id,无记忆)")
    print("="*50)
    result3 = agent.invoke(
        {"messages": [{"role": "user", "content": "我叫什么名字?"}]},
        config={"configurable": {"thread_id": "user_002"}}
    )
    print("AI回复:", result3["messages"][-1].content)

效果验证

  • 第2轮:Agent能准确说出你的名字,并且自动调用天气工具查询北京天气 → 记忆生效
  • 第3轮:更换 Thread ID 后,Agent表示不知道你的名字 → 会话完全隔离

💡 小提示:InMemorySaver 是内存存储,程序重启后记忆会清空,适合开发调试。生产环境可以换成 SqliteSaverRedisSaver 做持久化存储。


四、第三阶段:升级交互式对话

到这里功能都跑通了,但每次都要改代码输入问题太麻烦。我们把它改造成实时聊天模式,像跟微信聊天一样和 Agent 对话,体验感直接拉满。

交互式对话完整代码

输入 退出exit 即可结束程序,全程保留记忆,还能看到 Agent 的思考和工具调用过程。

python 复制代码
from langchain.agents import create_agent
from langchain_openai import ChatOpenAI
from langchain_core.tools import tool
from dotenv import load_dotenv, find_dotenv
import os
from langgraph.checkpoint.memory import InMemorySaver

# 加载环境变量
dotenv_path = find_dotenv()
load_dotenv(dotenv_path, override=True)

api_key = os.getenv("DEEPSEEK_API_KEY")
base_url = os.getenv("DEEPSEEK_BASE_URL")

# 初始化大模型
llm = ChatOpenAI(
    model="doubao-seed-2.0-lite",
    api_key=api_key,
    base_url=base_url,
    temperature=0.7,
)

# 自定义工具
@tool
def get_weather(city: str) -> str:
    """查询指定城市的实时天气情况,输入为城市名称,如北京、上海"""
    return f"{city}今日天气:晴转多云,24-31℃,东南风2级"

tools = [get_weather]

# 记忆配置:固定会话ID,全程保留记忆
checkpointer = InMemorySaver()
config = {"configurable": {"thread_id": "chat_session_001"}}

# 创建 Agent
agent = create_agent(
    model=llm,
    tools=tools,
    system_prompt="你是一个智能助手,请根据用户的需求调用合适的工具来帮助他们。",
    checkpointer=checkpointer,
)

# 交互式对话主程序
if __name__ == "__main__":
    print("=" * 60)
    print("🤖 Agent 交互式对话已启动")
    print("💡 输入问题即可对话,输入 退出/exit/quit 结束")
    print("=" * 60 + "\n")

    while True:
        # 获取用户输入
        user_input = input("👤 你:").strip()

        # 退出判断
        if user_input.lower() in ["退出", "exit", "quit"]:
            print("\n👋 对话已结束,再见!")
            break

        # 空输入跳过
        if not user_input:
            continue

        print("-" * 60)

        # 流式执行,展示完整过程
        for step_index, step in enumerate(agent.stream(
            {"messages": [{"role": "user", "content": user_input}]},
            config=config
        ), start=1):
            # 兼容不同版本的返回结构
            messages = step.get("messages", [])
            if not messages:
                for key in step:
                    if isinstance(step[key], dict) and "messages" in step[key]:
                        messages = step[key]["messages"]
                        break
            if not messages:
                continue

            last_msg = messages[-1]

            # 模型决定调用工具
            if last_msg.type == "ai" and last_msg.tool_calls:
                print(f"🧠 [思考中] 决定调用工具:")
                for tool_call in last_msg.tool_calls:
                    print(f"   └─ 工具:{tool_call['name']},参数:{tool_call['args']}")

            # 工具执行返回结果
            elif last_msg.type == "tool":
                print(f"🔧 [工具执行] 返回结果:{last_msg.content}")

            # 最终回复
            elif last_msg.type == "ai" and not last_msg.tool_calls:
                print(f"\n🤖 Agent:{last_msg.content}")

        print("-" * 60 + "\n")

推荐体验流程

大家可以按这个顺序测试,完整感受记忆 + 工具调用的能力:

  1. 第一轮输入:我叫小明,我在长沙
  2. 第二轮输入:我叫什么名字?
  3. 第三轮输入:我所在的城市今天天气怎么样?
  4. 第四轮输入:刚才我们聊了什么?

五、今天踩过的坑总结

作为初学者,这几个坑非常容易踩,特意整理出来帮大家避坑:

报错/问题 原因 解决方案
TavilySearch 报 value_error 缺少密钥 没有配置 Tavily 的 API Key 初学者先移除第三方工具,用自定义工具先跑通主流程
程序正常退出但没有任何输出 用了 coding 专属接口,不支持工具调用 把 base_url 改成标准路径 /api/v3
记忆不生效 调用时没传 config 和 thread_id 每次 invoke/stream 都必须传入带 thread_id 的 config
流式输出什么都不打印 返回结构和判断条件不匹配 先打印原始 step 的键名,再适配结构

六、下一步学习规划

今天把 Agent 的核心基础都跑通了,接下来的学习路线:

  1. 消息压缩中间件:解决长对话 Token 膨胀的问题
  2. 人工审核中间件:给高风险操作加上人类确认环节
  3. MCP 协议:标准化接入第三方工具服务
  4. 综合项目:做一个完整的智能客服 Agent

后续我会继续更新学习笔记,把每一步的实战代码和踩坑记录都分享出来。


最后

作为初学者,学习 Agent 不用一开始就堆很多功能,先跑通最小 Demo,理解核心的「自主决策循环」,再一步步加能力,是最稳妥的学习方式。

如果这篇文章对你有帮助,欢迎点赞收藏~ 有问题也可以在评论区交流,我们一起进步!

相关推荐
大鹅同志20 小时前
Agent Runtime Evaluation Platform — AI Agent 运行时全维度质量评估平台
ai·langchain·agent·rag·langgraph·vibecoding·llm-as-judge
闲猫1 天前
深入理解 Skills:从 API 调用到智能体行为封装
人工智能·python·langchain
BraveWang1 天前
【LangChain 1.x】02、LangChain 1.x 快速上手
langchain
白白白飘1 天前
【9】Langchain实战案例:构建一个聊天机器人
microsoft·langchain·机器人
白白白飘1 天前
【8】补充与拓展:Langchain的联网搜索Agent,使用Tavily工具
服务器·网络·langchain
爱奥尼欧1 天前
【LangChain】2.提示词工程
人工智能·microsoft·langchain
白白白飘1 天前
【10】Langchain读取数据库
数据库·langchain
陳陈陳2 天前
🤖 Agent开发完全指南:从LLM到智能体的蜕变之旅
langchain·llm·agent
倾颜2 天前
AI Mind 的多会话短期记忆容器:如何隔离多个聊天上下文
langchain·agent·next.js