# Prompt 撰写规范

## 核心原则

Prompt 是写给 LLM 的行为指令，不是写给人看的系统文档。判断标准：**这句话删掉后，LLM 的行为会变差吗？** 不会就删。

---

## 一、角色定位

### 描述能力，不要给标签

LLM 不需要知道自己"叫什么"，需要知道**怎么行动**。好的角色定位激活训练数据中的行为模式。

| 差 | 好 | 原因 |
|---|---|---|
| 你是 Librarian Agent | 你是一个知识库管理员，擅长从碎片信息中识别关联、去重和结构化整理 | 标签不激活行为；能力描述激活 |
| 你是后端服务 X | （删掉） | 架构角色对行为无帮助 |

### 角色三要素

1. **我擅长什么？** — 激活能力（"擅长从碎片信息中提炼结构"）
2. **我的核心任务是什么？** — 聚焦目标（"确保新信息与已有知识正确关联"）
3. **我的行为边界是什么？** — 防止漂移（"只整理和检索，不自行创造内容"）

---

## 二、实现细节：不写

LLM 不需要知道自己通过什么协议被调用、运行在什么框架上、调用方是谁、自己的代号。这些只消耗 token。

唯一例外：实现细节**影响行为**时。比如"你的回复会被程序解析为 JSON"——这不是架构说明，是输出约束。

---

## 三、信息分层

### 静态 vs 动态

把**不变的基础指令**和**随上下文变化的信息**分开。不变的放 system prompt 缓存；变化的按需注入。

参考 Claude Code 的做法：~25 个静态段落 + 若干条件段落（通过 feature flag 控制）。用户不需要某能力时，相关段落不注入。

### 三层结构

1. **角色和目标** — 做什么、怎么做的总纲
2. **知识** — 完成任务所需的背景信息（schema、字段含义、关联关系）
3. **操作策略** — 遇到 X 做 Y 的判断标准和输出格式

**知识和策略必须分开。** 混在一起会导致 LLM 在需要行动时回顾 schema、在理解数据时翻操作步骤。

### 按职责域分组，不按任务顺序

把相关信息放在一起（所有检索工具在一节、所有写入工具在一节），不要按"先检索再判断再写入"的执行顺序排列。LLM 需要的是参考手册，不是 step-by-step 教程。

---

## 四、约束表达

### 分层约束

从绝对到灵活，分三层：

1. **硬边界** — 绝对不可逾越："不要直接入库，只写草稿"
2. **条件规则** — 特定情况下的约束："新建 Capability 需同时满足三个条件"
3. **启发式** — 偏好和倾向："优先复用已有实体"

### 正面描述优于负面清单

"不要做X，不要做Y，不要做Z"太多时适得其反。改为正面描述期望行为。但**硬边界**用负面表述更安全（"绝对不要..."）。

### 预防合理化漂移

对关键约束，预判 LLM 会找什么借口绕过，然后提前堵住：

```
# 差：
不要跳过去重检查。

# 好：
收到新工具时必须先 tool_search 检查。不要因为"看起来是新的"就跳过检索——
名称不同但功能相同的工具很常见。
```

参考 Claude Code 的 verification agent：直接列出 LLM 会用的借口（"代码看起来是对的""测试已经通过了"），然后逐一反驳。

---

## 五、操作策略

### 写判断标准，不写流程

LLM 擅长在判断标准下自行组织行动。给决策规则，不给流程图：

```
# 差：
步骤1：检索。步骤2：判断。步骤3：写入。

# 好：
收到新工具时：已有→复用ID；全新→放入草稿。
新建 Capability 的条件：①有已验证工具 ②有真实用例 ③描述具体可操作
```

### 用例子代替抽象规则

一个好例子胜过三段解释：

```
# 差：
能力描述应该具体可操作，不要过于宽泛。

# 好：
能力描述要具体：不要写"图像处理"，要写"使用 ControlNet 进行人物姿态控制"。
```

### 提供逃生通道

告诉 LLM "不能做X"时，同时告诉它"改做Y"。否则 LLM 会自己发明绕过方案：

```
# 差：
不能直接入库。

# 好：
不能直接入库。写入 .cache/.knowledge/pre_upload_list.json 草稿池，等待人工确认后入库。
```

---

## 六、输出格式

### 只在必要时约束格式

程序解析的输出（JSON）→ 严格约束格式。人看的输出 → 不要过度约束，让 LLM 自然组织。

### 格式模板放在策略末尾

不要开头就给模板。LLM 会过早锁定结构而忽略内容质量。先描述任务和判断标准，最后给格式。

### 结构化输出模板

对复杂输出，提供带占位符的模板。这防止 LLM 臆造输出、方便程序解析、强制 LLM 真正执行而非编造结果：

```
### Check: [what you're verifying]
**Command:** [exact command]
**Output:** [actual output]
**Result: PASS / FAIL**
```

---

## 七、Token 效率

### 选择性详略

- **详写**：歧义代价高的地方（安全约束、关键判断标准）
- **略写**：意图明确的地方（工具简介、通用行为）
- **用表格**：多个相似项有多个属性时，表格比段落高效得多

### 条件注入

不是所有 Agent 都需要所有指令。用条件段落（类似 feature flag）控制注入，保持基础 prompt 精练：

```
# 只在需要入库能力时注入
commit_to_database 工具：将草稿提交入库...
```

### 上下文窗口意识

明确告诉 LLM 上下文会被管理（压缩、截断）。让它主动保存关键信息：

> 工具调用的结果可能在后续被清理。如果结果中有你后面需要用到的信息，在回复中记录下来。

---

## 八、常见反模式

| 反模式 | 问题 | 修正 |
|---|---|---|
| "你是 XX Agent" | 标签无行为激活效果 | 描述具体能力和行为特征 |
| 实现细节（协议、框架、架构） | 噪音 | 删掉，除非影响行为 |
| "请注意""重要""务必"满天飞 | 反复强调降低所有内容的权重 | 只强调一两个真正关键的点 |
| 详尽 step-by-step 流程 | 机械跟随而非灵活判断 | 给判断标准和决策规则 |
| 长负面清单 | 适得其反 | 正面描述期望行为 |
| 所有信息塞 system prompt | 注意力稀释 | 分层：始终需要的（system）+ 按需加载的（skill） |
| 开头就给输出模板 | 过早锁定结构 | 先给任务和标准，最后给格式 |
| "不能做X"但不给替代方案 | LLM 自行发明绕过方式 | 同时说明"改做Y" |
