Manus智能体范式拆解:手写最小AI Agent循环与工具调用
2026/9/19 13:07:33 网站建设 项目流程

简介:这是一份22页的PDF解析文档,聚焦Manus智能体,面向AI从业者、产品经理和关注智能体技术应用的读者,用于系统理解Manus的技术逻辑与商业价值。内容以多智能体架构为主线,拆解规划代理、执行代理、验证代理的分工协作,以及云端异步处理、断点续传、大模型融合等关键技术优势;结合金融投资、教育教学、旅游规划等实际案例,展示Manus如何在真实场景中完成复杂任务,并与传统AI工具对比,突出其任务执行、工具调用与自主学习能力。文档还对市场竞争格局、发展前景与潜在挑战作了梳理,帮助读者快速建立从技术到产业的整体认知。资源包共1个PDF文件,大小仅1.29MB,内容精炼、结构清晰,适合通读、引用配图,可快速完成知识扫盲。目前已有110人学习下载,对于想了解Manus智能体及AI新范式的读者,具有较好的参考价值。

1. Manus 智能体的“新范式”把 AI 竞争从生成答案拉到了交付任务

Manus 智能体在 2025 年刷屏时,大众讨论大多停在了“它居然能一口气做完这么多步操作”这个现象上。比起惊叹,更值得做的是把“任务型智能体”这套范式拆开看:一个任务进来,先拆解成子步骤,每一步调用工具,拿到结果再判断是否达到目标,没达到就继续迭代。那份题为“先锋探索”的 22 页 PDF,如果只被当作产品宣传材料读完合上,几天后什么都不会留下;把它描述的流程还原成自己也能搭建的最小结构,才是工程师面对“AI 新范式”这个词该有的动作。下面按这个思路走:先立住范式,再给代码,最后给验证手段。适合正在做智能体开发、智能体搭建,或者被业务方问过“这东西我们能搭吗”的读者。

2. Manus 智能体的范式内核:规划、执行、验证组成的目标闭环

2.1 对话式接口与任务型智能体的分界线

大语言模型本身只会输出文本,ChatGPT 类产品用得再好,能力边界也止步于“生成”。Manus 被视作新范式,核心不是模型变聪明了,而是产品层面上把“会生成”的模型包装成了“会干活”的角色。所谓干活,是让模型在给出最终答复之前,先去外部世界走一圈:查文件、跑代码、打开网页、读取结果,再基于真实返回值决定下一步动作。

这条链路的工程基础是 function calling。模型在输出文本之外多了一种能力:请求调用你预先注册好的工具。程序收到请求后负责执行工具,把返回值以 tool 消息回填给模型,模型看到新信息后再决定继续调用还是输出最终回答。判断一个模型算不算“智能体”,不看参数规模,只看它有没有接入这个循环:

# 收到模型响应后,第一件事是判断它在说话还是在请求工具 if response.tool_calls: for call in response.tool_calls: result = run_tool(call.function.name, call.function.arguments) messages.append({ "role": "tool", "tool_call_id": call.id, "content": result, }) continue # 把工具结果交回模型,进入下一轮决策 return response.content # 没有 tool_calls,说明模型认为任务已完成

逻辑说明:response.tool_calls是否存在,决定了当前这轮是“继续说”还是“去做事”。tool_call_id必须原样带回,平台靠它把工具结果和某一次调用请求对应起来;continue让循环继续,模型会看到刚拿到的工具结果。很多人初写 Agent 循环时漏掉continue,结果模型永远只拿到第一次工具结果,这是最常见的跑偏原因之一。

2.2 规划—执行—验证:AI Agent 的循环结构

Manus 式智能体和普通聊天机器人还有一个更本质的差别:多了“验证”这个动作。规划是把开放任务拆成可执行的子步骤;执行是每一步去调用工具;验证是把工具返回结果和原始目标做对比,不满足就回到规划重新调整。只有“规划+执行”没有验证,Agent 会把第一个工具结果当正确答案;只有规划没有执行,那只是一份漂亮的计划书。

维度传统 LLM 应用Manus 式智能体
输入一句问题一个开放式任务
输出一段文本交付物或动作序列
典型流程用户问 → 模型答规划 → 工具执行 → 验证 → 迭代
出错处理让用户换个问法把错误信息交给模型自行修正
评价指标回答是否流畅任务是否完成

验证这一环决定了一个 AI Agent 是“演示品”还是“可用的生产工具”。演示场景里任务路径是固定的,跑通一次就能录视频;生产环境里工具会超时、网页结构会变、参数会传错,没有验证闭环,Agent 就会把中间错误当成最终结果交付。Manus 能被广泛讨论,恰恰是因为它在产品界面上第一次让普通用户直观看到了这个闭环的完整过程,而不是只看到最后的答案。

2.3 Manus 与智能体平台、多智能体的关系

从工程师视角看,Manus 的产品形态是异步执行、过程可见、结果交付。这种能力并不是只能闭源实现,在 Dify 智能体平台、Coze(扣子)智能体这类工具里同样可以通过可视化编排复刻:一个工作流节点负责拆解任务,节点间挂上工具调用和条件判断,就能搭出类似的行为链路。区别在于平台化产品更侧重业务场景的定制封装,Manus 更像一个通用型助手。

多智能体是这个范式的自然延伸:一个主智能体做任务分解,把子任务分发给下游多个专职智能体,再汇总它们的结果。这里的“工具”从函数变成了另一个智能体,交互协议不变,变的只是工具执行体的内部复杂度。对大多数团队来说,先不要碰多智能体,把单智能体加工具集的循环调稳,再谈分工协作,否则排错成本会翻倍。

3. 复刻最小版 Manus 智能体:Python 工具注册表与执行循环

3.1 为什么先手写循环,再上智能体框架

很多人开始做智能体开发时,第一反应是选框架。社区里的选择很多:Dify 智能体平台适合快速搭建带界面的业务流,Coze 适合做端到端的 Bot,LangGraph 适合画带状态机的复杂图,AutoGPT 是通用自主 Agent 的早期代表。这些工具各有价值,但我建议先自己手写一遍最小循环。

原因很简单:框架替你封装了“模型调用、工具分发、消息回填”这套逻辑,如果一开始就没理解这个循环,出了问题只会调参数,不知道问题出在链路哪一环。手写一个 60 行的最小版,跑通后再回去看框架文档,你会立刻明白它每个配置项是在控制什么。先理解再封装,是智能体搭建性价比最高的路径。

3.2 最小执行循环:工具注册、模型决策与结果回填

下面的代码实现了一个可运行的 Manus 式最小智能体:两个工具、一个注册表、一个循环。接入任意支持 function calling 的模型接口即可运行。

""" 最小 Manus 式智能体:工具注册 + 规划执行循环 依赖:任一支持 function calling 的大模型接口 """ from typing import Callable, Dict, Any import json import datetime # 1) 工具注册表 TOOLS: Dict[str, Dict[str, Any]] = {} def register_tool(name: str, description: str, parameters: Dict[str, Any]): """把函数注册成智能体可调用的工具""" def decorator(fn: Callable): TOOLS[name] = { "fn": fn, "description": description, "parameters": parameters, } return fn return decorator @register_tool( "get_current_time", "获取当前日期和时间,无参数", {"type": "object", "properties": {}}, ) def get_current_time(): return {"result": str(datetime.datetime.now())} @register_tool( "calculate", "执行四则运算,参数 expression 是字符串算式,例如 '12*8+3'", { "type": "object", "properties": { "expression": {"type": "string", "description": "需要计算的数学表达式"} }, "required": ["expression"], }, ) def calculate(expression: str): # 仅为演示,生产环境请替换为 safe_eval 或 ast 解析 try: return {"result": eval(expression)} except Exception as exc: return {"error": str(exc)} # 2) 把注册表转成模型能识别的 tools 参数 def build_tool_schema(): return [ { "type": "function", "function": { "name": name, "description": meta["description"], "parameters": meta["parameters"], }, } for name, meta in TOOLS.items() ] # 3) Agent 主循环 def run_agent(user_task: str, max_steps: int = 6, temperature: float = 0.2): """ user_task: 用户下达的原始任务 max_steps: 最大工具调用轮数,防止死循环烧 token temperature: 规划阶段保持低温度,减少随机分叉 """ messages = [ { "role": "system", "content": "你是一个任务型智能体。先拆解任务," "再逐步调用工具,直到确认所有子目标完成," "最后用一段话汇报结果。", }, {"role": "user", "content": user_task}, ] for step in range(max_steps): # llm.respond 是模型客户端接口,需支持 function calling response = llm.respond( messages=messages, tools=build_tool_schema(), tool_choice="auto", temperature=temperature, ) if response.tool_calls: for call in response.tool_calls: meta = TOOLS[call.function.name] try: args = json.loads(call.function.arguments) output = meta["fn"](**args) except Exception as exc: output = {"error": str(exc)} messages.append({ "role": "tool", "tool_call_id": call.id, "content": json.dumps(output, ensure_ascii=False), }) continue return response.content return "已达到最大步数,任务可能未完成"

参数说明:tool_choice="auto"是默认策略,由模型自己决定本轮是否调用工具;如果希望某类任务必须使用指定工具,可把它改成{"type": "function", "function": {"name": "calculate"}}temperature在规划阶段建议压到 0.2 以下,后面会单独展开。json.loads解析参数时如果工具定义里没给全必填字段,模型生成的 arguments 可能不合法,所以参数 schema 里required列表要写完整。

运行一段对话后你会发现,模型会主动把“查询当前时间”和“计算某个表达式”拆成两次工具调用,拿到结果后才组织最终回答。这个过程就是 Manus 范式的原子版本,所有复杂的 Agent 产品都是在这个循环上叠加记忆、权限和更多工具堆出来的。

3.3 工具描述怎么写,模型才愿意调用

工具注册表里最容易被忽略的是 description 字段。模型靠它判断“这个工具是干什么的、什么时候该用”,写得太模糊,模型会跳过工具直接凭训练记忆回答;写得太长,又占用上下文窗口并干扰判断。好的描述遵循一个模式:动词开头,说明输入约束,说明输出形式。

写法模型看到后的典型反应
“查询当前时间”可能直接回答“现在是下午”,不调用工具
“返回服务器当前的本地时间,调用 get_current_time,结果以 JSON 返回”更愿意调用工具并引用真实返回值
“计算函数,参数是表达式”可能传入非法格式参数
“执行四则运算,参数 expression 是字符串算式,如 12*8+3”参数格式明确,一次调用成功率高

另一个常见坑是工具描述与系统提示词里对工具行为的描述不一致。系统提示词说“不要凭空猜测结果”,但工具描述里没写“必须调用工具获取数据”,模型就会在“调用工具”和“直接回答”之间摇摆。把工具注册表当作接口文档来写,描述里带上边界条件和典型输入样例,往往不需要额外调提示词就能把工具调用率提上去。

4. 智能体不跑偏的五个配置:步数、温度、上下文和容错参数

4.1 max_steps 设多大:按任务步数而不是拍脑袋

最大步数是最直观也最容易被拍脑袋的参数。设太小,任务还没做完就被截断;设太大,一个失败的循环能烧掉大量 token。经验值是:两到三次工具调用的简单任务设 5;需要检索、对比、汇总的多步任务设 10 到 15;超过 20 的配置要非常谨慎。每步的代价是“一次模型调用 + 若干次工具调用 + 工具结果重新进入上下文”,成本是线性增长的,但收益在 15 步之后通常不再上升。

正确的做法不是把 max_steps 调大,而是在循环里加完成判断。模型最终回答里出现明确的任务完成标志时提前跳出,而不是非得把循环走满。把 max_steps 当作预算上限而不是目标值,成本失控的概率会小很多。

4.2 temperature 分阶段设置:规划低、生成高

同一个智能体在不同阶段对随机性的要求不同。任务拆解阶段,温度太高会导致拆解方案每次都不一样,同样的任务三次运行得到三条路径,后续排错无从谈起;生成最终汇报文本时,温度稍高反而让表达更自然。常见做法是把循环里的请求默认设为 0.2,只有明确属于“写文案、总结陈述”的最后一步才把 temperature 提高到 0.5 到 0.7。

如果你用的是支持按请求传参的模型接口,直接在主循环中改成两套参数即可;如果用的平台不支持,退而求其次的做法是在系统提示词里写“严格按照工具返回数据生成汇报,不要自行发挥”。效果接近,但可控性不如参数直接调节。

4.3 上下文裁剪:把中间工具返回压缩成摘要

工具返回内容会累积。查网页任务里一次抓取可能带回几千 token,三五步之后上下文就过半了。模型窗口是有限的,等到触发超限错误再处理就晚了。常见的兜底策略是维护一个 token 计数,超过阈值就对早期消息做压缩。

def trim_messages(messages, max_context_tokens=6000): """超限时压缩中间工具结果,保留 system 和最近两轮完整消息""" if count_tokens(messages) <= max_context_tokens: return messages head = messages[:1] # 保留 system 角色定位 recent = messages[-4:] # 保留最近两轮(工具+模型交替) middle = messages[1:-4] condensed = [] for m in middle: if m.get("role") == "tool": condensed.append({ "role": "tool", "tool_call_id": m.get("tool_call_id", ""), "content": f"[已压缩] {m['content'][:120]}", }) return head + condensed + recent

参数说明:max_context_tokens一般设为模型窗口的 2/3,例如 8K 窗口设为 6000 左右,留出模型输出和后续工具返回的空间。recent保留最近四条的思路是“最近的决策依赖最新的上下文”,被压缩的一定是历史中间结果,而不是系统提示词和最近一轮。这种策略会丢失一部分早期信息,但对大多数检索类任务来说,足够的最近上下文比完整的早期记录更重要。

4.4 工具失败重试:把错误喂回模型,而不是直接中断

工具调用一定会失败,参数格式错误、目标服务超时、业务逻辑返回空值都很常见。新手常见的做法是失败就中断 Agent,把 error 抛出来,这对生产环境不可接受。可行的策略是把错误信息作为工具结果回填给模型,让模型自己决定是修正参数重试还是换一个工具,例如上面的代码中 catch 到异常后返回{"error": str(exc)},模型看到后通常会重新构造参数再试一次。

重试要有上限,一般同一工具连续失败两次就应中断或换路,否则它会用同一个错误参数反复撞墙,白白消耗步数预算。在工具层加一个简单的兜底约定:正常返回空值时统一给{"result": "not_found"},不要让模型面对 None 猜测“大概是没查到”。明确的失败信号比模糊的空值更有利于模型做下一步判断。

4.5 规划器与执行器分离的时机

单智能体加工具集适合大多数中等复杂度任务,但任务目标一旦开放,比如“做一个行业调研”,单智能体的上下文里会塞满大量中间结果,规划逻辑和工具执行混在一起互相干扰。这时可以拆成两层:规划器只负责拆解目标和维护步骤列表,执行器拿到单步任务后调用具体工具,再把结果返回给规划器。代价是模型调用次数增加,每一层还要维护各自的上下文,所以这个结构适合任务确实复杂的场景,不要为了架构好看而拆。

任务特征推荐结构典型场景
单步或两三个动作单智能体 + 几个工具查时间、算汇率、格式转换
多步骤但有固定流程单智能体 + 强提示词报表整理、定时摘要生成
目标开放、要大量检索归纳规划器 + 执行器分离行业调研、多源信息汇总
多个侧重点需并行推进多智能体协作销售智能体与文案智能体并行处理一条线索

多智能体的复杂度取决于分工是否清晰。如果一个任务拆成多个子任务后,子任务之间彼此依赖,并行就无从谈起,反而会增加消息传递延迟。拆分的唯一标准是子任务之间可独立执行、可独立验证。

5. 用 trace 日志验证 Manus 式智能体:任务完成率与工具失败率

5.1 给每次工具调用写结构化 trace 日志

智能体和普通接口最大的区别是不可复现:同样的输入,可能走不同的工具路径,得到不同的结果。调试时只靠打印语句是撑不住的,需要给每次工具调用落一份结构化日志。

import json import time def trace_step(step, tool, arguments, output, tokens, latency_ms, error=""): record = { "step": step, "tool": tool, "arguments": arguments, "output_head": str(output)[:200], "tokens": tokens, "latency_ms": latency_ms, "error": error, "ts": time.time(), } with open("agent_trace.jsonl", "a", encoding="utf-8") as f: f.write(json.dumps(record, ensure_ascii=False) + "\n")

参数说明:output_head只记录前 200 个字符,避免敏感数据和超长内容直接进日志;tokens记录这一次工具调用对应的模型输入输出量,用于成本核算;error单独留空位,成功时为空字符串,失败时填错误码。这样的日志是后续所有分析的基础。

5.2 从日志里读三个问题:失败率、打转、超预算

日志跑一段时间后,重点看三个指标。工具失败率等于失败调用数除以总调用数,持续高于 5% 说明工具 schema 或描述有问题,先检查必填参数和边界情况。原地打转的检测方式是扫描同一工具加同一参数组合的出现次数,连续出现 3 次以上基本可以判定循环未收敛,需要在循环里加临时的 escape 条件。单任务 token 消耗超预算时,优先检查是不是工具返回内容太长,而不是加窗口大小,上下文裁剪往往比换大窗口模型便宜得多。

# 统计工具失败率 jq -r 'select(.error != "")' agent_trace.jsonl | wc -l # 找出同一工具连续调用最多的记录 jq -r '.tool + " " + (.arguments|tostring)' agent_trace.jsonl | sort | uniq -c | sort -rn | head -20

5.3 建立回归任务集,把“智能”变成完成率

评估智能体和评估搜索系统或推荐系统一样,需要一个固定任务集。挑 20 到 50 个覆盖典型场景的任务,人工确认好正确输出,每次修改提示词或工具描述之后全量跑一遍,记录任务完成率和工具调用收敛情况。任务完成率上升、工具失败率下降,说明改动有效;只看一两个演示任务的效果,很容易被偶然性误导。Manus 范式真正落地到工程,不是靠模型的单次惊艳表现,而是靠这套可观测、可回归的度量循环。任务完成率和工具失败率这两组数字,比任何演示视频都更能说明你的智能体是不是真的“新范式”。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询