资讯动态

OpenClaw Nanobot 架构拆解:从源码学会 AI Agent 的骨架设计(2026)

发布时间:2026/9/1 23:51:24 来源:尧图企业网站定制
上周五在折腾一个自动化代码审查的 Agent写到一半发现自己在重复造轮子——任务调度、工具注册、上下文管理每个都自己糊一遍代码丑得我自己都不想看。正好那几天 OpenClaw 冲到 GitHub 20 万 Star热榜上全是它的入门教程就想着与其瞎搞不如把 OpenClaw 的 Nanobot 架构拆一遍看看人家怎么设计的。花了两天啃源码。说实话OpenClaw 的 Nanobot 架构是我 2026 年见过的最干净的 Agent 设计模式——轻量、可组合、Skills 热插拔。这篇是我的学习笔记把核心架构、关键代码、踩的坑全记下来顺便用 Claude 4.6 跑一个完整的 Nanobot 示例。先说结论维度说明Nanobot 是什么OpenClaw 的最小 Agent 执行单元一个 Nanobot 一个 System Prompt 一组 Skills 一个模型绑定核心设计思想单一职责 组合模式多个 Nanobot 可以编排成复杂 AgentSkills 是什么类似 Function Calling 的工具注册机制支持热插拔和版本管理适合谁学想自己搭 Agent 框架的开发者或者想深入理解 OpenClaw 而不只是当用户的人学习成本有 Python 基础 了解 Function Calling 概念2-3 小时能跑通Nanobot 架构全景图先上一张我梳理的架构图后面所有内容围绕这张图展开用户输入编排器 OrchestratorNanobot: 代码分析Nanobot: 文档生成Nanobot: 测试编写Skill: read_fileSkill: ast_parseLLM APISkill: markdown_renderSkill: run_pytestAPI ProviderGPT-5Claude 4.6GLM-5三层结构编排器负责调度Nanobot 负责执行Skills 负责干活。模型调用是 Nanobot 的内部行为外部只关心输入输出。环境准备# Python 3.11pipinstallopenclaw0.9.0 pipinstallopenai# OpenClaw 底层用 OpenAI 兼容协议调模型OpenClaw 的模型调用层走 OpenAI 兼容协议任何兼容 OpenAI API 格式的服务都能接。这一点后面会用到。第一步理解 Nanobot 的最小结构一个 Nanobot 的定义文件长这样YAML 格式# nanobot.yamlname:code_reviewerversion:1.0description:审查 Python 代码质量并给出改进建议system_prompt:|你是一个资深 Python 代码审查员。 审查重点代码可读性、潜在 bug、性能问题。 输出格式按严重程度排序每条包含行号、问题描述、修复建议。model:provider:openai_compatiblemodel_name:claude-sonnet-4-20250514temperature:0.3skills:-read_file-ast_parse-search_codebase就这些。没有复杂的继承关系没有抽象工厂纯声明式配置。我第一次看到的时候想就这但仔细想想这个设计确实聪明——把 Agent 的行为完全用配置描述运行时由框架装配。换模型改一行model_name加工具在skills列表追加一个。第二步用 Python 手撸一个 Nanobot光看 YAML 没意思从 Python 代码层面理解 Nanobot 的运行机制。OpenClaw 的核心类是Nanobot我把源码里的关键逻辑简化了一版fromopenaiimportOpenAIimportjsonclassNanobot:OpenClaw Nanobot 核心逻辑简化版def__init__(self,name:str,system_prompt:str,model:str,skills:listNone):self.namename self.system_promptsystem_prompt self.modelmodel self.skillsskillsor[]self.skill_registry{}# 初始化 LLM 客户端self.clientOpenAI(api_keyyour-key,base_urlhttps://api.ofox.ai/v1# 聚合接口一个 Key 调所有模型)# 注册 skillsforskillinself.skills:self._register_skill(skill)def_register_skill(self,skill_func):把 Python 函数注册为 Skill本质是 Function Calling 的 tooltool_def{type:function,function:{name:skill_func.__name__,description:skill_func.__doc__or,parameters:getattr(skill_func,_parameters,{type:object,properties:{}})}}self.skill_registry[skill_func.__name__]{definition:tool_def,handler:skill_func}defrun(self,user_input:str,max_rounds:int5)-str:执行 Nanobot 的核心循环LLM 推理 → 调用 Skill → 再推理messages[{role:system,content:self.system_prompt},{role:user,content:user_input}]tools[s[definition]forsinself.skill_registry.values()]forround_numinrange(max_rounds):responseself.client.chat.completions.create(modelself.model,messagesmessages,toolstoolsiftoolselseNone,tool_choiceautoiftoolselseNone)msgresponse.choices[0].message messages.append(msg)# 如果模型没有调用工具说明推理结束ifnotmsg.tool_calls:returnmsg.content# 执行所有 tool callsfortool_callinmsg.tool_calls:func_nametool_call.function.name func_argsjson.loads(tool_call.function.arguments)handlerself.skill_registry[func_name][handler]resulthandler(**func_args)messages.append({role:tool,tool_call_id:tool_call.id,content:str(result)})print(f [Round{round_num1}] Skill 调用:{func_name}({func_args}) →{str(result)[:100]}...)returnmessages[-1].contentifmessageselse达到最大轮次这段代码就是 Nanobot 的核心——一个带 tool 循环的 Chat Completion 调用。看起来简单但 OpenClaw 在这个基础上加了几个关键设计Skill 版本管理同一个 Skill 可以有多个版本Nanobot 可以锁定特定版本上下文窗口管理自动 truncate 超长对话保留 system prompt 和最近 N 轮错误重试Skill 执行失败会把错误信息喂回模型让它自己修正第三步定义 Skills 并跑起来Skills 就是普通的 Python 函数加点元信息装饰就行importosimportastdefskill(parameters:dict):装饰器给函数附加 JSON Schema 参数定义defdecorator(func):func._parametersparametersreturnfuncreturndecoratorskill(parameters{type:object,properties:{file_path:{type:string,description:要读取的文件路径}},required:[file_path]})defread_file(file_path:str)-str:读取指定路径的文件内容ifnotos.path.exists(file_path):returnf错误文件{file_path}不存在withopen(file_path,r,encodingutf-8)asf:contentf.read()# 限制返回长度防止撑爆上下文iflen(content)10000:returncontent[:10000]f\n...[文件过长已截断总长度{len(content)}字符]returncontentskill(parameters{type:object,properties:{code:{type:string,description:要解析的 Python 代码}},required:[code]})defast_parse(code:str)-str:解析 Python 代码的 AST 结构返回函数和类的列表try:treeast.parse(code)result[]fornodeinast.walk(tree):ifisinstance(node,ast.FunctionDef):args[a.argforainnode.args.args]result.append(f函数:{node.name}({, .join(args)}) 行{node.lineno})elifisinstance(node,ast.ClassDef):result.append(f类:{node.name} 行{node.lineno})return\n.join(result)ifresultelse未发现函数或类定义exceptSyntaxErrorase:returnf语法错误{e}# 组装 Nanobot 并运行reviewerNanobot(namecode_reviewer,system_prompt你是一个资深 Python 代码审查员。 审查流程 1. 先用 read_file 读取目标文件 2. 用 ast_parse 分析代码结构 3. 基于分析结果给出审查意见 输出格式按严重程度排序每条包含行号、问题描述、修复建议。,modelclaude-sonnet-4-20250514,skills[read_file,ast_parse])# 跑一下resultreviewer.run(请审查 ./src/utils.py 这个文件的代码质量)print(result)跑起来的输出大概是这样[Round 1] Skill 调用: read_file({file_path: ./src/utils.py}) → import os\nimport sys\n\ndef ... [Round 1] Skill 调用: ast_parse({code: import os\nimport sys...}) → 函数: load_config(path) 行5... [Round 2] 推理完成返回审查结果模型先读文件再解析 AST最后综合两个 Skill 的结果给出审查意见。这就是 Nanobot 的 ReAct 循环——推理、行动、观察、再推理。第四步多 Nanobot 编排真正有意思的是把多个 Nanobot 组合起来。OpenClaw 的编排器Orchestrator支持串行、并行、条件分支三种模式fromdataclassesimportdataclassfromtypingimportCallablefromconcurrent.futuresimportThreadPoolExecutordataclassclassNanobotTask:nanobot:Nanobot input_transform:CallableNone# 从上一步结果提取输入classOrchestrator:简化版编排器defrun_sequential(self,tasks:list[NanobotTask],initial_input:str)-list[str]:串行执行上一个的输出是下一个的输入results[]current_inputinitial_inputfortaskintasks:iftask.input_transform:current_inputtask.input_transform(current_input,results)resulttask.nanobot.run(current_input)results.append(result)current_inputresultreturnresultsdefrun_parallel(self,tasks:list[NanobotTask],shared_input:str)-list[str]:并行执行所有 Nanobot 拿到同一个输入withThreadPoolExecutor(max_workerslen(tasks))asexecutor:futures[executor.submit(t.nanobot.run,shared_input)fortintasks]return[f.result()forfinfutures]# 实际使用代码审查 → 生成修复方案 → 编写测试orchestratorOrchestrator()review_botNanobot(namereviewer,system_prompt审查代码...,modelclaude-sonnet-4-20250514,skills[read_file,ast_parse])fix_botNanobot(namefixer,system_prompt根据审查意见生成修复代码...,modelclaude-sonnet-4-20250514,skills[read_file])test_botNanobot(nametester,system_prompt为修复后的代码编写 pytest 测试...,modelclaude-sonnet-4-20250514,skills[])resultsorchestrator.run_sequential(tasks[NanobotTask(nanobotreview_bot),NanobotTask(nanobotfix_bot),NanobotTask(nanobottest_bot),],initial_input审查并修复 ./src/utils.py)三个 Nanobot 串起来就是一个完整的代码审查 修复 测试 pipeline。每个 Nanobot 只管自己那一步职责清晰。踩坑记录两天踩了不少坑记几个印象深的。坑 1Skill 返回值太长直接撑爆上下文一开始没做read_file的截断读了一个 3 万行的文件直接超了 Claude 4.6 的上下文窗口。报错信息还挺模糊的排查了半小时才定位到。解决方案就是上面代码里的截断逻辑。另外 OpenClaw 源码里有个context_window_manager模块专门处理这个建议直接用它的。坑 2并行执行时的 Rate Limit三个 Nanobot 并行跑瞬间打了三个请求直接触发 429。这个不是 OpenClaw 的问题是 API 那边的限流。后来换了 ofox.ai 的聚合接口底层做了多供应商负载均衡并发能力好很多三个并行请求没再被限流过。ofox.ai 是一个 AI 模型聚合平台支持 GPT-5、Claude 4.6、GLM-5 等 50 模型低延迟直连改个 base_url 就能用。坑 3tool_calls 的 arguments 偶尔不是合法 JSON某些模型尤其是小模型返回的function.arguments偶尔会带多余的逗号或者缺引号。OpenClaw 源码里用了一个repair_json的工具函数做容错这个思路值得学。自己写的话可以用json-repair这个库。坑 4system_prompt 里不写清楚调用顺序模型会乱来一开始 system_prompt 只写了「你可以用 read_file 和 ast_parse」结果模型有时候不读文件就直接开始分析纯靠幻觉编。后来改成明确写「第一步先用 read_file第二步用 ast_parse第三步再给出意见」效果好了很多。Agent 的 prompt 必须写执行流程光列工具没用。小结Nanobot 架构本质不复杂核心就三个东西Nanobot System Prompt Model Skills声明式定义运行时装配Skills Function Calling 的封装加了版本管理和错误重试Orchestrator 多 Nanobot 编排支持串行/并行/条件分支看完源码之后觉得自己之前造的轮子也不是完全白费——思路是对的只是没有 OpenClaw 这么工程化。如果你也在搞 Agent 开发建议花半天读一遍 OpenClaw 的nanobot/core.py和skills/registry.py这两个文件比看十篇教程有用。下一篇打算写 OpenClaw 的 Skills 生态怎么玩怎么自己发布一个 Skill 包到社区。有兴趣的可以先 star 一下更新了不迷路。

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

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

免费获取报价