
1. 四类 Agent 范式到底差在哪从一次代码评审任务说起如果你正在做 Agent 开发大概率已经被 Function-Call、Skill、MCP-Server、ReAct 这四个词绕晕过。它们经常出现在同一篇文档、同一个项目 README 里看起来像是四种可以互相替代的方案实际上它们根本不在一个层级上。我见过不少团队在选型会上争论“到底该用 MCP 还是 Skill”争了半天发现两边说的根本不是一回事。先把结论摆出来Function-Call 是模型输出工具调用的指令规范Skill 是宿主 Agent 内部的能力封装MCP-Server 是独立进程对外暴露的工具服务ReAct 是 Agent 整体的推理-行动循环范式。它们不是四选一而是一套完整 Agent 里经常同时存在的四个层次。用一个具体业务任务来感受差异。假设你要做一个“代码评审助手”用户丢过来一个项目路径Agent 需要读取本地源码文件同时查询数据库里的业务配置最后比对生成评审报告。这个任务里读取文件是宿主内部就能干的事查数据库可能需要一个独立部署的服务而整个“先读文件、再查库、再比对”的流程需要一个循环调度机制。Function-Call 负责的是模型怎么把“我要调用 read_file参数是 path/xxx”这件事结构化地表达出来。它不执行任何 IO只是输出一段 JSON。Skill 负责的是宿主收到这个调用请求后真正去读文件、返回内容。MCP-Server 负责的是把数据库查询能力封装成一个独立进程通过标准协议暴露给宿主。ReAct 负责的是决定先读文件还是先查库、拿到结果后下一步干什么、什么时候输出最终答案。这四者组合起来才是一条完整的调用链。本文会以 TaoToken 统一 Key/API 通道为底座交付四类范式的最小可复制配置和逐项验证动作帮你按场景选型并跑通端到端链路。TaoToken 在这里的角色是统一模型接入层你不需要为每个范式单独申请不同的 Key一套 API 通道就能覆盖 Function-Call、ReAct 等需要模型输出的环节。适合谁看正在做 Agent 开发、被这四个概念搞混、需要一套能直接跑起来的最小配置的工程师。读完你应该能判断自己的业务该用哪一层、怎么组合、怎么验证。2. TaoToken 前置准备统一 Key 与 API 通道配置在跑通四类范式之前先把模型接入层统一掉。TaoToken 的定位是模型 API 聚合通道你拿一个 Key 就能调用多种模型省去为每个范式单独配置不同厂商 SDK 的麻烦。官网地址是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 入口是 https://taotoken.net/api 。第一步拿到 API Key。进入控制台创建密钥路径是 https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 。创建后复制保存后面所有配置都用这一个 Key。第二步确认 Base URL。TaoToken 的 API 基地址是 https://taotoken.net/api 兼容 OpenAI 风格的接口路径。也就是说你原来用 openai 库的地方把 base_url 换成这个地址、api_key 换成 TaoToken 的 Key就能直接跑。第三步选模型。不同范式对模型能力要求不同。Function-Call 需要模型原生支持工具调用ReAct 需要模型有较强的推理和指令遵循能力。你可以在模型对话页面先试一下目标模型是否支持 tools 参数 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 。第四步环境变量配置。建议把 Key 和 Base URL 写进环境变量避免硬编码export TAOTOKEN_API_KEYsk-你的Key export TAOTOKEN_BASE_URLhttps://taotoken.net/api如果你用 Python安装 openai 库即可pip install openai然后初始化客户端import os from openai import OpenAI client OpenAI( api_keyos.environ[TAOTOKEN_API_KEY], base_urlos.environ[TAOTOKEN_BASE_URL], )到这里前置就完成了。注意一点TaoToken 是模型接入通道不是 Agent 框架也不是工具执行器。它只负责把模型输出接回来工具执行、循环调度这些逻辑仍然在你的宿主程序里。这个边界要清楚否则后面配置容易搞混。如果你需要长期跑编码类 Agent可以了解 Coding Plan https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。3. 四范式最小可复制配置JSON/TOML/settings 片段这一节给出四类范式各自的最小配置。每个配置都基于 TaoToken 的 Base URL 和 Key你可以直接复制到对应文件里改。3.1 Function-Call 最小配置Function-Call 的核心是 tools 参数。你需要在请求里传入工具 Schema模型会返回结构化的 tool_calls。下面是一个最小 Python 配置tools [ { type: function, function: { name: read_file, description: 读取本地文件内容, parameters: { type: object, properties: { path: {type: string, description: 文件路径} }, required: [path], }, }, } ] resp client.chat.completions.create( modelgpt-4o-mini, messages[{role: user, content: 读取 /tmp/demo.py 的内容}], toolstools, tool_choiceauto, ) print(resp.choices[0].message.tool_calls)这段配置里Base URL 和 Key 来自上一节的环境变量。模型只输出 tool_calls不执行读取。执行逻辑在你自己写的函数里。3.2 Skill 最小配置Skill 是宿主内部的能力封装。以 Claude Code Skill 为例它是一个 markdown SOP 文件放在.claude/skills/目录下。最小配置是一个SKILL.md--- name: code-review description: 评审代码文件并输出问题列表 --- 读取用户指定的文件逐行检查以下问题 1. 未处理的异常 2. 硬编码的密钥 3. 缺少输入校验 输出格式文件路径 行号 问题描述。这个 Skill 本身不做 IO它编排底层工具完成流程。如果你用的是代码型 Skill比如 Dify 自定义工具配置是一个 Python 函数加 Schema和 Function-Call 的 tools 定义类似但执行体在宿主内。3.3 MCP-Server 最小配置MCP-Server 是独立进程。以 stdio 方式为例你需要在宿主配置里声明 server 启动命令。Claude Code 的 settings 配置片段{ mcpServers: { db-query: { command: python, args: [/path/to/db_mcp_server.py], env: { TAOTOKEN_API_KEY: sk-你的Key, TAOTOKEN_BASE_URL: https://taotoken.net/api } } } }对应的db_mcp_server.py用 MCP SDK 暴露 tools/list 和 tools/call。宿主 MCP-Client 拿到 schema 后转成 Function-Call 工具定义传给模型。注意这里三件套要写全Base URL、Key、Model ID。Model ID 在 server 内部调用模型时使用比如gpt-4o-mini。3.4 ReAct 最小配置ReAct 是一套循环逻辑不是单个配置文件。最小实现是一个 while 循环加提示词。下面是一个可复制的 Python 骨架messages [{role: user, content: task}] for step in range(10): resp client.chat.completions.create( modelgpt-4o-mini, messagesmessages, toolstools, tool_choiceauto, ) msg resp.choices[0].message messages.append(msg) if not msg.tool_calls: break for call in msg.tool_calls: result execute_tool(call.function.name, call.function.arguments) messages.append({ role: tool, tool_call_id: call.id, content: result, }) print(messages[-1].content)这个骨架里ReAct 的 Thought 由模型内部完成Action 是 tool_callsObservation 是 tool 消息回填。循环直到模型不再发起工具调用。四类配置的共同点是都依赖 TaoToken 的 Base URL 和 Key。区别在于执行位置和生命周期Function-Call 无状态单次Skill 跟随宿主MCP-Server 独立常驻ReAct 多轮循环。4. 逐项验证请求与成功结果配置写完逐项验证。不要一次全跑容易混淆错误来源。先验证 Function-Call。运行 3.1 的代码预期输出是一个 tool_calls 列表里面包含 read_file 和 path 参数。如果输出是普通文本而不是 tool_calls说明模型不支持工具调用换一个支持 tools 的模型。成功结果长这样[ChatCompletionMessageToolCall(idcall_abc, functionFunction(nameread_file, arguments{path:/tmp/demo.py}), typefunction)]再验证 Skill。如果你用 Claude Code Skill在对话里输入触发词观察它是否按 SKILL.md 的流程编排工具。成功标志是它先调用读取工具再按格式输出问题列表。如果它直接回答而没有调用工具检查 SKILL.md 的 description 是否足够明确。验证 MCP-Server。启动宿主后查看 MCP 连接日志。成功标志是 tools/list 返回了你定义的 db_query 工具。然后发一条需要查库的请求观察宿主是否把 Function-Call 翻译成 MCP JSON-RPC 发给 server。你可以在 server 里加一行日志打印收到的请求。验证 ReAct。跑 3.4 的骨架任务设为“读取 /tmp/demo.py 并统计行数”。预期看到多轮循环第一轮模型发起 read_file 调用第二轮拿到内容后输出行数。如果循环超过 10 次还没结束检查工具返回内容是否为空导致模型反复重试。四项都通过后跑端到端组合任务读取文件 查数据库 生成评审报告。这条链路里ReAct 负责循环Function-Call 负责工单格式read_file 由 Skill 执行db_query 由 MCP-Server 执行。成功结果是模型输出一份包含文件问题和配置比对的报告。验证时建议打开 TaoToken 的请求日志确认每次模型调用都走了统一通道。如果某一步没有日志说明那一步没经过模型可能是纯本地执行。5. 本篇常见错排查401、local proxy failed、reading choices、OAuth这一节对照真实报错给出排查路径。这些错误我在配置四范式时基本都踩过。401 Unauthorized。最常见原因是 Key 没传对。检查环境变量TAOTOKEN_API_KEY是否为空或者代码里是否硬编码了旧 Key。如果你用 MCP-Server检查 settings.json 的 env 字段是否把 Key 传进了子进程。子进程不会自动继承宿主环境变量必须显式声明。修复方式是在 env 里补上TAOTOKEN_API_KEY和TAOTOKEN_BASE_URL。local proxy failed。这个报错通常出现在宿主尝试连接 MCP-Server 时。原因是 server 启动命令路径不对或者 Python 环境缺少依赖。检查 args 里的脚本路径是否是绝对路径检查 server 脚本能否单独运行。如果是 stdio 方式server 不能往 stdout 打印非协议内容否则会干扰 JSON-RPC 解析。把调试日志写到 stderr。reading choices 相关报错。典型信息是NoneType object has no attribute choices或reading choices。这通常发生在 ReAct 循环里resp 为 None 时直接访问 resp.choices。原因是请求失败但没抛异常或者模型返回了空响应。修复方式是在访问 choices 前加判空并打印原始响应。另一个原因是 tools 参数格式不对导致 API 返回错误结构。OAuth 相关报错。如果你用 Claude Code 接入可能遇到 OAuth 认证失败。检查是否配置了正确的 Base URL 和 Key。Claude Code 的接入配置在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 有说明。如果是 Codex 的 auth.json确认字段名和层级正确。三件套 Base URL、Key、Model ID 缺一不可。还有一个隐蔽错误MCP-Server 返回的工具 Schema 里 parameters 不是合法 JSON Schema导致模型无法生成正确 tool_calls。检查 required 字段是否是数组properties 是否每个都有 type。修复后重启 server 和宿主。排查顺序建议先确认 Key 和 Base URL再确认模型支持 tools再确认工具 Schema 合法最后确认循环退出条件。大部分问题在前两步就能定位。6. 按场景选型与统一通道接入回到选型问题。简单内部业务工具优先 Skill直接写代码或 SOP轻量快速不需要独立进程。需要跨 Agent 复用、独立部署、独立重启的工具用 MCP-Server。工具调用的下达方式优先 Function-Call弱模型才用纯提示词模拟。复杂多步骤任务用 ReAct 循环简单单步任务可以不用完整循环。典型组合参考Claude Code 是 ReAct 循环 Function-Call 内置 Skill MCP-Server。Dify 是 ReAct 循环 Function-Call Skill MCP SSE 接入。两者都把四层用上了只是实现细节不同。统一通道的价值在于不管你用哪层范式模型调用都走同一个 Base URL 和 Key。这样切换模型、排查问题、统计用量都集中在一个地方。TaoToken 的 API 入口是 https://taotoken.net/api 接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。如果你要长期跑编码类 AgentCoding Plan 在 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。需要先试模型是否支持工具调用去模型对话页面 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 。Key 管理在 https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 。最后给一个实用技巧在 ReAct 循环里加一个最大步数限制同时在每轮打印 tool_calls 的名称和参数。这样出问题时你能一眼看出是模型没发起调用、还是工具执行失败、还是循环没退出。这个习惯比任何调试工具都管用。