diff --git a/docs/guides/prompt-library-design.md b/docs/guides/prompt-library-design.md new file mode 100644 index 0000000..427fb1e --- /dev/null +++ b/docs/guides/prompt-library-design.md @@ -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/-.md`,frontmatter + 正文: + +``` +--- +id: task.doc-minutes # .,与文件名一致 +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-.md`(对照八法检查;定触发词与优先级; + 文档类加附件门槛;提供 `/` 命令别名)。 +2. 若需新占位符:EnvData 加字段 + resolvePlaceholders 加映射。 +3. 测试:prompts_test.go 加触发用例(命中/未命中/门槛/让位); + TestDefaultLibraryParses 自动覆盖格式合法性。 +4. 观测验证:真实 run 的上下文构成面板确认 `prompt(task.xxx · 命中原因)`。 +5. 若是程序消费的裁决类输出:消费端同步解析逻辑 + 固定格式测试。 + +## 8. 反模式(不要这样做) + +- ❌ 把技能指令写进 base 或画像 systemPrompt(永久占上下文、不可触发观测)。 +- ❌ 提示词内联在 Go 代码里(不可评审、不可覆盖、发版才能改)。 +- ❌ 无 version 的文案变更(用户副本漂移不可知)。 +- ❌ 触发词太泛("文件"、"帮我")造成误触发。 +- ❌ 只有正面要求没有反模式禁令与缺失表述规则(模型会用默认行为填空)。