news 2026/5/27 6:41:57

轻量 Agent 框架 Nanobot 教程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
轻量 Agent 框架 Nanobot 教程

01|为什么需要轻量级的 Agent 框架?

Nanobot是香港大学数据科学实验室(HKUDS)开源的一个项目,号称是 OpenClaw 的精简版实现。整个框架核心代码只有约 4000 行,比 OpenClaw 小了 99%,但功能一点都不含糊:工具调用、定时任务、记忆系统、多模型兼容、多平台支持,该有的都有。

更关键的是,这 4000 行代码写得非常清爽,几乎没有什么过度抽象,读源码就像读业务代码一样直白。对我这种喜欢折腾底层、想真正理解 Agent 是怎么运转的人来说,简直就是宝藏。

今天这篇教程,我就带你理解 Nanobot 的设计理念、核心架构,最后手把手教你从零搭建一个 Text-to-SQL 的 Agent。读完这篇文章,你不仅能跑通案例,还能理解每一行代码背后的原理,甚至能根据自己的需求改框架。


02|Nanobot 是什么?

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. always=true 的技能 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生成子 Agent
MessageTool发送消息
CronTool定时任务
MCP ToolMCP 协议工具桥接

自定义工具也很简单,继承 Tool 基类即可:

class MyCustomTool(Tool): @property defname(self) -> str: return"my_tool" @property defdescription(self) -> str: return"工具描述,告诉模型这个工具能做什么" @property defparameters(self) -> dict: return { "type": "object", "properties": { "param": {"type": "string", "description": "参数描述"} }, "required": ["param"] } asyncdefexecute(self, **kwargs) -> Any: # 执行逻辑 pass

AgentHook —— 生命周期钩子

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) # 本轮结束

04|Skills 渐进式加载机制

为什么需要渐进式加载?

假设你搭建了一个投研 Agent,有 8 个技能:股票查询、财报分析、新闻监控、估值计算、风险评估、组合优化、报告生成、邮件发送。每个 SKILL.md 平均 2000+ 字符,如果全部塞进 prompt,仅技能指导就要占用 16000+ 字符(约 4000 tokens),成本爆炸不说,模型还要在这些信息里找重点,容易分心。

Nanobot 的解决方案是三级加载系统

第 1 级:元数据(永远在 context 中,约 100 words/skill)

SkillsLoader.build_skills_summary()把所有技能生成 XML 摘要注入 system prompt:

<skills> <skill available="true"> <name>web-search</name> <description>联网搜索实时市场信息</description> <location>/path/to/web-search/SKILL.md</location></skill><skill available="false"> <name>database-query</name> <description>查询本地数据库</description> <location>/path/to/database-query/SKILL.md</location></skill></skills>

Agent 看到的是一个技能清单,知道自己"有什么工具可以用",但不需要知道"具体怎么用"。

第 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_file)

System 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 available="false" 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: return"query_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: return"Error: empty SQL query" # 安全校验:只允许 SELECT 和 PRAGMA upper = sql.upper().lstrip() ifnot (upper.startswith("SELECT") or upper.startswith("PRAGMA")): return"Error: 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: return"Query 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: returnf"SQL Error: {e}"

这个工具的设计有四个层次:

  1. 工具元数据namedescriptionparameters会被 ToolRegistry 收集,转换成 LLM function calling 的 schema 发给模型
  2. 安全校验:代码层面强制只允许 SELECT 和 PRAGMA,防止误操作
  3. 执行 SQL:连接数据库、执行查询、获取结果
  4. 结果限制:最多返回 50 行,防止大表查询撑爆上下文窗口

第二步:组装整个 Agent

def build_bot() -> Nanobot: """创建 Nanobot 实例,使用 config.json 配置""" bot = Nanobot.from_config( config_path=WORKSPACE / "config.json", workspace=WORKSPACE, ) # 注册自定义 SQL 查询工具 bot._loop.tools.register(QueryDBTool(DB_PATH)) return bot

组装完成后,Agent 可用的工具集包括:

  • read_file(框架内置):读文件(加载 SKILL.md)
  • write_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 的安全限制。

第五步:编写 Skills

schema-exploration SKILL.md

## Workflow1. Use `query_db(sql="SELECT name FROM sqlite_master WHERE type='table'")` to list all tables2. For each relevant table, run `query_db(sql="PRAGMA table_info(TableName)")` to see columns3. Identify primary keys, foreign keys, and relationships4. Summarize the schema for the user

query-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(sql="YOUR 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 type='table'")=> 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 开发本质的深刻理解:

  1. 配置优先:一个 config.json 就能定义完整 Agent,不需要写大量胶水代码
  2. Skills 渐进式加载:用三级加载系统高效管理上下文,避免 token 浪费
  3. 显式工具注册:继承 Tool 基类的方式虽然比装饰器多写几行代码,但参数验证、只读标记等元数据一目了然
  4. 非侵入式扩展: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%免费

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/27 6:34:23

AI重构实战:三级诊断框架与先问后码工作流,规避过度设计陷阱

1. 从代码异味到策略魔法&#xff1a;用人类判断驾驭AI2026年&#xff0c;问题早已不是“AI会不会写代码”了。它当然会。你的新“AI初级同事”不知疲倦&#xff0c;从不抱怨冗长的会议&#xff0c;一秒钟就能吐出五千行代码。它读过每一本架构书&#xff0c;对从策略模式到仓储…

作者头像 李华
网站建设 2026/5/27 6:32:20

Vue3 服务端渲染(SSR)实战 | 用 Nuxt3 搭建 SEO 友好的 Vue3 项目

前言&#xff1a;SEO 差&#xff1f;SPA 项目的"阿喀琉斯之踵" 作为前端开发者&#xff0c;你是否遇到过这种情况&#xff1a; SEO 工程师&#xff1a;“我们网站在 Google 搜索结果里怎么连影子都找不到&#xff1f;” 产品经理&#xff1a;“用户分享链接到微信&a…

作者头像 李华
网站建设 2026/5/27 6:29:13

《全流程闭环学术研究方法论体系构建:课题选择、基础理论、科学思维、学术创新与第四科研范式贡献的标准化路径》

《全流程闭环学术研究方法论体系构建&#xff1a;课题选择、基础理论、科学思维、学术创新与第四科研范式贡献的标准化路径》 作者&#xff1a;方见华 单位&#xff1a;世毫九实验室 摘要 &#xff08;内容概要&#xff1a;针对当前学者尤其是青年学者面临的选题迷茫、理论根基…

作者头像 李华
网站建设 2026/5/27 6:24:17

DynamIQ ACP访问机制与缓存一致性优化实践

1. ACP访问机制概述在DynamIQ共享单元(DSU)架构中&#xff0c;ACP(Accelerator Coherency Port)作为外部设备访问缓存子系统的关键接口&#xff0c;提供了两种不同的访问模式&#xff1a;常规(non-stashed)访问和stashed访问。这两种机制虽然最终都能实现对L3缓存的访问&#x…

作者头像 李华