NoteTool在上下文工程中的角色——HelloAgents深度解析
文章目录
前言
这篇文章讲 NoteTool 在上下文工程里到底扮演什么角色,它和 Memory 系统、summary.md 压缩有什么本质区别,读完你能判断自己的 agent 项目需不需要一个 NoteTool。
你肯定遇到过这种场景:agent 跑了 30 轮工具调用,上下文快满了,但任务才做了一半——中间的分析结论、阻塞问题、下一步计划全堆在窗口里。compact 压缩一触发,丢了细节;不压缩,窗口爆了。
NoteTool 就是解决这个问题的。
一、NoteTool 是什么
NoteTool 是 HelloAgents 框架内置的项目级持久笔记工具,代码在 hello_agents/tools/builtin/note_tool.py。
它跟 MemoryTool 的分工很明确:
MemoryTool 管对话级记忆(Working + Episodic + Semantic)
NoteTool 管项目级有状态任务——长流程、多步骤、需要跨多次调用追踪进度
一句话:把关键信息写到上下文窗口外的持久存储,需要时再拉回来。
二、存储格式:Markdown + YAML
每篇笔记是一个独立的 .md 文件,头部是 YAML 元数据,正文是 Markdown:
---
id: note_20260518_001
title: "修复登录模块 500 错误"
type: blocker
tags: ["auth", "urgent"]
created_at: 2026-05-18T10:00:00
updated_at: 2026-05-18T11:30:00
---
## 问题描述
登录接口返回 500,定位到 token 刷新逻辑里的空指针。
## 排查过程
1. 检查了 auth.py 的 refresh_token 函数
2. 发现用户表缺少 refresh_token_expires 字段
3. 迁移脚本已生成,待执行
额外还有一个 notes_index.json 文件,存所有笔记的元数据索引——不用打开所有文件就能快速检索。
为什么选这种格式?
- 人可读:直接用编辑器打开就能看懂
- Git 友好:纯文本,diff 清晰,方便版本控制
- 容易注入回上下文:ContextBuilder 直接读 Markdown 转成 ContextPacket
三、六种笔记类型
NoteTool 把笔记按语义分了六类,不是随便打的标签——每类在上下文注入时有不同的优先级:
| 类型 | 用途 | 检索优先级 |
|---|---|---|
blocker |
阻塞问题和 bug | 最高(0.9) |
action |
下一步行动计划 | 高(0.8) |
task_state |
阶段进度追踪 | 中(0.75) |
conclusion |
关键结论和决策 | 中(0.7) |
reference |
参考材料 | 低(0.6) |
general |
兜底类型 | 低(0.6) |
设计逻辑很清晰:
blocker 不解决,后续所有工作都没意义 → 0.9,最先注
入action 告诉你"下一步干什么" → 0.8,紧跟其后
conclusion 是已经沉淀的判断 → 0.7,需要时再看
reference 是参考资料 → 0.6,锦上添花
这个优先级不是硬编码死的,是 ContextBuilder 在构造上下文时的默认打分策略,你可以按自己的项目调整。
四、七个操作:完整生命周期
NoteTool 提供了 7 个 action,覆盖笔记的完整生命周期:
create → 新建笔记,自动生成唯一 ID,写入文件和索引
read → 读取指定笔记,分离 YAML 元数据和 Markdown 正文
update → 修改笔记内容/标签/类型,更新修改时间
search → 按关键词搜索标题和正文,支持类型和标签过滤
list → 列出笔记列表(只返回元数据,不返回全文)
summary → 统计概览:总数、类型分布、最近更新的 5 篇
delete → 删除笔记文件和索引条目
注意 search 和 list 的区别:
list只读索引文件,快但不深入正文。search遍历匹配的笔记全文,慢但准确。
agent 应该先list概览,再search精确定位。
五、NoteTool 和 Memory 系统的关系
HelloAgents 有完整的记忆体系,NoteTool 是其中的一环:
工作记忆(WorkingMemory)
├─ 当前对话上下文
└─ 会话结束即清空
│
▼
NoteTool(项目笔记)
├─ 跨会话持久化
├─ 结构化的项目状态
└─ 按需检索注入
│
▼
情景记忆(EpisodicMemory)
├─ 记录"什么时间发生了什么"
└─ 为语义记忆提供原材料
│
▼
语义记忆(SemanticMemory)
├─ 从事件中提炼的抽象知识
└─ 向量检索 + 知识图谱
NoteTool 夹在 WorkingMemory 和 EpisodicMemory 之间:比 Working 活得久,比 Episodic 更结构化、更主动。
六、NoteTool vs summary.md:本质区别
Claude Code 的 AutoCompact 流程会自动生成 summary.md,看起来跟 NoteTool 很像——都是 Markdown、都存磁盘、都能注入回上下文。
但本质完全不同:
| summary.md | NoteTool | |
|---|---|---|
| 生成方式 | compact 被动触发,系统自动 | agent 主动调用,显式写入 |
| 内容粒度 | 一篇不断被覆写的总摘要 | 多篇分类独立笔记 |
| 检索方式 | 压缩时全量注入 | 按类型打分 + 关键词搜索 + 限数量 |
| 跨会话 | 不继承,每次新会话是空的 | 自动继承,新会话拉 blocker/action |
| 本质 | compact 流程的中间产物 | 上下文工程的主动管理工具 |
一句话总结:
summary.md 是为了腾窗口空间,NoteTool 是为了管理项目状态。
前者是压缩的副产品,后者是上下文工程的一等公民。
七、NoteTool 和分块流水线的关系
前面讲文本分块时提到的六步流水线:
标准Markdown文本 → 标题层次解析 → 段落语义分割
→ Token计算分块 → 重叠策略优化 → 向量化准备
NoteTool 写出的笔记在进入向量库(Qdrant)之前,也要经过这套流水线。但有两个特殊处理:
- 标题结构保留:笔记的 YAML + Markdown 结构天然适合标题解析,不会像普通文档那样被切碎
- 元数据增强:分块时会带上笔记的 type 和 tags 作为附加向量维度,让检索不只是文本匹配,还有类型权重
八、自动创建机制
HelloAgents 的 CodebaseMaintainer 例子里有一个精妙的设计——后处理自动建笔记:
响应内容检测:
含"问题"/"bug"/"错误"/"阻塞" → 自动建 blocker 笔记
含"计划"/"下一步"/"任务"/"todo" → 自动建 action 笔记
不需要 agent 显式调用 NoteTool,框架层检测关键词自动归档。这比全靠 agent 自己判断写到哪儿更可靠——agent 可能"忘记"记笔记,但框架不会。
九、你的 agent 需不需要 NoteTool
不是所有 agent 都需要 NoteTool。判断标准很简单:
| 场景 | 需要 NoteTool? |
|---|---|
| 单轮问答,不超 10 次工具调用 | 不需要,窗口装得下 |
| 多轮但每次独立,不跨会话 | 不需要,compact 够用 |
| 长任务 + 跨会话 + 有依赖关系 | 需要,否则上下文爆炸 |
| 多人协作的项目级 agent | 必须,笔记是共享状态 |
如果你在做 Java agent 项目,可以先从简化版开始:
第一版:只做 blocker + action 两种类型,SQLite 存储
第二版:加上 search/list 操作和 relevance 打分
第三版:接入向量库做语义检索
不要一上来就把六种类型七个操作全实现——过度设计是 agent 项目最常见的坑。
十、总结
NoteTool 解决的不是"怎么记"的问题,而是"记了怎么用"的问题。它的核心价值不在存储,在检索注入的策略:按类型打分、按优先级注入、限制数量避免窗口污染。
跟 Claude Code 对比,两者的设计哲学差异很明显:
Claude Code:给你 1M 窗口 + 子 Agent 隔离,靠"大"来解决
HelloAgents:精细化上下文管理,靠"准"来解决
没有谁更好——如果你的底层模型有 1M 窗口,确实可以省掉很多工程设施。但如果你用的是窗口有限的模型,或者在做一个需要展示架构完整性的项目,NoteTool 的设计思路非常值得借鉴。
更多推荐



所有评论(0)