第三章 提示词系统——Agent的持久人格
核心问题:你花了一个小时把AI调教成你想要的样子——风格、规则、偏好全都对了。第二天打开新对话,它又回到了出厂设置。Agent如何才能"记住自己是谁"?
这不是AI不够聪明。这是提示词和对话活在同一生命周期里的必然结果。
对话结束,提示词消散。你花时间建立的风格、约定的规则、积累的配置——全都归零。下次重新来过,永远是第一天。更深的问题是:就算某次调教效果很好,你也说不清楚好在哪里。是哪句话起了作用?是哪条约束发挥了关键作用?没有记录,没有结构,就没有可复现的知识。
这是可工程化的问题,不只是效率问题。一个不可复现的过程,无法被团队共享,无法系统改进,出了问题也无从追溯。
OpenClaw的解法直指根源:把提示词写进文件,永久保留。这听起来像是一个技巧,实际上是一次范式转变——Agent的身份从此独立于任何一次对话而存在,可以版本控制,可以团队协作,可以持续积累。
一、临时指令的困境
本节要说清楚:传统提示词的问题是结构性的,不是个人技巧问题。
把所有配置压进一段系统提示词,注入对话开头——这是过去十年"提示词工程"的标准做法。表面上够用,但有三个隐患一直没有解决:
| 问题 | 具体表现 | 根本原因 |
|---|---|---|
| 临时性 | 对话结束即消散,每次从零开始 | 提示词与对话同一生命周期 |
| 不可工程化 | 无法复现,不知道哪里发挥了作用 | 没有结构,无法单独修改某一层 |
| 难协作 | 无法追溯谁改了什么、为什么改 | 一段私有文本,没有版本历史 |
三个问题有同一个根源:提示词是临时的。
OpenClaw的解法是一次解耦:把Agent的身份从对话生命周期中剥离出来,写进文件,独立存在。
传统方式:
对话开始 ──→ 用户输入提示词 ──→ AI响应 ──→ 提示词随对话消亡
OpenClaw方式:
┌──────────────────────────────────────┐
│ SOUL.md / USER.md / AGENTS.md ... │ ← 持久存在,与对话无关
└─────────────────┬────────────────────┘
↓ 每次推理前自动读取,动态组装
每次对话 ─────────→ 系统提示词 ──→ AI响应这个区别的意义不止于"方便"。文件是可以用 Git 版本控制的。你可以看到三个月前的配置和今天的差异,知道当初为什么那样改,在新项目里复用一套经过验证的配置——这些在"提示词即临时文字"的时代都不可能。
二、配置即人格:8个文件架构
本节解答:8个文件分别是什么,为什么这样划分。
一段"大杂烩"提示词拆成八个文件,不只是"更整齐"——它为配置引入了可寻址性:行为异常时,你知道去哪里找原因;要调整时,你知道改哪个文件会影响什么。
总览
| 文件 | 通俗类比 | 核心作用 |
|---|---|---|
SOUL.md | 人设与性格 | 定义"我是谁"——性格、价值观、行为准则 |
USER.md | 通讯录与画像 | 定义"你是谁"——用户画像、偏好、交互历史 |
AGENTS.md | 办事能力 | 定义"我怎么做事"——工作流、决策规则 |
TOOLS.md | 工具箱 | 定义"我有什么工具"——环境配置、资源映射 |
IDENTITY.md | 身份证/名片 | 定义Agent的身份标识和基础属性 |
MEMORY.md | 记事本/经验库 | 定义"我记得什么"——事实库、经验总结 |
HEARTBEAT.md | 闹钟/日程表 | 定义"我何时行动"——定时任务、触发条件 |
BOOTSTRAP.md | 出厂设置 | 新工作空间的初始引导配置 |
八个文件覆盖了Agent运作所需的所有维度:它是谁(SOUL、IDENTITY)、它服务谁(USER)、它怎么工作(AGENTS)、它有什么工具(TOOLS)、它记得什么(MEMORY)、它怎么主动行动(HEARTBEAT)、它如何初始化(BOOTSTRAP)。没有冗余,没有遗漏。
SOUL.md 与 AGENTS.md:人格与规则的分离
LLM有一个结构性特点:它会根据问题类型"猜测"自己应该扮演什么角色——技术问题扮专家,生活问题扮朋友,创意问题扮发散思维的伙伴。这种角色漂移是LLM强大能力的副作用,但对于需要可预测行为的Agent,这是致命的。SOUL.md放在系统提示词最高优先级,目的只有一个:无论语境如何变化,锁定角色,防止漂移。
SOUL.md 回答"这个Agent是什么样的存在":
"我是专注安全的系统工程师,不确定时保守行事。"
→ 价值观与信念,不被用户请求覆盖,是底层操作系统
AGENTS.md 回答"这个Agent怎么工作":
"收到部署请求:检查覆盖率 → 确认环境变量
→ 发确认消息 → 等待批准 → 执行部署"
→ 决策流程与操作规范,可根据场景调整人格决定"怎么想",规则决定"怎么做"。两者分离,才能分别优化。
USER.md 与 MEMORY.md:两种不同的"了解你"
这两个文件常被混淆,但描述的是完全不同的信息:
USER.md(你是什么样的人——静态画像)
──────────────────────────────────
技术水平:中级开发者
偏好:简洁直接,不要废话
语言:中文优先
MEMORY.md(我们经历过什么——动态积累)
──────────────────────────────────────
2026-03-10:确认用pnpm,不是npm
2026-03-12:部署前必须先跑db:migrate
凤凰项目 = 客户X的电商重构项目USER.md 是相对稳定的用户画像;MEMORY.md 是随使用不断积累的经历。混淆两者会导致 USER.md 越来越长、越来越难维护。
USER.md 不是纯静态的。当用户在对话中说"用中文回答",Agent 完成任务后,会主动把"语言偏好:中文"写入 USER.md——这个偏好从此持久保存,下次对话无需再次提醒。这种机制让用户画像随实际使用自动完善。
TOOLS.md 是环境备忘录——服务器地址、项目路径、凭证位置。它不控制"哪些工具可用",而是告诉Agent"我在哪里工作",把那些"不可能每次口头告知"的环境信息固化下来。
比如:你让 Agent "帮我部署到测试服务器"。Agent 有部署能力,但不知道测试服务器的 IP、用户名、密钥在哪。TOOLS.md 把这些环境信息固化,Agent 不需要每次被告知,直接从"记忆"里检索出来用。
MEMORY.md 随使用不断积累。它的写入策略是"静默刷新为主,主动指令为辅":当对话变长、系统需要压缩上下文时,Agent 会在后台自动把重要信息写入 MEMORY.md——这个过程是静默的,不会打断你的工作流。你也可以随时直接告诉 Agent"记住这件事",它会立即完成写入。
HEARTBEAT.md 定义定期检查清单。大多数Agent是被动的,HEARTBEAT.md 让它从"问答机器"进化为"主动协作者"。
BOOTSTRAP.md 仅在工作区创建后首次加载,完成引导后归档——初始化逻辑不应永远留在系统中。
三、系统如何运转
本节解答:配置文件如何被读取、组装,以及三个关键机制。
优先级层叠
每次你发出消息,Agent推理之前,系统重新读取所有配置文件,动态组装系统提示词:
系统提示词(从上到下,优先级递减):
┌──────────────────────────────────┐
│ 工具定义(可用工具列表) │ ← 始终最前,安全边界不可被覆盖
│ 安全护栏 │
│ 技能列表(名称+描述+路径,非全文) │ ← 索引,按需加载
│ 工作目录信息 │
│ 八份配置文件内容 │ ← SOUL / USER / AGENTS / TOOLS / ...
│ 沙箱限制(如启用) │
│ 当前时间 │ ← 始终最后,最低优先级
└──────────────────────────────────┘越靠前的内容越难被后面的内容覆盖。这个顺序也是一条调试思路:行为出现预期外的结果时,沿着优先级链从上往下排查——比面对一段混合文本无从下手强得多。
每个配置文件有大小上限(bootstrapMaxChars 默认 20,000 字符),超出部分从尾部截断。这意味着一条写配置的铁律:把最重要的内容写在文件开头。
热更新
修改文件,保存,发下一条消息——新配置立刻生效。没有重启,没有部署,没有等待。
比如,你把 SOUL.md 里 Agent 的名字从"Alex"改成"Jordan",发出下一条消息,它已经是 Jordan 了。不需要重启,不需要重新部署——这就是热更新对人格配置的意义:修改即生效。
这靠的是文件指纹比对:
首次加载:
读取文件内容 → 记录指纹(路径+大小+修改时间)→ 存入缓存
后续每次对话前:
快速比对新旧指纹
├── 指纹相同 ──→ 直接用缓存(零额外开销)
└── 指纹变了 ──→ 重新读文件,新配置立即生效文件未变时几乎零开销,文件变化时立即感知。更深的价值是:热更新把Agent调教从"改→部署→测试→改"的瀑布循环,变成"改→看效果→改"的实时反馈循环。
Token预算与技能懒加载
技能文件(skills/*.md)不会全文注入,只注入一行索引:
.agents/
├── skills/
│ ├── deploy-app/
│ │ └── SKILL.md
│ ├── run-tests/
│ │ └── SKILL.md
│ └── code-review/
│ └── SKILL.md系统提示词(索引部分):
deploy-app: 将应用部署到目标环境 [path: skills/deploy-app.md]
run-tests: 执行测试并生成报告 [path: skills/run-tests.md]
│ Agent判断需要某个技能时
↓
主动用read工具读取技能全文(按需)基础提示词保持精简,同时支持数十个技能共存而不撑爆上下文。无论你有5个技能还是50个,索引部分大小几乎不变。
四、Markdown:最低成本的工程化桥梁
本节解答:为什么是Markdown,而不是JSON、YAML或代码。
选择Markdown不是偶然的,它同时满足了三个角色的需求:
| 角色 | 需求 | Markdown的优势 |
|---|---|---|
| 人类编写者 | 直观可读,低门槛编辑 | 所见即所得,无需学习配置语法 |
| Git版本控制 | 文本文件,可差异比较 | 提示词第一次有了提交历史 |
| LLM读取者 | 训练数据的主要格式 | 模型对Markdown结构天然理解 |
用JSON写配置,人类阅读成本高;用代码写,门槛更高,还引入了逻辑执行的风险。Markdown是三者都能接受的最低公分母——人类可以直接编辑,Git可以追踪变更,LLM可以准确理解。
这也意味着Agent配置第一次有了可追溯的历史。用Git提交SOUL.md的修改时附上说明,三个月后你能知道当初为什么做了这个改变。这在"提示词即临时文字"的时代是完全不可能的。
写好配置文件有一条核心原则:具体优于抽象。
❌ 模糊:"请你谨慎行事"
→ "谨慎"的解释权交给了模型,行为不可预测
✅ 具体:"执行任何删除操作前,先列出受影响的文件路径,
等我用'确认'回复后再执行"
→ 定义了可观测的行为,结果可预测好的配置不是写给人看的文档,而是让模型在任何给定情况下都没有歧义地知道该做什么。
小结
| 核心能力 | 实现方式 |
|---|---|
| 持久人格 | 8个Markdown文件独立于对话存在 |
| 职责清晰 | 每文件单一职责,行为异常时可定位 |
| 优先级可控 | 系统提示词组装顺序固定,SOUL在最前 |
| 即时生效 | 文件指纹缓存,修改后下一条消息立即反映 |
| 上下文精准 | 截断从尾部,技能按需加载,不粗放全量 |
| 可版本控制 | Markdown + Git,提示词第一次有了历史 |
Agent的成长从此是可积累的资产,而不是每次对话结束后归零的临时状态。你既是用户,也是培养者——每一次配置迭代,都是从隐性知识到显性工程的一步提炼。
→ 第四章 工具系统