Add the prompt library design and extension guide

Why: the prompt system's design rationale (layering, the eight module
patterns, trigger semantics, override chain) needs to live with the
docs so future prompt work follows it instead of re-deriving it.

Evidence: guide content distilled from the implemented library and the
Claude prompt catalog analysis recorded in the task card.

Impact: new docs/guides/prompt-library-design.md; no code change.

Refs: feature/prompt-library task card.
This commit is contained in:
2026-09-30 10:36:40 +00:00
parent ab14f62534
commit 02198f1ceb
+109
View File
@@ -0,0 +1,109 @@
# 提示词库设计与扩展指南
状态:active(feature/prompt-library 交付)|维护对象:`modules/backend/internal/prompts/`
本指南总结 Agent-System 提示词体系的**设计思路**,供后续新增/修改提示词时遵循。
方法来源:Claude Code 提示词体系的分层组装与技能化模式(2026-04 目录分析),
结合本系统的画像/设置/意图闸门/命令总线既有机制落地。
## 1. 分层模型:提示词不是一段话,是一组有职责的块
| 层 | 职责 | 组装时机 | 示例 |
|---|---|---|---|
| `base` | 常驻基座:身份/行为/谨慎/工具/风格 | 每次 run,画像可裁剪 | base.identity |
| `env` | 动态环境事实(占位符) | 每次 run,随运行填充 | env.runtime |
| `task` | 任务技能:有触发条件 | 命中才注入(同层取优先级最高) | task.doc-minutes |
| `agent` | 子代理/小队角色人设 | 派生 run 时取用 | agent.sub.explore |
| `tool` | 工具描述文案(模型侧) | 声明工具时覆盖注册表默认 | tool.knowledge_search |
| `aux` | 辅助模板(压缩/标题/解释) | 功能接线时取用(可先入库) | aux.session-compact |
| `style` | 表达变体 | 画像显式引用才启用 | style.explanatory |
设计动机:**技能塞基座 = 永久占用上下文 + 干扰无关任务**。分层后基座保持小而稳,
技能按需进场,风格可选叠加——上下文预算花在刀刃上。
## 2. 模块设计八法(写一个好模块的检查清单)
1. **角色定义**:第一句说清"你是谁、对什么负责"。子代理尤其要写边界
("你是规划者,不是实现者")。
2. **权限/只读约束**:凡不该做的事显式禁止(探索代理:不写入不修改)。
约束写在提示里 + 机制上配工具白名单,双层防线。
3. **输出契约**:结构化产出必须定义形态(几个部分、各含什么)。
契约同时是验收标准——人可以按契约检查交付。
4. **强制裁决格式**:程序要消费的结论给固定格式(验证代理以
`VERDICT: PASS|FAIL|PARTIAL` 结尾;标题生成只输出 JSON)。
5. **反模式禁令**:点名常见错误("不要把发言当决议"、"不要把外部知识冒充文档内容"、
"不要为简短丢信息")。禁令比正面要求更能纠正模型默认行为。
6. **失败与缺失的表述规则**:查不到/原文没有时怎么说("文档未提及"、列出已检索范围),
防止编造兜底。
7. **详略授权**:明确"默认完整、压缩需用户明示"还是相反——输出质量的直接杠杆。
8. **防污染**:过程性指令不得泄漏进产出(压缩摘要不提压缩这件事本身)。
## 3. 触发设计
- `intent`:关键词子串匹配。关键词要**任务特有**("纪要"好于"会议"),
避免日常闲聊误触发。文档类技能加 `requiresAttachments: true` 门槛。
- `command`:`/xxx` 显式命令。命令是显式用户意图,**不受附件门槛约束**。
技能命令出现在 `/` 菜单(source=prompt-skill),发送时跳过命令总线走正常 run。
- `attachment`:本轮有附件(可叠加关键词)。
- `manual`:永不自动触发,仅画像引用/程序显式调用。
- **多命中取舍**:task 层同轮多技能命中时注入优先级(priority,大者胜)最高者,
其余记录让位(可观测)。同优先级保持库 ID 序。
## 4. 文件格式与命名
库文件:`internal/prompts/library/<layer>-<name>.md`,frontmatter + 正文:
```
---
id: task.doc-minutes # <layer>.<name>,与文件名一致
layer: task
version: 1 # 文案有实质变更时 +1(触发用户副本 drift 提示)
title: 会议纪要生成
description: 一句话用途(/ 菜单与设置界面展示)
priority: 70
requiresAttachments: true
outputContract: |
多行输出契约
triggers:
- kind: intent
keywords: 纪要, 会议记录
- kind: command
command: /minutes
---
正文:给模型的指令(Markdown)。
```
frontmatter 刻意最小(无 YAML 依赖,解析器在 parse.go);正文即 `body`;
`{{date}} {{weekday}} {{model}} {{attachments}}` 占位符仅 env 层使用。
## 5. 覆盖链与版本
`builtin(embed 文件)→ user(DB prompt_modules 表)`。
用户副本记录 `basedOnVersion`;内置版本前进后副本标记 `drifted`(提示、不强制覆盖)。
删除用户副本即回到内置。改内置文案:改文件 + version+1 + 走 PR 评审。
## 6. 组装与可观测
`prompts.Service.ResolveSystem(profile, triggerCtx, env)` 产出多段 system 消息:
基座(画像 promptModules 引用或缺省 base+env)→ 命中技能 → 画像 systemPrompt 兼容段。
每次组装产出命中记录,注入 ctxasm Report("上下文构成"面板可见):
`prompt(task.doc-minutes v1 · intent:纪要)`、`skill-yield(task.summarize · superseded-by:...)`。
**改了提示词,观测里能看到它进没进场**——这是排查提示问题的第一入口。
## 7. 新增一个技能的步骤
1. 写 `library/task-<name>.md`(对照八法检查;定触发词与优先级;
文档类加附件门槛;提供 `/` 命令别名)。
2. 若需新占位符:EnvData 加字段 + resolvePlaceholders 加映射。
3. 测试:prompts_test.go 加触发用例(命中/未命中/门槛/让位);
TestDefaultLibraryParses 自动覆盖格式合法性。
4. 观测验证:真实 run 的上下文构成面板确认 `prompt(task.xxx · 命中原因)`。
5. 若是程序消费的裁决类输出:消费端同步解析逻辑 + 固定格式测试。
## 8. 反模式(不要这样做)
- ❌ 把技能指令写进 base 或画像 systemPrompt(永久占上下文、不可触发观测)。
- ❌ 提示词内联在 Go 代码里(不可评审、不可覆盖、发版才能改)。
- ❌ 无 version 的文案变更(用户副本漂移不可知)。
- ❌ 触发词太泛("文件"、"帮我")造成误触发。
- ❌ 只有正面要求没有反模式禁令与缺失表述规则(模型会用默认行为填空)。