资讯动态

MetaGPT姐妹项目OpenManus的agent和tool模块理解:把settings改到TaoToken

发布时间:2026/10/14 9:08:22 来源:尧图企业网站定制
1. OpenManus 的 agent 与 tool 模块到底怎么协作OpenManus 是 MetaGPT 团队开源的一个通用智能体项目核心目标是把「大模型思考 工具执行」这条链路跑通让模型能自己决定调用浏览器、执行 Python 代码、搜索网页。它适合谁适合已经跑通过基础 LLM 调用、想进一步理解多智能体工具调用机制、并且希望把模型请求统一收敛到一个稳定通道的开发者。我自己在本地把 OpenManus 拉起来跑过几轮最直观的感受是agent 负责「想」tool 负责「做」而两者之间靠一个统一的 LLM 通道串起来这个通道一旦配置不对agent 就会卡在 think 阶段反复空转。先看 agent 模块的继承关系。项目核心代码在app目录下app.agent里有 manus、planning、react、toolcall 等模块。Manus 继承 BrowserAgentBrowserAgent、PlanningAgent、SWEAgent 都继承 ToolCallAgentToolCallAgent 继承 ReActAgentReActAgent 再继承 BaseAgent。这条链最关键的两个抽象方法是think()和act()class ReActAgent(BaseAgent, ABC): name: str description: Optional[str] None system_prompt: Optional[str] None next_step_prompt: Optional[str] None llm: Optional[LLM] Field(default_factoryLLM) memory: Memory Field(default_factoryMemory) state: AgentState AgentState.IDLE max_steps: int 10 current_step: int 0 abstractmethod async def think(self) - bool: Process current state and decide next action abstractmethod async def act(self) - str: Execute decided actions async def step(self) - str: should_act await self.think() if not should_act: return Thinking complete - no action needed return await self.act()step()就是一次完整的「思考—行动」循环。think()里会调用 LLM把当前 memory、system_prompt、可用工具列表一起发过去让模型返回一个 tool_callact()则解析这个 tool_call找到对应工具并执行把 observation 写回 memory。所以 agent 本身不干活它只是调度器。再看 tool 模块。app.tool下每个工具都继承BaseTool实现execute()。浏览器工具browser_use_tool.py和 Python 执行工具python_execute.py是最重要的两个。以 PythonExecute 为例它的parameters是一段 JSON Schema告诉模型这个工具接受什么参数class PythonExecute(BaseTool): name: str python_execute description: str Executes Python code string. Note: Only print outputs are visible... parameters: dict { type: object, properties: { code: { type: string, description: The Python code to execute., }, }, required: [code], }而 ToolCallAgent 的act()里会调用self.execute_tool(command)拿到 observation。也就是说tool 的name、description、parameters会被序列化进 LLM 的 tools 参数模型据此决定调哪个工具、传什么参数。理解这一点后你会发现agent 和 tool 的耦合点其实只有两处——工具描述注入 prompt以及 tool_call 解析后分发执行。真正容易出问题的是中间那次 LLM 请求。我实测下来OpenManus 默认走的是 OpenAI 兼容接口config/config.toml里配置base_url、api_key、model。如果你本地网络环境对某些域名不稳定agent 的think()就会超时或返回空 tool_calls表现就是「一直思考但不动手」。把 LLM 请求统一改到一个稳定的 OpenAI 兼容通道是让 OpenManus 跑顺的最短路径。下面我就按「改 settings → 验证 tool 调用」的顺序把可复制的配置和排障过程写清楚。2. 把 OpenManus 的 settings 改到 TaoToken 统一通道OpenManus 的配置入口是项目根目录下的config/config.toml它由app/config.py读取最终注入到LLM类。LLM 类在app/llm.py内部用openaiSDK 发请求所以只要base_url指向一个 OpenAI 兼容端点api_key用对应平台的 Key就能无缝切换。TaoToken 提供的就是这样一个统一通道官网在 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 端点是 https://taotoken.net/api 。先说清楚三件套这是后面所有配置的基础配置项值说明Base URLhttps://taotoken.net/apiOpenAI 兼容端点末尾不要多加/v1API Key在控制台创建形如sk-开头的一串Model ID按控制台可用列表填例如gpt-4o、claude-3-5-sonnet等Key 的获取路径是登录后进入控制台在 API Keys 页面新建一个 Key。控制台地址是 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API Keys 页面是 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。创建后立刻复制保存页面刷新后不再完整显示。接下来改config/config.toml。OpenManus 的配置结构里[llm]段是主模型[llm.vision]是视觉模型浏览器截图分析用。把两段的base_url、api_key、model都指向 TaoToken[llm] model gpt-4o base_url https://taotoken.net/api api_key sk-你的TaoTokenKey max_tokens 4096 temperature 0.0 [llm.vision] model gpt-4o base_url https://taotoken.net/api api_key sk-你的TaoTokenKey max_tokens 4096 temperature 0.0如果你更习惯用环境变量OpenManus 也支持在.env里覆盖。项目根目录复制一份.env.example为.env写入LLM_API_KEYsk-你的TaoTokenKey LLM_BASE_URLhttps://taotoken.net/api LLM_MODELgpt-4o注意config.toml和环境变量的优先级app/config.py里通常先读 toml再用环境变量覆盖所以两者都写时以环境变量为准。我建议只保留一处避免排查时自己绕晕。改完配置后先别急着跑完整 agent先用一个最小脚本验证 LLM 通道本身是通的。在项目根目录新建check_llm.pyimport asyncio from app.llm import LLM from app.schema import Message async def main(): llm LLM() resp await llm.ask([ Message.user_message(只回复两个字通了) ]) print(LLM 返回:, resp) if __name__ __main__: asyncio.run(main())运行python check_llm.py。如果打印出「通了」说明 Base URL、Key、Model 三件套都对agent 的think()就有稳定的模型来源了。这一步是整个 OpenManus 跑通的地基地基不稳后面 tool 调用全是玄学问题。3. 可复制的 settings 片段与 tool 注册到 agent 的完整配置这一节把配置和代码放在一起方便你直接抄。OpenManus 的工具注册发生在 agent 初始化时以 Manus 为例它会把 BrowserUseTool、PythonExecute、WebSearch 等工具塞进available_tools然后 ToolCallAgent 在think()时把这些工具的 schema 一起发给 LLM。先看完整的config/config.toml这是最关键的 settings 片段[llm] model gpt-4o base_url https://taotoken.net/api api_key sk-你的TaoTokenKey max_tokens 4096 temperature 0.0 [llm.vision] model gpt-4o base_url https://taotoken.net/api api_key sk-你的TaoTokenKey max_tokens 4096 temperature 0.0 [browser] headless false disable_security true [search] engine Google如果你用 Claude 系列模型做 agent 的推理Model ID 换成对应的即可Base URL 和 Key 不变。TaoToken 的模型对话入口在 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 你可以在里面先手动测一下目标模型是否可用再去改 OpenManus 配置能省不少来回。然后是 tool 注册。OpenManus 里工具通过available_tools字典注入键是工具名值是工具实例。下面这段是精简后的注册逻辑你可以对照自己的app/agent/manus.pyfrom app.tool import BrowserUseTool, PythonExecute, WebSearch, Terminate class Manus(ToolCallAgent): name: str Manus description: str A versatile agent that can solve various tasks using multiple tools available_tools: ToolCollection Field( default_factorylambda: ToolCollection( PythonExecute(), BrowserUseTool(), WebSearch(), Terminate(), ) )ToolCollection会把每个工具的name、description、parameters转成 OpenAI function calling 格式。ToolCallAgent 的think()大致逻辑是async def think(self) - bool: messages self.memory.to_messages() response await self.llm.ask_tool( messagesmessages, toolsself.available_tools.to_params(), tool_choiceauto, ) self.memory.add_message(Message.assistant_message(response.content, tool_callsresponse.tool_calls)) return bool(response.tool_calls)act()则遍历response.tool_calls按function.name找到工具json.loads(function.arguments)解析参数调用execute()async def act(self) - str: for tool_call in self.tool_calls: tool self.available_tools.get(tool_call.function.name) args json.loads(tool_call.function.arguments) result await tool.execute(**args) self.memory.add_message(Message.tool_message(result, tool_call.id)) return Tools executed看到这里agent 和 tool 的协作闭环就完整了LLM 决定调哪个 tool → agent 解析 tool_call → tool.execute 返回 observation → observation 写回 memory → 下一轮 think 带上新 observation。你要验证的就是这个闭环里每一次 LLM 请求都经 TaoToken 正常返回。4. 验证一次 tool 注册到 agent 调用的完整请求配置改好后跑一次真实调用。OpenManus 的入口是main.py启动命令python main.py启动后它会进入交互模式输入一个必须用工具才能完成的任务比如帮我用 python_execute 计算 123 * 456并打印结果预期行为是agent 的think()通过 TaoToken 请求模型模型返回一个python_execute的 tool_call参数是{code: print(123 * 456)}act()执行后 observation 是56088下一轮think()把 observation 带回模型模型判断任务完成返回终止。如果你想更直接地验证 tool 本身可以单独跑python_execute.py里注释掉的测试代码。把文件末尾的注释解开运行python app/tool/python_execute.py我实测的输出里示例 2 算术运算返回成功: True 输出: 4示例 3 语法错误返回成功: False 输出: ( was never closed示例 4 超时返回成功: False 输出: Execution timeout after 1 seconds。这些结果说明 tool 的execute()逻辑是自洽的问题只会出在 agent 到 LLM 这一段。再验证浏览器工具。browser_use_tool.py末尾也有注释掉的测试解开后访问一个页面并提取内容async def go_to_bilibili(tool): result await tool.execute( actiongo_to_url, urlhttps://www.bilibili.com ) print(result.output) result await tool.execute( actionextract_content, urlhttps://www.bilibili.com, goalget_content ) print(result.output)这里有个我踩过的坑extract_content在原始实现里必须调用 LLM 做内容抽取而且必须先go_to_url让页面加载完成否则context.get_current_page()拿不到有效页面。如果你直接调extract_content不先导航会报页面相关错误。这不是 TaoToken 的问题是工具本身的设计约束等待上游修复。验证成功的标志有三个第一check_llm.py能打印模型回复第二main.py里输入任务后 agent 能返回 tool_call 并执行第三终端日志里每次 LLM 请求都指向https://taotoken.net/api没有出现连接超时或 401。三个都满足说明 agent 与 tool 的协作链路已经跑通。5. 本篇常见报错排查401、local proxy failed、reading choices、OAuth跑 OpenManus 时最容易撞上的几类报错我按现象、原因、处理列出来方便你对照。401 Unauthorized。现象是check_llm.py直接抛openai.AuthenticationError: Error code: 401。原因通常是 Key 复制不完整、Key 前后有空格、或者config.toml和环境变量里的 Key 不一致。处理重新去 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 复制一次确认api_key sk-...引号内没有多余字符同时检查.env是否覆盖了 toml。local proxy failed / Connection error。现象是openai.APIConnectionError: Connection error或日志里出现local proxy failed。原因多半是本地环境变量里残留了HTTP_PROXY、HTTPS_PROXY指向一个已经失效的地址导致 openai SDK 走了一个不通的出口。处理检查echo $HTTP_PROXY、echo $HTTPS_PROXY如果指向本地端口且该端口没有服务清掉这两个变量再跑。注意这里说的是清理本地无效代理配置不是让你去搭什么通道。reading choices 报错。现象是KeyError: choices或TypeError: NoneType object is not subscriptable发生在解析 LLM 响应时。原因是模型返回体里没有choices字段通常是 Base URL 写错比如多写了/v1变成https://taotoken.net/api/v1/v1或者请求打到了一个不返回 OpenAI 格式的端点。处理确认base_url https://taotoken.net/api末尾不加/v1因为 SDK 会自己拼/chat/completions。OAuth / token 过期类报错。现象是invalid_api_key或token expired。如果你用的是某些需要 OAuth 刷新的客户端Key 可能有时效。处理回到控制台重新生成 Key更新到config.toml和.env。如果你在用 Claude Code 这类工具它的配置在~/.claude/settings.json或项目级 settings 里同样把 Base URL、Key、Model ID 三件套对齐即可接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。tool_call 解析失败。现象是 agent 一直 think 但 act 不执行日志里response.tool_calls为空。原因是模型没有按 function calling 格式返回可能是 Model ID 不支持 tool use或者tool_choice设置有问题。处理换一个明确支持 function calling 的模型确认tools参数正确传入。这一步排查完agent 与 tool 的闭环基本就稳了。6. 把统一通道用顺之后的下一步OpenManus 的 agent 与 tool 模块本质是一个 ReAct 循环加一层工具分发。你把config.toml里的base_url指向 https://taotoken.net/api 把 Key 和 Model ID 对齐agent 的think()就有了稳定输入tool 的execute()结果也能可靠回传。我自己的经验是先把check_llm.py跑通再跑python_execute.py的单测最后才启动main.py做端到端这样出问题时能快速定位是通道问题还是工具问题。如果你接下来要长期跑编码类或 Agent 类任务可以了解下 Coding Plan地址是 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 它更适合高频、长时间的模型调用场景。想先手动验证模型效果模型对话入口在 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。接入过程中遇到配置问题接入文档 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 里有各客户端的完整参数说明。最后留一个实用技巧改完配置后在app/llm.py的请求处加一行日志打印实际使用的base_url和model这样每次 agent 发起 think 时你都能确认请求确实走了统一通道而不是被某个残留环境变量劫持。这个习惯帮我省了很多「明明改了配置却没生效」的排查时间。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑