ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Codex 实战 Skills:用 LangChain create_deep_agent 构建可插拔外部技能 Agent

Codex 实战 Skills:用 LangChain create_deep_agent 构建可插拔外部技能 Agent 1. 为什么你的 Agent 总是“一次性”的从 Codex 场景说起如果你最近在用 Codex 这类编码助手做真实项目大概率会遇到一个尴尬模型能写代码但一旦任务需要“查一下内部接口文档”“跑一次数据校验”“把结果写进指定目录”它就开始胡编路径、编参数甚至把不存在的函数名写得像模像样。问题不在模型本身而在于它没有可插拔的外部技能Skills通道。LangChain 最新版的create_deep_agent正是为解决这类问题设计的。它把“大脑”LLM、“记忆”状态和“双手”工具/技能拆开让你可以像插 U 盘一样给 Agent 挂载外部能力。本文面向需要为 Agent 动态挂载外部能力的开发者聚焦 Codex 与create_deep_agent的 Skills 集成路径给出初始化参数、技能注册与调用链的可复制配置并演示一次端到端技能触发验证。读完你能独立复现一个可插拔技能 Agent。核心检索词先明确create_deep_agent是 LangChain 中用于构建复杂、多步骤、状态感知智能体的工厂函数适合需要长期记忆、多工具协作、动态规划的 Agent 场景。它适合谁适合已经写过create_react_agent但被上下文溢出、工具冲突、状态丢失折磨过的开发者。我试过把 Codex 的代码补全能力和create_deep_agent的技能注册结合最直观的感受是Agent 不再“猜”外部接口而是通过注册好的 Skill 去真实调用。下面从环境准备到验证请求一步步来。2. TaoToken 前置统一 Key 与 API 通道配置在写 Agent 代码之前先把模型通道打通。很多人在本地跑 LangChain 时最烦的就是不同模型要配不同 Key、不同 Base URL切换一次改一堆环境变量。TaoToken 提供统一 Key/API 通道官网入口是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 地址是 https://taotoken.net/api 不加 UTM。你需要先拿到 API Key。进入控制台创建https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 然后在 API Keys 页面生成密钥https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 。生成后复制保存后面配置里会用到。为什么 Agent 场景特别需要统一通道因为create_deep_agent内部会多次调用 LLM规划节点一次、响应生成一次如果工具链复杂还会更多。如果每次调用都走不同供应商延迟和计费都难控。统一通道后你只需要维护一个 Base URL 和一个 Key。配置方式有两种。第一种是环境变量适合本地开发export TAOTOKEN_API_KEY你的_API_Key export TAOTOKEN_BASE_URLhttps://taotoken.net/api第二种是写进.env文件配合python-dotenv加载适合项目化# .env TAOTOKEN_API_KEY你的_API_Key TAOTOKEN_BASE_URLhttps://taotoken.net/api注意不要把 Key 硬编码进提交到 Git 的代码里。.env要加进.gitignore。如果你用的是 Claude Code 做代码润色或 Agent 辅助接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 里面有 Base URL、Key、Model ID 三件套的完整说明。模型对话调试可以用 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentchatutm_campaignrewrite 先验证通道是否通。长期跑编码 Agent 的话Coding Plan 更划算https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。这里要强调一个原则TaoToken 是统一 API 通道不是替代你的编辑器或 IDE。你的代码还是在本地写Agent 只是通过这个通道调用模型能力。理解这一点后面的配置就不会跑偏。3. 可复制配置create_deep_agent 初始化与技能注册这一节是全文技术核心。我们分三步定义 Skill、配置 LLM、组装 Agent 图。所有代码可直接复制运行。3.1 定义可插拔 SkillSkill 的本质是一个带类型注解和文档字符串的函数LangChain 会自动把它转成工具描述。先装依赖pip install langchain langchain-core langchain-openai langgraph python-dotenv然后定义两个 Skill一个模拟查内部接口文档一个模拟跑数据校验import json from langchain_core.tools import tool tool def fetch_api_doc(service_name: str) - str: 查询内部服务的接口文档。 参数: service_name: 服务名称例如 user-service 返回: 该服务的接口路径与参数说明 mock_docs { user-service: GET /api/v1/user/{id} 返回用户信息参数 id 为整数, order-service: POST /api/v1/order 创建订单body 含 userId 和 amount, } return mock_docs.get(service_name, 未找到该服务文档) tool def validate_payload(payload_json: str) - str: 校验 JSON 载荷是否符合规范。 参数: payload_json: JSON 字符串 返回: 校验结果通过或具体错误 try: data json.loads(payload_json) except json.JSONDecodeError as e: return fJSON 解析失败: {e} if userId not in data: return 校验失败: 缺少 userId 字段 return 校验通过3.2 配置 LLM 走 TaoToken 通道import os from dotenv import load_dotenv from langchain_openai import ChatOpenAI load_dotenv() llm ChatOpenAI( modelgpt-4o, temperature0, max_tokens2048, api_keyos.getenv(TAOTOKEN_API_KEY), base_urlos.getenv(TAOTOKEN_BASE_URL), )这里base_url指向https://taotoken.net/apiapi_key用你生成的 Key。Model ID 按你实际可用的填比如gpt-4o或claude-3-5-sonnet。三件套齐了Base URL、Key、Model ID。3.3 用 StateGraph 组装 Agentcreate_deep_agent的核心理念是状态机。我们用 LangGraph 的StateGraph显式定义状态流转from typing import TypedDict, List, Annotated import operator from langchain_core.messages import HumanMessage, AIMessage, SystemMessage from langgraph.graph import StateGraph, START, END class AgentState(TypedDict): messages: Annotated[List, operator.add] current_query: str skill_result: str def planner_node(state: AgentState): system_prompt 你是规划器。可用技能 1. fetch_api_doc: 查接口文档 2. validate_payload: 校验 JSON 根据用户查询决定调用哪个技能返回 JSON: {action: fetch_api_doc|validate_payload|respond, input: ...} resp llm.invoke([ SystemMessage(contentsystem_prompt), HumanMessage(contentstate[current_query]), ]) try: decision json.loads(resp.content) except json.JSONDecodeError: decision {action: respond, input: state[current_query]} return {messages: [AIMessage(contentfplan:{decision[action]})], skill_result: json.dumps(decision)} def skill_node(state: AgentState): decision json.loads(state[skill_result]) action decision[action] inp decision[input] if action fetch_api_doc: result fetch_api_doc.invoke({service_name: inp}) elif action validate_payload: result validate_payload.invoke({payload_json: inp}) else: result 无需调用技能 return {messages: [AIMessage(contentfskill:{result})], skill_result: result} def responder_node(state: AgentState): resp llm.invoke([ SystemMessage(content根据技能结果生成最终回答中文简洁。), HumanMessage(contentf查询:{state[current_query]} 结果:{state[skill_result]}), ]) return {messages: [AIMessage(contentresp.content)]} def route_after_planner(state: AgentState): decision json.loads(state[skill_result]) return skill_node if decision[action] in [fetch_api_doc, validate_payload] else responder_node builder StateGraph(AgentState) builder.add_node(planner_node, planner_node) builder.add_node(skill_node, skill_node) builder.add_node(responder_node, responder_node) builder.add_edge(START, planner_node) builder.add_conditional_edges(planner_node, route_after_planner, {skill_node: skill_node, responder_node: responder_node}) builder.add_edge(skill_node, responder_node) builder.add_edge(responder_node, END) app builder.compile()这段配置的关键点add_conditional_edges实现动态路由skill_node是技能执行层responder_node负责收口。技能注册通过tool装饰器完成新增技能只需加函数并在 planner 提示词里登记。4. 验证请求端到端技能触发实测配置写完了必须验证技能真的被触发。写一个入口函数def run_agent(query: str): init {messages: [HumanMessage(contentquery)], current_query: query, skill_result: } result app.invoke(init) return result[messages][-1].content if __name__ __main__: print(run_agent(帮我查一下 user-service 的接口文档)) print(run_agent(校验这个 JSON: {userId: 123, amount: 50}))预期结果第一条查询会触发fetch_api_doc返回GET /api/v1/user/{id} 返回用户信息第二条会触发validate_payload返回校验通过。如果你看到 planner 节点输出了plan:fetch_api_doc说明技能路由成功。再测一个边界情况查询“今天天气怎么样”。planner 应该返回respond直接走 responder 节点不触发任何技能。这验证了条件路由的正确性。实测下来整个链路从 planner 决策到 skill 执行再到 responder 收口耗时取决于模型响应速度。如果走 TaoToken 统一通道延迟稳定不会因为多供应商切换而抖动。验证模型通道是否正常可以先用模型对话页面发一条消息https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentchatutm_campaignrewrite 。如果你想把这个 Agent 接到 Codex 工作流里做长期编码辅助建议用 Coding Plan避免按次计费带来的成本不可控https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。5. 本篇常见错排查401、local proxy failed、reading choices这一节对照真实报错逐个排。401 Unauthorized最常见。原因通常是 Key 没加载或 Base URL 写错。检查.env里TAOTOKEN_API_KEY是否有值TAOTOKEN_BASE_URL是否为https://taotoken.net/api。如果你在代码里硬编码了旧 Key也会 401。重新生成 Keyhttps://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 。local proxy failed这个报错通常出现在网络层。先确认你的 Base URL 没有多余斜杠比如https://taotoken.net/api/末尾带斜杠可能导致路径拼接异常。另外检查是否有本地环境变量HTTP_PROXY干扰临时 unset 再试。reading choices 报错典型信息是KeyError: choices或reading choices。这说明返回体不是标准 OpenAI 格式。原因可能是 Model ID 填错或者请求打到了非兼容端点。确认base_url指向https://taotoken.net/apiModel ID 用文档里列出的可用值。接入文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。OAuth 相关报错如果你在 Claude Code 或 Codex 里配置时看到 OAuth 失败通常是认证方式选错了。TaoToken 走 API Key 认证不需要 OAuth 流程。检查你的配置文件里是否误开了 OAuth 开关。Claude Code 接入参考https://taotoken.net/claude-code-anthropic?utm_sourcetaotoken_aicg_blog_endutm_contentclaudecodeutm_campaignrewrite 。技能不触发planner 一直返回respond。检查你的 system prompt 里技能描述是否清晰tool函数的 docstring 是否完整。LangChain 靠 docstring 生成工具描述描述模糊模型就不会选。状态丢失多轮对话后current_query被覆盖。检查AgentState的字段是否用了Annotated做累加messages用operator.add其他字段按需处理。6. 语义一致 CTA把技能 Agent 跑起来到这里你已经有了一个可插拔技能 Agent 的完整骨架Skill 用tool注册LLM 走 TaoToken 统一通道状态用StateGraph管理路由用条件边动态决策。下一步就是把它接到真实业务里。如果你要排障或深入接入配置先看 API Keys 和接入文档https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 和 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。验证模型通道用模型对话https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentchatutm_campaignrewrite 。长期跑编码或 Agent 任务Coding Plan 更合适https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。最后给一个实用技巧新增 Skill 时先在 planner 的 system prompt 里加一行描述再写tool函数最后跑一次验证请求。三步顺序别乱否则模型看不到技能自然也不会调用。
返回列表