
nanobot Prompt Overrides 指南用dream.md与evaluator.md自定义 Dream 记忆与心跳通知门控【免费下载链接】nanobotUltra-lightweight, open-source, self-hosted personal AI agent framework in Python with WebUI, tools, memory, MCP, multi-agent workflows, automation, and chat apps项目地址: https://gitcode.com/gh_mirrors/nanob/nanobot本文介绍 nanobot 工作区级提示词覆盖Prompt Overrides机制如何通过prompts/dream.md定制 Dream 的长期记忆整理方式以及通过prompts/evaluator.md定制心跳heartbeat结果通知门控的判定标准。读完本文你将掌握/dream-prompt与/evaluator-prompt两个命令的完整用法、覆盖文件的解析与加载规则以及如何安全地删除覆盖文件回退到内置默认行为。一、什么是 Prompt OverridesPrompt Overrides 说明文档 定义了 nanobot 工作区中一类特殊的纯文本文件它们位于工作区的prompts/目录下以普通 Markdown 形式书写用于整体替换系统内置的某段系统提示词system prompt而不是追加或拼接。这套机制的核心文件路径约定定义在 workspace_prompts.pydef workspace_prompt_file(workspace: Path, name: str) - Path: Return the conventional path for a named workspace prompt override. return workspace / prompts / f{name}.md也就是说任何一个名为name的覆盖文件都遵循prompts/name.md这一固定命名规范。当前仓库内置了两种可覆盖的提示词覆盖文件命令作用prompts/dream.md/dream-prompt init决定 Dream 如何组织工作区长期记忆prompts/evaluator.md/evaluator-prompt init决定心跳结果是否值得推送给用户两个命令的是否已创建覆盖判断、文件创建逻辑均复用了initialize_workspace_prompt()/has_workspace_prompt_override()见 workspace_prompts.py因此行为完全一致只有文件存在且非空时才视为覆盖生效文件缺失、无法读取或为空时一律回退到内置默认提示词。二、覆盖文件的加载与解析规则在深入具体覆盖项之前先理解通用的加载规则这对理解删除/清空即恢复默认的行为至关重要。load_workspace_prompt_override()是统一的加载入口workspace_prompts.pydef load_workspace_prompt_override( path: Path, *, max_chars: int WORKSPACE_PROMPT_MAX_CHARS, ) - tuple[str | None, int]: Load and cap a non-empty UTF-8 prompt override. Returns the loaded text and its original length. Missing, unreadable, and empty files return (None, 0) so callers can fall back to their default. 从源码可以提炼出四条关键规则非空才生效文件读取后执行rstrip()若内容为空则返回(None, 0)调用方回退到默认提示词。UTF-8 编码覆盖文件必须为 UTF-8 编码编码错误UnicodeDecodeError会被静默吞掉并按无覆盖处理。长度上限 32,000 字符WORKSPACE_PROMPT_MAX_CHARS 32_000workspace_prompts.py。超长覆盖会被truncate_text截断同时保留原始长度供调用方记录告警日志。这是防止失控文件撑爆评估调用的安全阀。删除或清空 恢复默认因为加载器对缺失/空一律返回None所以删除文件或将文件清空是等价的回退操作。三、覆盖 Dream 记忆组织方式dream.md3.1 Dream 是什么Dream 是 nanobot 中负责把会话历史整理进长期记忆的后台组件。它读取memory/history.jsonl中当前游标之后的新条目调用 LLM 将对话压缩为原子化事实并写入SOUL.md、USER.md、memory/MEMORY.md等持久化记忆文件。默认的 Dream 指令模板位于 agent/dream.md内含文件路由表、历史属性标签[skip]/[correction]/[permanent]/[durable]/[ephemeral]、技能创建标准与编辑校验要求。对于绝大多数用户默认行为已经足够不需要修改。但如果你希望调整记忆的路由策略、保留规则或整理风格可以通过覆盖文件完全替换这份内置指导。3.2 创建可编辑副本在任意聊天渠道WebUI、Telegram 等输入/dream-prompt init该命令由 cmd_dream_prompt 实现。其执行逻辑如下调用initialize_workspace_prompt(path, store.default_dream_prompt())其中path为prompts/dream.md由 memory.py 的dream_prompt_file属性提供若目标文件不存在或为空则以内置默认模板为内容创建文件并返回已创建提示若目标文件已存在且非空则不会覆盖任何已有内容仅提示已存在需要你自行编辑。注意/dream-prompt init是幂等的安全命令——initialize_workspace_prompt()的源码明确保证不会覆写非空文件workspace_prompts.py所以重复执行不会丢失你的自定义内容。3.3 覆盖文件的生效机制Dream 运行时通过build_dream_prompt()组装提示词memory.py其中_dream_template()负责选择模板memory.pydef _dream_template(self) - str: text, original_chars load_workspace_prompt_override(self.dream_prompt_file) if text is not None: if original_chars WORKSPACE_PROMPT_MAX_CHARS and not self._dream_prompt_oversize_logged: self._dream_prompt_oversize_logged True logger.warning(workspace Dream prompt exceeds {} chars ({}); truncating. ...) return text return self.default_dream_prompt()可见一旦prompts/dream.md存在且非空它就会整体替换默认模板注意整体替换而非追加随后 Dream 提示词由覆盖文件内容 会话历史两部分组成template self._dream_template() prompt f{template}\n\n## Conversation History\n{history_text}默认模板通过render_template(agent/dream.md, ...)渲染memory.py因此你创建的可编辑副本就是这份默认模板的文字版可直接在其基础上修改。3.4 恢复默认行为想要放弃自定义只需删除prompts/dream.md或将其内容清空。由于加载器对空文件返回NoneDream 会自动回退到内置默认模板无需重启。3.5 查看当前状态不带参数直接执行/dream-prompt命令会反馈当前工作区的 Dream 记忆指令状态已有自定义显示文件路径并提示删除或清空此文件可恢复默认使用内置默认提示可编辑文件路径并给出/dream-prompt init建议。四、覆盖心跳通知门控evaluator.md4.1 心跳评估器是什么nanobot 的心跳heartbeat机制会在后台周期性地执行内部检查。每次检查结束后系统会发起一次轻量级 LLM 调用由评估器决定这次结果是否值得推送给用户——这就是文档中提到的heartbeat notification gate心跳通知门控。该模块的完整实现位于 evaluator.py。模块 docstring 明确说明其定位After heartbeat executes an internal check, this module makes a lightweight LLM call to decide whether the result warrants notifying the user.内置的默认评估器系统提示词模板见 agent/evaluator.md其中明确了何时通知 / 何时抑制的判定标准应当通知包含可操作信息、错误、已完成的交付物、定时提醒/计时器完成或用户明确要求被提醒的内容用户安排的提醒即使回复简短也通常应通知应当抑制例行状态检查且无新信息、一切正常的确认、内容基本为空以及关于任务本身的元推理如描述内部指令、引用 HEARTBEAT.md/AWARENESS.md 等配置文件、讨论是否要通知用户——用户永远不应看到 Agent 在思考要不要说话。4.2 创建可编辑副本输入/evaluator-prompt init该命令由 cmd_evaluator_prompt 实现逻辑与/dream-prompt init完全对称以默认评估器提示词为内容创建prompts/evaluator.md若文件已存在且非空则不做任何覆写。从源码可见该命令明确声明了它的两条硬性约束builtin.py必须保留对evaluate_notification工具的调用指令否则门控 fail closed 并保持沉默the gate fails closed and stays silent。4.3 为什么必须保留evaluate_notification工具调用评估器的判定不是靠自由文本回复而是靠强制调用一个结构化工具。该工具定义在 evaluator.py_EVALUATE_TOOL [ { type: function, function: { name: evaluate_notification, description: Decide whether the user should be notified about this background task result., parameters: { type: object, properties: { should_notify: { type: boolean, description: true result contains actionable/important info the user should see; false routine or empty, safe to suppress, }, reason: { type: string, description: One-sentence reason for the decision, }, }, required: [should_notify], }, }, } ]而evaluate_response()evaluator.py的判定流程是if not llm_response.should_execute_tools: ... return default_notify # 心跳场景下 default_notifyFalse即 fail closed也就是说如果评估模型没有执行工具调用无论是因为你的覆盖提示词没让它调用还是模型异常结果都会回退到default_notify——心跳场景传入的是False于是门控默认不通知、保持沉默。这正是文档强调删除或清空文件可恢复内置提示词的原因一旦自定义文件把工具调用指令写丢通知门控就会永久静默。另外值得注意的是评估调用本身使用temperature0.0并携带evaluate_notification工具定义evaluator.py调用失败时同样回退到default_notify并记录异常日志。4.4 覆盖文件的选择与截断resolve_evaluator_prompt()evaluator.py与 Dream 侧逻辑一致存在非空覆盖则使用覆盖否则返回内置默认。同时EVALUATOR_PROMPT_MAX_CHARS复用了WORKSPACE_PROMPT_MAX_CHARS32,000 字符超长覆盖会被截断并记录告警——这正是文档称之为高级覆盖advanced override的原因你不仅要写对判定标准还要确保不破坏工具调用契约与长度限制。4.5 恢复默认行为删除prompts/evaluator.md或将其清空has_evaluator_prompt_override()会返回False评估器随即回退到内置默认提示词。五、两个命令的通用行为小结操作命令结果创建/初始化可编辑副本/dream-prompt init生成prompts/dream.md已存在则跳过创建/初始化可编辑副本/evaluator-prompt init生成prompts/evaluator.md已存在则跳过查看当前状态/dream-prompt反馈自定义/默认状态与文件路径查看当前状态/evaluator-prompt反馈自定义/默认状态与文件路径恢复默认删除或清空对应文件下一次运行时自动回退内置提示词六、相关源码与测试验证覆盖机制核心workspace_prompt_file()、load_workspace_prompt_override()、initialize_workspace_prompt()见 workspace_prompts.pyDream 模板解析与组装_dream_template()、build_dream_prompt()、dream_prompt_file见 memory.py评估器与evaluate_notification工具契约resolve_evaluator_prompt()、evaluate_response()见 evaluator.py两个命令的路由注册router.exact(/dream-prompt, ...)与router.exact(/evaluator-prompt, ...)见 builtin.py命令解析与消息转发含 Telegram 渠道的/dream-prompt、/evaluator-prompt归一化处理见 telegram/runtime.py命令行为测试覆盖/dream-prompt init、/evaluator-prompt init的解析与使用说明见 test_telegram_channel.py。七、使用建议默认即可按需覆盖Dream 与心跳评估器的内置提示词经过完整设计绝大多数工作区无需任何修改仅在确实需要改变记忆路由策略或通知判定标准时创建覆盖文件。覆盖即整体替换prompts/dream.md、prompts/evaluator.md不是增量补丁而是对默认提示词的完全替换编辑时请先通读默认模板确保没有丢失必要指令。守护工具调用契约编辑evaluator.md时务必保留调用evaluate_notification工具并返回should_notify/reason的指令否则通知门控会 fail closed 而永久静默。回退永远安全删除或清空覆盖文件即可一键恢复内置行为命令本身幂等、绝不覆写已有内容可以放心反复尝试。这套 Prompt Overrides 机制把工作区级行为定制从代码层面下沉到了纯文本配置层面不修改任何 Python 源码即可为每个工作区定制 Dream 的记忆整理逻辑与心跳通知的判定标准。【免费下载链接】nanobotUltra-lightweight, open-source, self-hosted personal AI agent framework in Python with WebUI, tools, memory, MCP, multi-agent workflows, automation, and chat apps项目地址: https://gitcode.com/gh_mirrors/nanob/nanobot创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考