轻量 Agent 框架 Nanobot 教程
01为什么需要轻量级的 Agent 框架Nanobot是香港大学数据科学实验室HKUDS开源的一个项目号称是 OpenClaw 的精简版实现。整个框架核心代码只有约 4000 行比 OpenClaw 小了 99%但功能一点都不含糊工具调用、定时任务、记忆系统、多模型兼容、多平台支持该有的都有。更关键的是这 4000 行代码写得非常清爽几乎没有什么过度抽象读源码就像读业务代码一样直白。对我这种喜欢折腾底层、想真正理解 Agent 是怎么运转的人来说简直就是宝藏。今天这篇教程我就带你理解 Nanobot 的设计理念、核心架构最后手把手教你从零搭建一个 Text-to-SQL 的 Agent。读完这篇文章你不仅能跑通案例还能理解每一行代码背后的原理甚至能根据自己的需求改框架。02Nanobot 是什么Nanobot 的定位很明确超轻量级个人 AI 助手框架。它的 GitHub 地址是 https://github.com/HKUDS/nanobot目前已经在开源社区获得了不少关注。核心特点极致轻量核心代码约 4000 行没有臃肿的抽象层资源占用极低启动飞快。我自己的笔记本上从启动到能接收第一条消息只需要 2-3 秒。研究友好代码简洁易读方便修改和扩展。如果你想研究 Agent 是怎么做工具调用、怎么管理上下文的直接读源码就行不需要在层层叠叠的抽象里迷路。开箱即用支持 pip、uv 或源码安装一个config.json就能定义完整的 Agent模型、工具、提供商5 分钟就能跑起来。多平台支持内置 WhatsApp、Telegram、Discord、Matrix、Slack、飞书、QQ 等聊天渠道你想在哪个平台部署都能搞定。多模型兼容支持 OpenRouter、本地 vLLM 等任意 OpenAI 兼容接口也原生支持通义千问DashScope、DeepSeek、OpenAI、Anthropic 等 20 多个提供商。主要功能工具调用支持 MCP 工具服务器可执行代码、搜索网络、操作文件等定时任务内置 Cron 支持可设置周期性提醒和自动化工作流记忆系统支持持久化记忆长期保存重要上下文多实例运行可同时运行多个针对不同平台或不同用途的机器人实例与其他 Agent 框架的对比维度NanobotDeepAgents框架体量轻量纯 Python重型依赖 LangGraph LangChain配置方式config.json 声明式Python 代码构建Skills 机制原生渐进式加载SKILL.md 自动发现SkillsMiddleware 中间件注入工具定义继承Tool基类显式注册tool装饰器 中间件管理上下文管理ContextBuilder MemoryConsolidatorSummarizationMiddleware入口方式CLI (nanobot) / Python SDK纯 Python 脚本Nanobot 的核心理念可以用一句话概括config.json配置 AGENTS.md身份 skills/技能 Tool 类工具 组合即 Agent。03核心架构揭秘四个核心组件Nanobot 的架构设计非常清晰主要由四个核心组件构成AgentLoop、ContextBuilder、ToolRegistry 和 AgentHook。理解了这四个组件你就理解了 Nanobot 的全部工作原理。AgentLoop —— 核心运行时AgentLoop 是整个框架的心脏所有逻辑的入口。它负责接收消息、构建上下文、调用 LLM、执行工具、返回响应形成一个完整的处理闭环。它的初始化代码非常直观class AgentLoop: def __init__(self, bus, provider, workspace, model, ...): self.context ContextBuilder(workspace) # System Prompt 组装 self.tools ToolRegistry() # 工具注册表 self.runner AgentRunner(provider) # LLM工具循环 self.subagents SubagentManager(...) # 子 Agent 管理 self._register_default_tools() # 注册内置工具可以看到AgentLoop 就像一个指挥官把各个模块组装在一起然后按照固定的流程运转。ContextBuilder —— System Prompt 组装这是 Nanobot 最精妙的设计之一。ContextBuilder 负责从多个来源组装完整的 System Prompt让 Agent 知道自己是谁、能做什么、该怎么做。它的组装逻辑是这样的class ContextBuilder: def build_system_prompt(self): parts [self._get_identity()] # 1. 内置身份描述 parts.append(self._load_bootstrap_files()) # 2. AGENTS.md / SOUL.md parts.append(self.memory.get_memory_context()) # 3. memory/MEMORY.md parts.append(always_skills) # 4. alwaystrue 的技能 parts.append(self.skills.build_skills_summary()) # 5. 技能 XML 摘要 return \n\n.join(parts)这里的关键是第 5 步ContextBuilder 只将技能的名称和描述XML 摘要注入 prompt而不是把每个技能的完整内容都塞进去。当 Agent 真正需要使用某个技能时它会通过read_file工具去读取完整的 SKILL.md 内容。这种渐进式加载的设计非常聪明。想象一下如果你有 10 个技能每个技能 2000 字全部塞进 prompt 就要 20000 字约 5000 tokens成本高不说还容易让模型分心。而 XML 摘要只有几百字Agent 按需读取既省钱又高效。ToolRegistry —— 工具注册ToolRegistry 管理所有可用工具提供 JSON Schema 格式的工具定义给 LLM。Nanobot 内置了以下工具工具功能ReadFileTool读取文件WriteFileTool写入文件EditFileTool编辑文件ListDirTool列出目录ExecTool执行 Shell 命令WebSearchTool网络搜索支持 5 种搜索引擎WebFetchTool获取网页内容SpawnTool生成子 AgentMessageTool发送消息CronTool定时任务MCP ToolMCP 协议工具桥接自定义工具也很简单继承 Tool 基类即可class MyCustomTool(Tool): property defname(self) - str: returnmy_tool property defdescription(self) - str: return工具描述告诉模型这个工具能做什么 property defparameters(self) - dict: return { type: object, properties: { param: {type: string, description: 参数描述} }, required: [param] } asyncdefexecute(self, **kwargs) - Any: # 执行逻辑 passAgentHook —— 生命周期钩子AgentHook 是 Nanobot 提供的扩展机制类似 DeepAgents 的中间件但更轻量。它允许你在 Agent 运行周期的关键节点插入自定义逻辑class AgentHook: asyncdefbefore_iteration(self, ctx) # 每轮 LLM 调用前 asyncdefon_stream(self, ctx, delta) # 流式输出每个 token asyncdefbefore_execute_tools(self, ctx) # 工具执行前可拦截/修改 asyncdefafter_iteration(self, ctx) # 每轮结束后 deffinalize_content(self, ctx, content) # 最终输出后处理每个方法默认都是空的pass不挂钩就不执行任何逻辑。这种非侵入式的设计让框架保持简洁同时又提供了足够的扩展性。AgentLoop 的每一轮迭代都会按顺序调用这些钩子(1) hook.before_iteration(ctx) # LLM 调用前(2) 调用 LLM 模型 ├─ hook.on_stream(ctx, delta) # 每个 token 流出时 └─ hook.on_stream_end(ctx) # 流式结束(3) 如果有 tool_calls: ├─ hook.before_execute_tools(ctx) # 工具执行前 ├─ 执行工具 └─ hook.after_iteration(ctx) # 本轮结束(4) 如果返回最终文本: ├─ hook.finalize_content(ctx, text) # 后处理 └─ hook.after_iteration(ctx) # 本轮结束04Skills 渐进式加载机制为什么需要渐进式加载假设你搭建了一个投研 Agent有 8 个技能股票查询、财报分析、新闻监控、估值计算、风险评估、组合优化、报告生成、邮件发送。每个 SKILL.md 平均 2000 字符如果全部塞进 prompt仅技能指导就要占用 16000 字符约 4000 tokens成本爆炸不说模型还要在这些信息里找重点容易分心。Nanobot 的解决方案是三级加载系统第 1 级元数据永远在 context 中约 100 words/skillSkillsLoader.build_skills_summary()把所有技能生成 XML 摘要注入 system promptskills skill availabletrue nameweb-search/name description联网搜索实时市场信息/description location/path/to/web-search/SKILL.md/location/skillskill availablefalse namedatabase-query/name description查询本地数据库/description location/path/to/database-query/SKILL.md/location/skill/skillsAgent 看到的是一个技能清单知道自己有什么工具可以用但不需要知道具体怎么用。第 2 级always 技能全文自动注入SKILL.md 的 frontmatter 中可以标记always: true这类技能的完整内容会自动塞进 system prompt---name: memorydescription: Two-layer memory system with grep-based recall.always: true---目前内置的只有 memory 技能标记了 always: true因为记忆系统需要随时可用。第 3 级按需加载模型自主 read_fileSystem prompt 中会注入提示告诉模型需要时去 read_file# SkillsThe following skills extend your capabilities. To use a skill, read its SKILL.md file using the read_file tool.Skills with availablefalse need dependencies installed first - you can try installing them with apt/brew.当 Agent 判断需要使用某个技能时它会主动调用read_file工具读取完整的 SKILL.md然后按照里面的指导执行。SKILL.md 文件格式一个标准的 SKILL.md 长这样---name: web-searchdescription: 联网搜索实时市场信息获取最新股价、行业动态等keywords: 联网, 搜索, 最新, 实时, 行情---# web-search 技能指南## 适用场景- 查询某只股票的最新行情- 获取最新的行业政策## 工作流1. 确定搜索关键词2. 调用 web_search 工具3. 分析搜索结果4. 整理输出渐进式披露设计原则Progressive Disclosure Design Principle在这里体现得淋漓尽致只给模型当前需要的信息不多不少。05实战案例从零搭建 Text-to-SQL Agent光讲理论没意思我们来实战一个案例搭建一个 Text-to-SQL Agent让用户可以用自然语言查询数据库。项目结构nanobot-examples/text-to-sql/├── config.json # 模型配置├── AGENTS.md # Agent 身份和规则├── agent.py # 入口 QueryDBTool 自定义工具├── chinook.db # 示例数据库自动下载└── skills/ ├── schema-exploration/ # 数据库结构探索技能 └── query-writing/ # SQL 编写与错误恢复技能第一步自定义 QueryDBTool这是整个案例的核心。我们需要创建一个能执行只读 SQL 查询的工具from nanobot.agent.tools.base import ToolclassQueryDBTool(Tool): SQL 查询工具 - 在 Chinook 数据库上执行只读 SQL def__init__(self, db_path: Path): self._db_path db_path property defname(self) - str: returnquery_db property defdescription(self) - str: return ( Execute a read-only SQL query against the Chinook database. Returns query results as formatted text. Only SELECT and PRAGMA statements are allowed. ) property defparameters(self) - dict[str, Any]: return { type: object, properties: { sql: { type: string, description: The SQL query to execute (SELECT only) } }, required: [sql] } property defread_only(self) - bool: returnTrue# 标记为只读可安全并行执行 asyncdefexecute(self, **kwargs: Any) - str: sql kwargs.get(sql, ).strip() ifnot sql: returnError: empty SQL query # 安全校验只允许 SELECT 和 PRAGMA upper sql.upper().lstrip() ifnot (upper.startswith(SELECT) or upper.startswith(PRAGMA)): returnError: only SELECT and PRAGMA statements are allowed try: conn sqlite3.connect(str(self._db_path)) cursor conn.cursor() cursor.execute(sql) columns [desc[0] for desc in cursor.description] if cursor.description else [] rows cursor.fetchall() conn.close() ifnot rows: returnQuery returned 0 rows. # 格式化为文本表格 lines [ | .join(columns)] lines.append(- * len(lines[0])) for row in rows[:50]: # 最多返回 50 行 lines.append( | .join(str(v) for v in row)) iflen(rows) 50: lines.append(f... ({len(rows)} total rows, showing first 50)) return\n.join(lines) except Exception as e: returnfSQL Error: {e}这个工具的设计有四个层次工具元数据name、description、parameters会被 ToolRegistry 收集转换成 LLM function calling 的 schema 发给模型安全校验代码层面强制只允许 SELECT 和 PRAGMA防止误操作执行 SQL连接数据库、执行查询、获取结果结果限制最多返回 50 行防止大表查询撑爆上下文窗口第二步组装整个 Agentdef build_bot() - Nanobot: 创建 Nanobot 实例使用 config.json 配置 bot Nanobot.from_config( config_pathWORKSPACE / config.json, workspaceWORKSPACE, ) # 注册自定义 SQL 查询工具 bot._loop.tools.register(QueryDBTool(DB_PATH)) return bot组装完成后Agent 可用的工具集包括read_file框架内置读文件加载 SKILL.mdwrite_file框架内置写文件exec框架内置执行 shell 命令query_db自定义执行只读 SQL第三步配置 config.json{ providers:{ custom:{ apiKey:your-key-or-dummy, apiBase:https://api.your-provider.com/v1 }},agents:{ defaults:{ provider:custom, model:your-model-name }}}第四步定义 AGENTS.md# SQL Query AgentYou are a SQL database analyst. You help users query databases using natural language.## Rules- Always explore the schema before writing queries- Use query_db tool to execute SQL; NEVER use exec for SQL- Only use SELECT statements (read-only access)- Format results clearly for the user- If a query fails, analyze the error and try a different approach这里的关键是明确约束用query_db执行 SQL不要用 exec。因为 exec 是通用 shell如果模型用 exec 去跑 sqlite3就绕过了 QueryDBTool 的安全限制。第五步编写 Skillsschema-exploration SKILL.md## Workflow1. Use query_db(sqlSELECT name FROM sqlite_master WHERE typetable) to list all tables2. For each relevant table, run query_db(sqlPRAGMA table_info(TableName)) to see columns3. Identify primary keys, foreign keys, and relationships4. Summarize the schema for the userquery-writing SKILL.md## Workflow### Step 1: Understand the Question- Identify what tables and columns are needed- If unsure about schema, read the schema-exploration skill first### Step 2: Write the Query- Start simple, then add complexity- Use JOINs when data spans multiple tables- Use GROUP BY for aggregations- Use ORDER BY LIMIT for top N questions### Step 3: Execute and Verify- Run with query_db(sqlYOUR QUERY)- If error: analyze the message, fix the query, retry- If results look wrong: check JOINs and WHERE clauses## Error Recovery- no such table - re-list tables with schema-exploration- no such column - re-check table_info- ambiguous column - add table alias prefix第六步运行效果执行命令python agent.py How many customers are from Canada?输出Text-to-SQL Agent (nanobot)Question: How many customers are from Canada? 模型加载 schema-exploration SKILL.md query_db(SELECT name FROM sqlite_master WHERE typetable) query_db(PRAGMA table_info(Customer)) 模型加载 query-writing SKILL.md query_db(SELECT COUNT(*) FROM Customer WHERE Country Canada)Answer: There are 8 customers from Canada in the database.exit_code: 0 | elapsed: 35s整个过程完全自主Agent 先探索数据库结构再编写并执行查询最后给出答案。如果上一次运行已经缓存了 schema 信息下次查询会直接命中无需重新探索。如果查询出错比如表名大小写不对Agent 会根据 Error Recovery 的指导自动修正。这就是 Skills 的价值把领域知识如何探索 schema、如何写 SQL、如何纠错封装在 SKILL.md 里框架负责调度两者各司其职。06给开发者的建议总结Nanobot 的核心价值在于 “轻量但不简陋” 。4000 行代码的背后是对 Agent 开发本质的深刻理解配置优先一个 config.json 就能定义完整 Agent不需要写大量胶水代码Skills 渐进式加载用三级加载系统高效管理上下文避免 token 浪费显式工具注册继承 Tool 基类的方式虽然比装饰器多写几行代码但参数验证、只读标记等元数据一目了然非侵入式扩展AgentHook 提供生命周期钩子不改框架源码就能插入自定义逻辑适用场景Nanobot 特别适合以下场景个人项目想快速搭一个能用的 Agent不想引入重型框架学习研究想深入理解 Agent 的工作原理读源码不迷路定制化需求框架的某个行为不符合预期直接改源码资源受限环境边缘设备、低配置服务器需要轻量级方案不适用场景如果你需要复杂的 多 Agent 协作流程虽然 nanobot 支持 spawn 子 Agent但不如 LangGraph 的图编排强大企业级的监控、日志、权限管理可视化的 Workflow 编排界面那可能还是 LangChain/LangGraph 更适合你。最后的话我一直觉得好的工具应该像一把顺手的瑞士军刀——功能齐全、体积小巧、开箱即用。Nanobot 就是这样一把刀。它不是万能的但在它擅长的领域它做得足够好。更重要的是当你需要调整它时你能看懂它在做什么而不是对着一堆抽象层发懵。如果你也对轻量级 Agent 开发感兴趣不妨试试 Nanobot。4000 行代码也许就是你理解 AI Agent 的最佳入口。学AI大模型的正确顺序千万不要搞错了2026年AI风口已来各行各业的AI渗透肉眼可见超多公司要么转型做AI相关产品要么高薪挖AI技术人才机遇直接摆在眼前有往AI方向发展或者本身有后端编程基础的朋友直接冲AI大模型应用开发转岗超合适就算暂时不打算转岗了解大模型、RAG、Prompt、Agent这些热门概念能上手做简单项目也绝对是求职加分王给大家整理了超全最新的AI大模型应用开发学习清单和资料手把手帮你快速入门学习路线:✅大模型基础认知—大模型核心原理、发展历程、主流模型GPT、文心一言等特点解析✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑✅开发基础能力—Python进阶、API接口调用、大模型开发框架LangChain等实操✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经以上6大模块看似清晰好上手实则每个部分都有扎实的核心内容需要吃透我把大模型的学习全流程已经整理好了抓住AI时代风口轻松解锁职业新可能希望大家都能把握机遇实现薪资/职业跃迁这份完整版的大模型 AI 学习资料已经上传CSDN朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】