
1. 从零跑通一个 Agent Demo为什么总卡在“Key 和工具”这两步大模型 Agent 入门最劝退的地方往往不是 ReAct 循环本身而是你还没开始写推理逻辑就先被三件事绊住LLM 选型要开好几个平台的账号、每个平台一套 Key、MCP 工具服务注册又要单独配一遍鉴权。等你把环境凑齐写代码的热情已经消耗掉一半。这篇面向的是刚接触 Agent 的开发者你可能已经看过 ReAct 的论文图解也知道 MCP 是“模型上下文协议”但还没真正让一个 Agent 自己决定调用工具、拿到结果、再继续推理。我们要做的就是用 TaoToken 的统一 Key 把 LLM 调用和 MCP 工具调用收敛到一套凭证上然后本地跑通一次完整的 ReAct 工具调用。四个核心考点会贯穿全文LLM 选型怎么定、ReAct 循环怎么写、MCP 协议怎么接、统一 Key 怎么管。每个考点都落到可复制的配置和可验证的请求上不是概念罗列。你跟着做完手里会有一个能跑、能改、能扩展的最小 Agent Demo。先说清楚 TaoToken 在这里扮演的角色它是一个兼容 OpenAI 接口规范的模型调用入口你拿到一个 Key 之后可以用同一套 Base URL 和 Key 去请求不同模型省掉在多个平台之间来回切换凭证的麻烦。对 Agent 入门来说这一点很关键——ReAct 循环里模型会被调用很多次如果每次换模型都要改鉴权代码调试成本会成倍上升。下面从环境准备开始一步步把配置、代码、验证和排障串起来。全程只需要一个终端、一个 Python 环境以及一个可用的 TaoToken Key。2. TaoToken 统一 Key 前置准备LLM 选型与凭证管理2.1 为什么 Agent 场景更需要统一 Key普通聊天应用一次请求就结束Key 管理粗放一点问题不大。但 Agent 不一样一个 ReAct 任务可能触发 5 到 15 轮模型调用中间还夹杂工具调用。如果你在推理用 A 平台、工具决策用 B 平台代码里就会散落多套鉴权逻辑出问题时你甚至不确定是哪套 Key 失效了。统一 Key 的价值在于Base URL 和 Key 只配一次模型通过参数切换。这样 ReAct 循环里的模型调用代码可以保持单一入口排障时也只需要检查一处凭证。2.2 获取 Key 与确认接入信息登录 TaoToken 控制台后在 API Keys 页面创建一个新 Key。建议给 Agent Demo 单独建一个 Key方便后续按项目排查用量。创建后你会得到类似sk-xxxxxxxx的字符串复制保存好它只完整显示一次。接入信息固定为两项配置项值Base URLhttps://taotoken.net/apiAPI Key你创建时保存的sk-...Model ID按需选择如gpt-4o-mini、claude-3-5-sonnet等注意 Base URL 结尾不要多加/v1具体路径由 SDK 拼接。如果你用的是 OpenAI 官方 SDK把base_url指向上面这个地址即可。2.3 LLM 选型Agent 场景怎么挑模型Agent 入门阶段选型原则是“先跑通再优化”。ReAct 循环对模型的指令遵循能力要求较高因为它需要模型稳定输出Thought / Action / Action Input这样的结构化文本。太小的模型容易格式跑偏导致解析失败。我的建议是调试阶段用一个中等能力、响应快的模型把循环逻辑跑顺等流程稳定后再把复杂推理步骤路由到更强的模型。TaoToken 的好处是切换模型只改一个字符串不用动鉴权代码。选型时关注三个维度指令遵循能不能稳定按格式输出、上下文长度ReAct 历史会累积、成本循环调用次数多。入门 Demo 用gpt-4o-mini这类模型就够等你要处理复杂任务再换。2.4 环境变量配置不要把 Key 硬编码进代码。用环境变量管理既安全又方便切换export TAOTOKEN_API_KEYsk-你的Key export TAOTOKEN_BASE_URLhttps://taotoken.net/apiWindows PowerShell 用$env:TAOTOKEN_API_KEYsk-...。配好后可以用echo $TAOTOKEN_API_KEY确认是否生效。这一步看起来简单但后面所有请求都依赖它先确认再往下走。3. 可复制配置ReAct 循环与 MCP 服务注册3.1 安装依赖pip install openai mcpopenai用来发模型请求mcp是 MCP 协议的 Python SDK。如果你打算用现成的 MCP Server还需要按对应 Server 的说明装它的依赖。3.2 统一 Key 的客户端配置片段先写一个模型客户端封装把 Base URL 和 Key 收敛到一处import os from openai import OpenAI client OpenAI( api_keyos.environ[TAOTOKEN_API_KEY], base_urlos.environ[TAOTOKEN_BASE_URL], ) MODEL_ID gpt-4o-mini def chat(messages, toolsNone): resp client.chat.completions.create( modelMODEL_ID, messagesmessages, toolstools, temperature0, ) return resp.choices[0].message这段代码就是整个 Agent 的模型入口。后面无论 ReAct 循环调用多少次都走这一个函数Key 只在这里读取一次。3.3 ReAct 循环的可复制实现ReAct 的核心是Thought → Action → Observation三步循环。下面是一个最小实现工具先用一个本地函数模拟import json def get_weather(city: str) - str: return f{city} 今天晴气温 22 度 TOOLS [ { type: function, function: { name: get_weather, description: 查询指定城市的天气, parameters: { type: object, properties: { city: {type: string, description: 城市名} }, required: [city], }, }, } ] TOOL_MAP {get_weather: get_weather} def run_react(user_query, max_steps10): messages [ {role: system, content: 你是一个会使用工具的助手请先推理再行动。}, {role: user, content: user_query}, ] for step in range(max_steps): msg chat(messages, toolsTOOLS) messages.append(msg) if not msg.tool_calls: return msg.content for call in msg.tool_calls: fn TOOL_MAP.get(call.function.name) args json.loads(call.function.arguments) result fn(**args) if fn else 工具不存在 messages.append({ role: tool, tool_call_id: call.id, content: result, }) return 达到最大步数任务未完成max_steps就是防死循环的第一道闸。入门阶段先设 10观察实际用了多少步再调整。3.4 MCP 服务注册示例MCP 的作用是把工具能力标准化暴露出来。下面是一个 MCP Server 的注册配置示例用 JSON 描述{ mcpServers: { weather-server: { command: python, args: [weather_server.py], env: { TAOTOKEN_API_KEY: sk-你的Key, TAOTOKEN_BASE_URL: https://taotoken.net/api } } } }这个配置告诉 MCP Host有一个叫weather-server的服务通过运行weather_server.py启动并把统一 Key 通过环境变量传进去。这样 MCP Server 内部如果需要调用模型也能复用同一套凭证。对应的weather_server.py骨架from mcp.server import Server from mcp.server.stdio import stdio_server server Server(weather-server) server.tool() def get_weather(city: str) - str: 查询指定城市的天气 return f{city} 今天晴气温 22 度 async def main(): async with stdio_server() as (read, write): await server.run(read, write, server.create_initialization_options()) if __name__ __main__: import asyncio asyncio.run(main())这里server.tool()装饰器把函数注册成 MCP 工具Host 端就能发现并调用它。注意 MCP Server 和 ReAct 循环里的本地工具是两种接入方式入门阶段可以先跑通本地工具再换成 MCP。3.5 三件套对照表无论你用哪种接入方式模型调用都需要三件套齐全组件值作用Base URLhttps://taotoken.net/api请求入口API Keysk-...身份凭证Model IDgpt-4o-mini等指定模型缺任何一个都会报错排障时先核对这三项。4. 验证请求本地跑通一次 ReAct 工具调用4.1 发起一次完整调用把前面的代码存成react_demo.py然后运行python react_demo.py在脚本末尾加上if __name__ __main__: print(run_react(北京今天天气怎么样))4.2 预期输出与过程解读正常运行时你会看到类似这样的流程模型先输出一段推理决定调用get_weather代码执行工具拿到北京 今天晴气温 22 度把结果回传给模型模型再生成最终回答。最终打印结果应该是类似“北京今天晴气温 22 度”的自然语言回复。如果你在run_react里加了日志能看到tool_calls被触发了一次说明 ReAct 循环完整走通了。4.3 验证 MCP 服务是否注册成功如果你用的是 MCP 方式可以用 MCP 客户端连接测试from mcp import ClientSession, StdioServerParameters from mcp.client.stdio import stdio_client params StdioServerParameters(commandpython, args[weather_server.py]) async def test(): async with stdio_client(params) as (read, write): async with ClientSession(read, write) as session: await session.initialize() tools await session.list_tools() print([t.name for t in tools]) import asyncio asyncio.run(test())输出里出现get_weather就说明 MCP Server 注册成功、工具可被发现。4.4 用模型对话快速验证 Key如果你只想先确认 Key 能用不想跑完整 Agent可以直接发一条最小请求resp client.chat.completions.create( modelMODEL_ID, messages[{role: user, content: 你好}], ) print(resp.choices[0].message.content)能打印出回复说明 Base URL、Key、Model ID 三件套没问题。这一步是排障的基准线后面任何报错都先回到这里确认。5. 本篇常见错排查401、local proxy failed 与 choices 解析5.1 401 Unauthorized最常见的报错。原因通常是 Key 没读到、Key 失效、或者环境变量名写错。排查顺序先echo $TAOTOKEN_API_KEY确认变量存在再确认代码里读的是同一个变量名最后去控制台看 Key 是否被删除或过期。如果你把 Key 写进了配置文件注意别多复制了空格或换行。sk-开头的字符串前后有空白字符也会导致鉴权失败。5.2 local proxy failed这个报错通常出现在网络层说明请求没到达服务端。检查你的 Base URL 是否写成了https://taotoken.net/api有没有误加/v1或结尾斜杠。另外确认本机没有配置会拦截请求的环境变量比如HTTP_PROXY、HTTPS_PROXY。如果有先清掉再试unset HTTP_PROXY HTTPS_PROXY5.3 reading choices 报错类似Cannot read properties of undefined (reading choices)的报错说明响应体结构和你预期的不一样。常见原因是请求根本没成功返回的是错误对象而不是正常的 completion 结构。先打印完整响应看看resp client.chat.completions.create(...) print(resp)如果里面是错误信息按错误码排查如果是空检查 Model ID 是否拼写正确。模型名写错时有些服务端会返回非标准结构导致解析choices时崩溃。5.4 OAuth 相关报错如果你在 MCP 配置里看到 OAuth 报错通常是因为某个 MCP Server 要求 OAuth 鉴权而你只配了 API Key。入门阶段建议先用不依赖 OAuth 的本地 MCP Server把协议流程跑通再处理鉴权复杂的服务。5.5 工具调用解析失败如果模型返回的tool_calls里arguments不是合法 JSONjson.loads会抛异常。这通常是模型指令遵循能力不足导致的。解决办法换一个更强的模型或者在 system prompt 里明确要求“工具参数必须是合法 JSON”。调试时可以把原始msg打印出来看模型到底输出了什么。5.6 死循环如果 Agent 反复调用同一个工具、传同样的参数说明它没拿到有效结果。加两层防护一是max_steps限制总步数二是记录最近几次工具调用连续 3 次相同就主动退出。这两条在入门 Demo 里就该加上别等出问题再补。6. 把 Demo 变成可复用能力下一步怎么走跑通上面这个最小 Demo 之后你手里其实已经有了 Agent 的骨架统一 Key 管住了模型入口ReAct 循环管住了推理与行动MCP 管住了工具标准化。接下来可以往三个方向扩展。第一把本地工具换成真实 MCP Server。你可以找现成的文件系统、数据库类 MCP Server按第 3.4 节的 JSON 格式注册进去观察 Agent 如何发现并调用它们。这一步能让你真正理解 MCP 的“N M”价值。第二给 ReAct 循环加记忆。入门 Demo 的messages是单次任务的任务结束后就丢了。你可以把历史对话存到本地文件或 Redis下次任务时按需加载这就是短期记忆的雏形。第三做模型路由。简单任务用便宜模型复杂推理切到强模型。因为统一 Key 的关系切换只是改MODEL_ID一个变量不需要动鉴权代码。这是 TaoToken 在 Agent 场景里最实际的好处。如果你想把长期编码和 Agent 调试固定下来可以了解下 Coding Plan它更适合需要持续调用模型做开发的场景。需要看模型实际对话效果可以直接在模型对话页面试。接入细节和参数说明都在接入文档里Key 的创建和管理在 API Keys 页面。最后留一个实用建议每次改完配置先用第 4.4 节那条最小请求验证三件套再跑完整 Agent。这样出问题时你能快速定位是凭证问题还是逻辑问题省掉大量猜测时间。