LangChain V1.0 Agent开发核心组件:用TaoToken统一Key打通LLM与工具链
1. LangChain V1.0 Agent 开发LLM、工具、记忆三大组件怎么协作LangChain V1.0 里的 Agent说白了就是一个会自己拿主意的执行框架。它跟传统写死流程的代码不一样传统代码是 if-else 一条道走到黑Agent 则是把大模型当大脑让它自己判断“这一步该不该调工具、调哪个工具、调完结果够不够、要不要再来一轮”。这个循环一直跑到模型给出最终答案或者撞上迭代上限才停。这套机制里真正干活的是三个组件LLM 负责推理决策工具负责跟外部世界打交道记忆负责把上下文留住。三者缺一不可——没有 LLM 就没有决策没有工具就只能空谈没有记忆每轮都像失忆。这篇就围绕这三块用 TaoToken 统一 Key 接入 LLM把 Agent 调用外部工具的完整链路跑通最后做一次端到端验证确认工具调用和记忆读写都正常返回。适合谁看已经会写点 Python、想上手 LangChain V1.0 Agent 的同学被多家模型 Key 管理搞烦、想用一个通道统一接入的同学以及想搞清楚 Agent 内部到底怎么转起来的同学。下面所有代码都能直接复制改改就跑。2. 用 TaoToken 统一 Key 接入 LLM省掉多供应商切换的麻烦LangChain V1.0 的模型层做了统一抽象ChatOpenAI这个类基本能对接所有兼容 OpenAI 协议的后端。这意味着你只要拿到一个 Base URL 和一个 API Key就能用同一套代码切换不同模型不用为每家供应商单独写适配。TaoToken 在这里扮演的就是这个统一通道的角色。官网在 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 端点是 https://taotoken.net/api 。你注册后在控制台生成一个 Key后面 LLM、工具链、记忆模块全都走这一个 Key省得在环境变量里塞一堆不同厂商的密钥。先把依赖装上pip install -U langchain[openai] langchain-openai python-dotenv然后在项目根目录建一个.env文件把 Key 和 Base URL 放进去。注意 Base URL 这里要带上/v1因为 OpenAI 兼容协议默认走这个路径TAOTOKEN_API_KEYsk-你的key TAOTOKEN_BASE_URLhttps://taotoken.net/api/v1接着初始化模型。这里用ChatOpenAI把base_url和api_key显式传进去避免环境变量名对不上导致 401import os from dotenv import load_dotenv from langchain_openai import ChatOpenAI load_dotenv() llm ChatOpenAI( modelgpt-4o-mini, api_keyos.getenv(TAOTOKEN_API_KEY), base_urlos.getenv(TAOTOKEN_BASE_URL), temperature0, timeout30, max_retries2, ) resp llm.invoke(用一句话说明什么是 Agent) print(resp.content)跑通这一步说明你的 Key 和通道没问题。如果这里就报 401先别往下走去第 5 节看排错。模型名可以按你账号里可用的来换gpt-4o-mini只是示例。有一点要提醒base_url结尾的/v1别漏很多人复制的时候只写到/api结果请求打到错误路径上返回 404 或者奇怪的解析错误。这个坑我踩过排查了半天才发现是路径少了一段。3. 可复制的 Agent 配置工具注册 记忆接入完整代码这一节是重点把 LLM、工具、记忆三块拼成一个能跑的 Agent。先定义工具再配记忆最后用create_agent组装起来。3.1 用 tool 装饰器注册工具工具是 Agent 的手脚。LangChain V1.0 里最省事的写法是tool装饰器函数的 docstring 会被当成工具描述喂给模型所以描述要写清楚参数含义模型才知道什么时候调、怎么传参from langchain_core.tools import tool tool def get_weather(city: str) - str: 查询指定城市的天气情况。 Args: city: 需要查询天气的城市名称例如北京。 fake_db {北京: 晴18℃, 上海: 多云22℃, 广州: 小雨26℃} return fake_db.get(city, f暂时查不到 {city} 的天气) tool def calculate(a: float, b: float, operation: str) - float: 对两个数字做四则运算。 Args: a: 第一个数字。 b: 第二个数字。 operation: 运算类型只能是 add、subtract、multiply、divide。 if operation add: return a b if operation subtract: return a - b if operation multiply: return a * b if operation divide: if b 0: raise ValueError(除数不能为零) return a / b raise ValueError(f不支持的运算类型: {operation})工具名、描述、参数 schema 这三样决定了模型调用准不准。名字要短描述要说清用途参数要有类型标注。parse_docstringTrue可以让 LangChain 从 docstring 里解析参数说明写复杂工具时更省心。3.2 配置记忆短期 checkpointer 长期 store记忆分两层。短期记忆用 checkpointer按thread_id保存每个会话的状态让 Agent 记得住多轮对话长期记忆用 store跨会话存用户偏好这类信息。开发阶段先用内存版跑通了再换数据库from langgraph.checkpoint.memory import InMemorySaver from langgraph.store.memory import InMemoryStore checkpointer InMemorySaver() store InMemoryStore()生产环境换成 Postgres 或 Redis 就行接口一样只是把InMemorySaver换成PostgresSaver或RedisSaver记得首次使用调一下setup()。3.3 组装 Agent把模型、工具、记忆三样交给create_agentfrom langchain.agents import create_agent agent create_agent( modelllm, tools[get_weather, calculate], system_prompt你是一个助手需要查天气或算数时请调用对应工具。, checkpointercheckpointer, storestore, )到这里 Agent 就搭好了。create_agent内部会基于 LangGraph 构建执行图自动处理“推理—调工具—观察—再推理”的循环你不用自己写 while 循环。4. 端到端验证确认工具调用与记忆读写都正常返回配置写完必须验证不然你不知道是模型没调工具还是工具调了但结果没回传。下面这段代码一次跑完工具调用和记忆读写两件事。config {configurable: {thread_id: user-001}} result agent.invoke( {messages: [{role: user, content: 北京天气怎么样顺便帮我算下 12 乘 8}]}, configconfig, ) for msg in result[messages]: print(type(msg).__name__, -, getattr(msg, content, ))正常输出里你会看到几类消息依次出现HumanMessage是用户输入AIMessage里带tool_calls表示模型决定调工具ToolMessage是工具返回结果最后一条AIMessage是整合后的最终回答。如果AIMessage的tool_calls是空的说明模型没触发工具多半是工具描述不够清楚。验证记忆读写再发一轮看它记不记得上一轮result2 agent.invoke( {messages: [{role: user, content: 我刚才问的是哪个城市}]}, configconfig, ) print(result2[messages][-1].content)因为两轮用了同一个thread_idcheckpointer 会把上一轮上下文带进来模型应该能答出“北京”。如果它说不知道检查thread_id是不是写成了不同的值或者 checkpointer 没传进create_agent。想更直观地看执行过程把stream_mode设成updates能看到每个节点执行后的状态增量for chunk in agent.stream( {messages: [{role: user, content: 上海天气}]}, configconfig, stream_modeupdates, ): print(chunk)5. 本篇常见报错排查401、local proxy failed、reading choices跑 Agent 时最容易卡在几个固定报错上这里逐个对照。401 UnauthorizedKey 不对或没读到。先确认.env里TAOTOKEN_API_KEY没有多余空格再确认load_dotenv()在读取环境变量之前调用。如果 Key 直接写在代码里检查有没有被引号包错。还有一种情况是base_url写成了https://taotoken.net/api少了/v1请求路径不对也会返回鉴权类错误。local proxy failed / connection error这类通常是网络层问题检查本机网络是否正常、base_url有没有拼错、端口有没有被占用。如果你在容器里跑确认容器能访问外网。别去折腾什么代理工具正常网络环境下直连即可。Error reading choices / 解析响应失败多半是base_url路径不对请求打到了非 OpenAI 兼容的端点上返回的 JSON 结构对不上。确认base_url是https://taotoken.net/api/v1模型名是账号里真实可用的。OAuth / 认证方式冲突如果你之前配过别的认证方式环境变量里可能残留了旧的OPENAI_API_KEYLangChain 会优先读它。把无关的旧变量清掉或者显式传api_key参数覆盖。工具没被调用不是报错但很常见。检查工具 docstring 是否描述了用途和参数system_prompt里有没有引导模型使用工具。工具描述太模糊模型就倾向于直接回答。排查顺序建议先单独llm.invoke确认通道通再加工具确认tool_calls出现最后加记忆确认多轮上下文。分层定位比一上来就跑完整 Agent 快得多。6. 把 Key 和通道固定下来Agent 开发才跑得顺Agent 开发最烦的不是写逻辑是环境不稳。模型通道今天通明天断、Key 到处散落、换个模型要改一堆配置这些琐事会吃掉大量调试时间。把 LLM 接入统一到一个通道上Base URL 和 Key 固定成环境变量工具和记忆各自独立配置整个项目结构就清爽了。后面你要扩展无非是加工具、换记忆后端、调模型参数这几件事核心链路不用动。想验证不同模型的表现可以直接在模型对话里试要长期跑编码类 Agent可以看下 Coding Plan接入文档和 API Key 管理都在控制台里。把这篇的配置存成模板下次开新项目直接复制能省不少重复劳动。