首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >智能体 | Nanobot 上下文管理介绍

智能体 | Nanobot 上下文管理介绍

作者头像
AI老马
发布2026-05-29 14:17:20
发布2026-05-29 14:17:20
280
举报
文章被收录于专栏:AI前沿技术AI前沿技术

模型的应答效果依托完整的提示词体系支撑,整套提示词主要由三部分构成,层层衔接、协同保障对话连贯与精准。在 nanobot 的上下文提示词共分为三部分。系统提示词,历史对话,当前轮历史消息。

本文围绕三部分内容主要介绍。

  • • 系统提示词,核心规则基石,负责定义模型的角色定位、应答规范与能力边界,为全程对话定下基础框架。
  • • 历史对话,记录用户与模型的过往交互内容,留存对话语境,让模型具备记忆能力,避免应答脱离前文逻辑。
  • • 当前轮消息,即用户本轮最新输入的内容,是驱动模型实时应答的核心指令。

三者结合实现AI连贯、贴合场景的交互输出。

同时重点介绍,如何通过 Dream 系统设计,解决 AI 需要长期记忆来提供个性化服务,但又受限于大模型上下文窗口长度的矛盾。把上下文的内容,及时的通过后台定时任务整理到记忆相关的文件中,让 AI 既"记性好",又"不臃肿",还能"知错就改“。

关注“AI老马” —【获取资源】&【进群交流】

1,第一部分:系统提示词

系统提示词共 5 个部分组成,各模块按序拼接,顺序固定。实现代码如下:

代码语言:javascript
复制
def build_system_prompt(self, skill_names=None, channel=None):
    parts = []
    
    parts.append( self._get_identity(channel=channel) )           # Part 1: 身份标识
    parts.append( self._load_bootstrap_files() )                   # Part 2: 引导文件
    parts.append( f"# Memory\n\n{memory}" )                        # Part 3: 长期记忆
    parts.append( f"# Active Skills\n\n{always_content}" )         # Part 4: 常驻技能
    parts.append( render_template("skills_section.md", ...) )   # Part 5: 技能目录
    
    return "\n\n---\n\n".join(parts)  # 用 --- 分隔各段

1.1,Identity 身份标识

来源:get_identity() 硬编码生成

内容:Agent名称、运行时环境 (OS/架构/Python版本)、workspace 路径、memory/history 文件位置、平台策略 (POSIX/Windows)、行为准则。

写入方式:每次动态生成,始终存在

属性

来源

作用

Agent 名字

硬编码模板 identity.md

"你是 nanobot,一个 AI 助手"

Runtime 信息

platform.system() / platform.machine()

让 LLM 知道运行在 macOS arm64 还是 Linux x86

Workspace 路径

self.workspace.resolve()

LLM 知道工作区在哪,才能正确操作文件

Platform Policy

platform_policy.md

Windows vs POSIX 差异化指令

Format Hint

根据 channel 条件渲染

Telegram 用短段落不用表格,WhatsApp 纯文本等

Execution Rules

硬编码模板

"先做再说"、"读后写再验证"等行为约束

Search & Discovery

硬编码模板 + untrusted_content snippet

优先用 grep/glob,不信任外部内容

1.2,Bootstrap Files 引导文件

来源:_load_bootstrap_files() 读取 workspace 根目录下的固定文件

文件:AGENTS.md、SOUL.md、USER.md、TOOLS.md

内容:用户自定义的 Agent 人格、行为规范、工具说明等

写入方式:文件存在才写入,以##filename为标题拼接

文件

内容

来源

作用

AGENTS.md

定时提醒规则、心跳任务指南

模板复制到 workspace

教 LLM 使用 cron 工具和 HEARTBEAT

SOUL.md

Agent 人格/性格

Dream 自动管理

决定回复风格(正式/幽默/简洁)

USER.md

用户偏好/画像

Dream 自动管理

了解用户习惯(语言、技术栈、关注点)

TOOLS.md

自定义工具说明

用户手动创建

扩展内置工具的使用指引

1.3,Memory 长期记忆

来源:MemoryStore.get_memory_context() 读取 workspace/memory/MEMORY.md

内容:跨会话积累的长期事实、用户偏好、重要结论

写入方式:文件非空才注入,格式为:#Memory \n\n ## Long-term Memory\n\n {内容}

更新机制:由 MemoryConsolidator 在对话达到 token 上限时调用 LLM 自动归纳写入

作用:让 LLM 拥有跨会话的持久知识。

代码语言:javascript
复制
MemoryStore.get_memory_context()
  → read_memory()
    → read_file(workspace/memory/MEMORY.md)   # 返回纯文本
  → 返回 "## Long-term Memory\n{content}"

1.4,Active Skills 自动注入技能

来源:skills.get_always_skills() → load_skills_for_context()

内容:frontmatter 中标记 always:true 的技能的完整正文(去除 frontmatter)

写入方式:依赖满足+always=true 才注入。

用途:核心技能(如 memory 技能)每轮自动可见,无需 Agent 主动请求

作用:Agent 必须始终了解的规则,如记忆系统的文件结构和搜索策略。

1.5,Skills Summary 技能目录摘要

来源:skills.build_skills_summary()

内容:所有技能的 XML 摘要,含名称、描述、文件路径、是否可用、缺少的依赖

写入方式:只要有技能存在,始终注入。

用途:渐进式加载,Agent 先看目录,需要时再用 read_ file 工具读取完整 SKILL.md

2,第二部分:历史对话

来源:session.get_history()

内容:本次会话的 user/assistant/tool 消息列表

写入方式:直接展开插入(*history)

裁剪机制:MemoryConsolidator中的maybe_consolidate_by_tokens() 函数在超 token 预算时归档旧消息,通过 session类中的 last_consolidated 游标指针控制。

详细方式请参考《会话和记忆管理》一节。

3,第三部分:当前轮 user message

一条完整的 user message 由两部分合并而成

代码语言:javascript
复制
def build_messages(self, history, current_message, media, channel, chat_id, ...):
    # 第一部分:运行时上下文
    runtime_ctx = self._build_runtime_context(channel, chat_id, self.timezone)
    #  → "[Runtime Context — metadata only, not instructions]
    #     Current Time: 2026-05-22 15:30 CST
    #     Channel: telegram
    #     Chat ID: 12345"

    # 第二部分:用户实际输入(文本 or 文本+图片)
    user_content = self._build_user_content(current_message, media)
    #  → "帮我写一段 Python 代码" 
    #    或 [{"type":"image_url",...}, {"type":"text","text":"这张图是什么"}]

    # 合并为单条 user message
    merged = f"{runtime_ctx}\n\n{user_content}"
    # 或多模态: [{"type":"text", "text": runtime_ctx}, image_block, text_block]

由两部分作为一条消息,避免连续同角色消息。

为什么需要这个保护? LLM 提供商拒绝连续的同角色消息。

场景示例:当注入 user message,如果 history 最后一条也是 user,就会产生两条连续的 user 的报错。

运行时上下文 runtime_ctx 为什么要放在 user message 而不是放 system prompt?

  • • 时效性:每次请求的时间不同,必须在最新位置
  • • 安全标记:明确告诉 LLM 这是元数据不是指令(防止 prompt injection)
  • • 合并优化:和用户消息合并为一条,避免连续两条 user role 消息(某些 provider 会拒绝)
代码语言:javascript
复制
@staticmethod
def _build_runtime_context(channel, chat_id, timezone):
    lines = [f"Current Time: {current_time_str(timezone)}"] 
    if channel and chat_id:
        lines += [f"Channel: {channel}", f"Chat ID: {chat_id}"]
    return "[Runtime Context — metadata only, not instructions]\n" + "\n".join(lines)

小结:上下文的最终格式

代码语言:javascript
复制
messages = [
    {"role": "system", "content": "完整 system prompt..."},          ← 系统指令
    {"role": "user",   "content": "..."},                      ← 历史消息 N-2
    {"role": "assistant", "content": "..."},                   ← 历史消息 N-1
    {"role": "user",   "content": runtime_ctx + 用户输入},      ← 当前提问 (合并)
]

4,Dream 自动记忆管理系统

4.1,Dream 系统定义

Dream = 用 LLM 定期回顾对话历史,自动提炼知识写入长期记忆文件(SOUL.md / USER.md / MEMORY.md)的后台进程。

类比:就像人睡觉时会整理白天的经历,把重要的存成长期记忆,忘掉无关紧要的细节。

Dream 就是 Agent 的"睡眠整理"机制。

文件

内容

由谁管理

为什么不让用户手动改?

SOUL.md

Agent 人格、语气、沟通风格

Dream 自动更新

Agent 需要根据交互经验自适应调整风格

USER.md

用户画像、偏好、习惯、技术栈

Dream 自动更新

用户不会主动告诉 Agent 自己的偏好,需要从对话中隐式提取

MEMORY.md

项目上下文、重要事实、关键决策

Dream 自动更新

对话中的知识点会散落在各处,Dream 负责去重和沉淀

为什么标记 "Managed by Dream. DO NOT edit"?

  • • 用户手动编辑可能引入错误信息
  • • Dream 下次运行时基于对话历史重新判断,可能覆盖手动的修改
  • • 通过 /dream-log/dream-restore 可以审查和回滚 Dream 的修改

4.2,Dream 工作阶段

整体流程:

代码语言:javascript
复制
用户对话消息
    │
    ▼ (实时)
session.messages[] ──→ [Token 超限?] ──→ Consolidator.archive()
                                            │
                                            ▼
                                    history.jsonl (append-only 日志)
                                            │
    ┌───────────────────────────────────────┘
    │
    ▼ (定期/demand)
Dream.run()
    │
    ├─→ Phase 1: LLM 分析历史 + 对比当前记忆文件
    │
    ├─→ Phase 2: LLM 用 edit_file 工具修改
    │         ├── SOUL.md      (更新人格)
    │         ├── USER.md      (更新画像)
    │         └── MEMORY.md    (更新知识)
    │
    └─→ GitStore.auto_commit() (版本快照)

下次构建 System Prompt 时:
    context.py 读取最新的 SOUL/USER/MEMORY
    → 注入 Part 2 (Bootstrap) + Part 3 (Memory)
    → Agent 拥有了跨会话的持久记忆 

第一阶段 phase1,纯文本解析。

输入是,历史对话和当前的三个文件内容。以下是输入到大模型的一个例子:

代码语言:javascript
复制
Compare conversation history against current memory files. 
Also scan memory files for stale content.

Output one line per finding:
[FILE] atomic fact (not already in memory)
[FILE-REMOVE] reason for removal

Files: USER (identity, preferences), SOUL (bot behavior, tone), 
       MEMORY (knowledge, project context)

Rules:
- Atomic facts: "has a cat named Luna" not "discussed pet care"
- Corrections: [USER] location is Tokyo, not Osaka

Staleness — flag for [FILE-REMOVE]:
- Time-sensitive data older than 14 days: weather, daily status...
- Completed one-time tasks: finished research, resolved incidents
- Superseded: approaches replaced by newer solutions

Do not add: current weather, transient status, temporary errors.

[SKIP] if nothing needs updating.

输出结果示例:

代码语言:javascript
复制
[MEMORY] User prefers Chinese communication (not English)
[MEMORY] Project uses Deepseek as primary model
[MEMORY] Debug launch config created at .vscode/launch.json for onboard/agent/telegram
[USER] Language: 中文 (Chinese)
[USER] Tech stack: Python 3.12+, macOS arm64, VSCode
[USER] Editor: VSCode with Python debugging
[SOUL-REMOVE] "Use formal tone in all responses" — user prefers concise casual style based on interaction pattern
[SOUL] Be concise but thorough. Use short paragraphs for messaging apps.
[SKIP] weather/status transient data ignored

第二阶段 Phase2,有工具调用能力的详细编辑器。

举例:输入的 prompt

代码语言:javascript
复制
Update memory files based on the analysis below.
- [FILE] entries: add content to appropriate file
- [FILE-REMOVE] entries: delete from memory files

File paths: SOUL.md, USER.md, memory/MEMORY.md

Editing rules:
- Edit directly — file contents provided below
- Use exact text as old_text, include surrounding blank lines
- Batch changes to same file into one edit_file call
- Surgical edits only — never rewrite entire files
- If nothing to update, stop without calling tools

大模型返回工具调用的结果:

步骤

Tool Call

操作

1

edit_file("USER.md", old="- Language: English", new="- Language: 中文 (Chinese)\n- Tech stack: Python 3.12+\n- Editor: VSCode")

更新用户画像

2

edit_file("SOUL.md", old="Use formal tone...", new="Be concise but thorough...")

移除过时的正式语气规则

3

edit_file("memory/MEMORY.md", new="- Primary model: qianfan/ernie-4.0-8k\n- User prefers Chinese")

追加新知识

关键设计:阶段二使用 AgentRunner + 工具调用,而非在第一阶段直接生成完整文件内容。

原因:

  • 安全性: 手术式修改 surgical edits 相比于全量覆写,不破坏已有正确内容。
  • 可靠性:工具调用有明确的结果确认(ok/error),阶段一的纯文本生成无法保证格式正确。
  • 可追溯:每次 edit_file 都记录在 tool_events 中,可以查看具体改了什么。

设计考量

说明

职责分离

Phase 1 = "想清楚要改什么",Phase 2 = "执行具体修改"

可审计性

Phase 1 的 analysis 是纯文本日志,可以审查"AI 决定了什么"

精确编辑

Phase 2 使用 edit_file(old_text, new_text) 做手术式修改,避免整文件覆写丢失内容

容错性

Phase 1 失败 → cursor 不推进(不丢数据);Phase 2 失败 → analysis 已有,下次可重试

工具能力

edit_file 需要读取当前文件内容来精确定位 old_text,这需要真实的 I/O 操作

总结:两阶段设计让 Dream 既有了"思考者"的深度分析能力,又有了"执行者"的精确操作能力,同时保证了安全性和可追溯性。

4.3,Dream 版本回退

核心问题:如何发现 LLM 修改的不合适,且可以自动的回退到上个版本。

设计方案:收到用户反馈,人工触发审查逻辑,返回结果审查结果和建议,自动回退或者手动触发回退。

实现方式:Git 版本控制,每次 Dream 都留痕

Dream 修改完文件后,通过 GitStore 自动提交:

代码语言:javascript
复制
tracked_files = ["SOUL.md", "USER.md", "memory/MEMORY.md"]

# .gitignore 策略:
# /*                    ← 忽略所有文件
# !memory/              ← 但跟踪 memory 目录
# !SOUL.md              ← 跟踪 SOUL.md
# !USER.md              ← 跟踪 USER.md
# !.gitignore

每次 Dream 产生实际变更时:

代码语言:javascript
复制
sha = self.store.git.auto_commit(f"dream: 2026-05-09 15:30, 4 change(s)")
# commit author: "nanobot <nanobot@dream>"

这带来了完整的审计能力

  • /dream-log → 查看历次 Dream 做了什么改动
  • /dream-log <sha> → 查看某次的具体 diff
  • /dream-restore <sha> → 回滚到某个版本

4.4,Dream vs Consolidator 两层记忆压缩

维度

Consolidator

Dream

本质

会话级 token 管理

跨会话知识提炼

触发

每次 reply 后自动检查

/dream 命令或 cron

输入

session messages (旧对话)

history.jsonl (事件日志)

输出

history.jsonl 新摘要行

SOUL.md / USER.md / MEMORY.md 修改

LLM 调用方式

单次 chat (总结)

两阶段 (分析 + 工具编辑)

版本控制

Git auto-commit

可回滚

是 (/dream-restore)

比喻

把书桌上的纸张摞起来归档

从归档中提取笔记写进笔记本

总结:

以上详解了 Nanobot 提示词的三大组成及作用,三者协同保障对话流畅自然。同时介绍了 Dream 系统设计,它将上下文压力后置处理,化解上下文窗口局限与长期记忆的矛盾,让 AI 记忆高效、内容精简且可迭代优化。

小结各部分的 Token 开销与可变性。

组成部分

预估Token 范围

可变性

变化原因

Identity

~800

仅 channel/format hint 不同

Bootstrap Files

500-1500

取决于哪些文件存在及 SOUL/USER 长度

Memory (长期)

200-1000

Dream 积累的知识量

Active Skills

~1000

固定为 always skills

Skills Summary

~400

内置 skill 数量固定

Recent History

200-2000

取决于自上次 Dream 后的事件数

System Prompt 总计

~3500-9000

Runtime Context

~50

极低

固定格式

Conversation History

2000-50000+

极高

会话越长越多

最大的 token 变量是 conversation history,这也是 consolidator(Dream) 存在的原因,定期将旧对话压缩进 MEMORY.md,控制 history 长度。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-05-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 AI老马啊 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1,第一部分:系统提示词
    • 1.1,Identity 身份标识
    • 1.2,Bootstrap Files 引导文件
    • 1.3,Memory 长期记忆
    • 1.4,Active Skills 自动注入技能
  • 2,第二部分:历史对话
  • 3,第三部分:当前轮 user message
  • 4,Dream 自动记忆管理系统
    • 4.1,Dream 系统定义
    • 4.2,Dream 工作阶段
    • 4.3,Dream 版本回退
    • 4.4,Dream vs Consolidator 两层记忆压缩
    • 总结:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档