ARTICLE DETAIL

资讯详情

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

开源项目第188期:深入理解 AI Agent — 李博杰开源的 AI Agent 完整技术书,10章95实验,用 TaoToken 统一 Key 跑通工具调用实验

开源项目第188期:深入理解 AI Agent — 李博杰开源的 AI Agent 完整技术书,10章95实验,用 TaoToken 统一 Key 跑通工具调用实验 1. 工具调用实验为什么总卡在 Key 配置这一步《深入理解 AI Agent》这本书我关注挺久了李博杰开源的这套技术书把 Agent 拆成「LLM 上下文 工具」三要素10 章配 95 个实验第 4 章专门讲工具调用涉及 MCP 协议、感知/执行/协作三类工具、事件驱动异步 Agent。书本身质量很高但真到本地复现实验时很多人第一步就卡住了实验代码里要填 API Key而不同章节、不同实验用的模型提供商还不一样。我试过按书里.env.example的方式把 Kimi、智谱、DeepSeek、Siliconflow 的 Key 各配一份。结果就是第 2 章上下文实验用 A 家的模型第 4 章工具调用实验想换 B 家对比第 5 章 Coding Agent 又要 C 家。每换一次就要改.env、重启进程、重新确认 base_url 有没有写对。更麻烦的是有些实验脚本读的是settings.json有些读config.toml格式还不统一。这一篇就聚焦第 4 章「工具调用」的实验复现。目标很明确用 TaoToken 一个统一 Key 和统一 API 通道把多模型分散配置的问题收拢掉让你能在本地把工具调用这条链路完整跑通。适合已经会写 Python、用过 LLM API但被多 Key 配置折腾过的读者。下面给的是可直接复制的配置骨架和一次完整的工具调用验证动作。2. TaoToken 在工具调用实验里的定位先说清楚 TaoToken 在这里扮演什么角色。它是一个统一的模型 API 接入层你拿一个 Key就能通过同一个 base_url 调用不同厂商的模型。对做 Agent 实验的人来说价值不在「多一个平台」而在于把「模型切换」这件事从改代码降级成改一个字符串。书里第 4 章的工具调用实验核心是让 LLM 根据用户输入决定调用哪个工具、传什么参数然后执行工具、把结果塞回上下文。这个链路里模型只是「决策者」你完全可以用不同模型跑同一套工具代码对比它们的 function calling 表现。如果每换一个模型都要动.env和重启对比实验的成本就很高。TaoToken 的接入信息官网https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentAPI 地址https://taotoken.net/api模型对话入口https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewriteAPI 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注意TaoToken 是合规的 API 聚合接入服务本文只讨论本地实验环境的配置不涉及任何网络层操作。拿到 Key 之后你的实验环境里只需要维护一份凭证。模型名通过参数传入工具调用的代码逻辑完全不用改。这就是「统一 Key」对 Agent 实验最实际的意义。3. 可复制的配置骨架settings.json 与 config.toml书里的实验代码风格不完全统一有的脚本读 JSON有的读 TOML。我按两种格式各给一份骨架你按实验目录里的实际读取逻辑选一份用。3.1 settings.json 骨架放在实验根目录或者第 4 章实验脚本指定的配置路径下{ provider: { name: taotoken, base_url: https://taotoken.net/api, api_key: sk-你的TaoToken密钥, api_key_env: TAOTOKEN_API_KEY }, models: { default: claude-sonnet-4-20250514, tool_calling: claude-sonnet-4-20250514, fast: gpt-4o-mini }, agent: { max_tool_rounds: 5, tool_timeout_seconds: 30, verbose: true } }这里api_key建议留空改用api_key_env从环境变量读避免密钥进版本库。max_tool_rounds控制工具调用链最多循环几轮防止模型陷入反复调用的死循环第 4 章实验里这个参数很关键。3.2 config.toml 骨架如果实验脚本用的是 TOML[provider] name taotoken base_url https://taotoken.net/api api_key_env TAOTOKEN_API_KEY [models] default claude-sonnet-4-20250514 tool_calling claude-sonnet-4-20250514 [agent] max_tool_rounds 5 tool_timeout_seconds 30 verbose true3.3 环境变量与依赖安装export TAOTOKEN_API_KEYsk-你的TaoToken密钥 # 书里推荐用 uv 管理依赖以第 4 章为例 git clone https://github.com/bojieli/ai-agent-book.git cd ai-agent-book uv sync --locked --extra ch4如果你没装 uv用 pip 也行python -m pip install -e .[ch4]3.4 用 CC Switch 管理多套配置做对比实验时你可能需要在「TaoToken 统一通道」和「某个直连配置」之间切换。CC Switch 这类配置切换工具的价值就是让你不用手动改文件。核心思路是把上面两份骨架各存成一个 profile切换时只替换base_url和api_key_env两个字段。{ profiles: { taotoken: { base_url: https://taotoken.net/api, api_key_env: TAOTOKEN_API_KEY }, local_test: { base_url: http://127.0.0.1:8000/v1, api_key_env: LOCAL_API_KEY } }, active: taotoken }切换动作就是改active字段实验脚本读配置时自动生效。这样你跑同一套工具调用代码可以快速对比不同通道下的行为差异。4. 一次工具调用链路的验证动作与预期输出配置好了得验证链路真的通。下面这段代码模拟第 4 章的核心场景给模型一个「查天气」工具看它能不能正确决定调用、传参、并把结果整合成回答。import os import json from openai import OpenAI client OpenAI( base_urlhttps://taotoken.net/api, api_keyos.environ[TAOTOKEN_API_KEY], ) tools [ { type: function, function: { name: get_weather, description: 查询指定城市的当前天气, parameters: { type: object, properties: { city: {type: string, description: 城市名称} }, required: [city], }, }, } ] def get_weather(city: str) - str: fake_db {北京: 晴12°C, 上海: 多云18°C} return fake_db.get(city, 暂无数据) messages [{role: user, content: 帮我查一下北京现在的天气}] resp client.chat.completions.create( modelclaude-sonnet-4-20250514, messagesmessages, toolstools, tool_choiceauto, ) msg resp.choices[0].message print(第一轮 finish_reason:, resp.choices[0].finish_reason) print(工具调用请求:, msg.tool_calls) if msg.tool_calls: messages.append(msg) for call in msg.tool_calls: args json.loads(call.function.arguments) result get_weather(args[city]) messages.append({ role: tool, tool_call_id: call.id, content: result, }) final client.chat.completions.create( modelclaude-sonnet-4-20250514, messagesmessages, toolstools, ) print(最终回答:, final.choices[0].message.content)预期输出大致是这样第一轮 finish_reason: tool_calls 工具调用请求: [ChatCompletionMessageToolCall(idcall_xxx, functionFunction(nameget_weather, arguments{city: 北京}), typefunction)] 最终回答: 北京现在是晴天气温 12°C。看到finish_reason是tool_calls说明模型正确识别了需要调用工具看到arguments里city是「北京」说明参数抽取正确最终回答里带上了工具返回的天气数据说明结果回填链路通了。这三步都过第 4 章工具调用的基础链路就算跑通了。5. 本篇常见错排查5.1 报错 401 Unauthorized最常见的原因是环境变量没生效。先确认echo $TAOTOKEN_API_KEY如果输出为空说明export只在当前终端有效换个终端就没了。建议写进~/.bashrc或~/.zshrc。另外检查 Key 有没有多余空格复制时很容易带上。5.2 模型返回纯文本而不是 tool_calls如果finish_reason是stop而不是tool_calls通常是模型不支持 function calling或者tools参数没传对。换一个明确支持工具调用的模型再试。另外tool_choiceauto是让模型自己决定如果它觉得不需要工具就会直接回答这不算报错。5.3 工具调用死循环模型反复调用同一个工具、max_tool_rounds一直跑满一般是工具返回的内容让模型误以为任务没完成。检查你的工具返回值是不是空字符串或者格式混乱。在配置里把max_tool_rounds设成 3 到 5跑满就强制结束避免烧 token。5.4 base_url 写错导致 404TaoToken 的 API 地址是https://taotoken.net/api注意有些 SDK 会自动在末尾拼/v1有些不会。如果报 404先确认你用的 SDK 版本拼接规则必要时在代码里打印实际请求的 URL。接入文档里有各语言 SDK 的完整示例遇到路径问题直接对照。5.5 配置读取优先级混乱实验脚本可能同时存在.env、settings.json、config.toml三份配置。排查时先确认脚本实际读的是哪一份在代码里加一行打印配置来源。别三份都填了不同的 Key最后自己都搞不清用的哪个。6. 把统一 Key 用在长期编码与 Agent 实验上工具调用只是第 4 章的一部分后面第 5 章 Coding Agent、第 10 章多 Agent 协作实验复杂度会更高模型调用次数也更多。这时候统一 Key 的价值会更明显你不用在多个平台之间来回切换额度、管理多份凭证一套配置贯穿整个学习路径。如果你打算长期跑这些实验尤其是涉及 Coding Agent 和 Agent 协作的章节可以了解一下 Coding Plan它更适合高频、长时间的模型调用场景https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite配置和 Key 相关的操作都在 API Keys 页面完成https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite各语言 SDK 的接入细节、参数说明、错误码对照接入文档里写得比较全遇到本文没覆盖的报错可以直接查https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite想先不写代码、直接在网页上验证某个模型的工具调用行为可以用模型对话入口快速试https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite最后给一个我踩过的坑跑第 4 章实验时别一上来就跑完整的异步 Agent 示例先用本文这段最小工具调用代码确认链路通再逐步加工具、加轮次。链路不通的时候工具越多越难定位问题。
返回列表