diff --git a/docs/protocol-spec.md b/docs/protocol-spec.md new file mode 100644 index 0000000..9f49a9d --- /dev/null +++ b/docs/protocol-spec.md @@ -0,0 +1,591 @@ +# Prompt Envelope Protocol 设计文档 + +> **版本**:1.0 +> **更新日期**:2026 年 6 月 8 日 + +--- + +## 1. 概述 + +**Prompt Envelope Protocol** 是一套让 LLM 上下文在聊天界面中可见化的协议与 UI 系统。 + +传统聊天应用中,system prompt、memory、tools、skills、文档等上下文对用户是**不可见**的——它们被框架悄悄拼接到 prompt 中,用户无法知晓模型"看到了什么"。Prompt Envelope 将每条聊天消息拆解为若干带类型的 **Segment**,每种 Segment 有独立的视觉呈现,让隐藏的上下文成为可见的一等元素。 + +### 核心理念 + +``` +传统模式: Prompt Envelope: +┌─────────────┐ ┌──────────────────────┐ +│ 原始文本 │ │ Message │ +│ (用户不可见 │ │ ├─ 🔵 变量 badge │ +│ 的上下文) │ │ ├─ 📋 System Prompt │ +└─────────────┘ │ ├─ 🧠 Memory │ + │ ├─ 🛠️ Tools │ + │ ├─ ⚡ Skills │ + │ └─ 💬 Text │ + └──────────────────────┘ +``` + +### 适用场景 + +- 调试 LLM 行为——理解模型为什么给出某个回复 +- 教育——展示 LLM 上下文的组成结构 +- HCI 研究——探索上下文透明性对用户体验的影响 +- 协议标准化——跨平台、跨模型的统一上下文表示 + +--- + +## 2. 数据模型 + +协议采用三层结构:**Envelope → Message → Segment**。 + +``` +PromptEnvelope ← 顶层信封 +├─ version: "1.0" ← 协议版本 +├─ model?: string ← 模型名称 +└─ messages: Message[] ← 消息列表 + ├─ Message ← 单条消息 + │ ├─ id: string ← 唯一标识 + │ ├─ role: Role ← system | user | assistant | tool + │ ├─ segments: Segment[] ← Segment 列表 + │ └─ timestamp: number ← Unix epoch 毫秒 + └─ ... +``` + +### 2.1 PromptEnvelope(顶层信封) + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `version` | `"1.0"` | ✓ | 协议版本号 | +| `model` | `string` | | 模型名称,如 `gpt-4-turbo`、`claude-opus-4-8` | +| `messages` | `Message[]` | ✓ | 消息列表,至少 1 条 | + +### 2.2 Message(消息) + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `id` | `string` | ✓ | 消息唯一标识(如 `a-1`、`b-3`) | +| `role` | `"system" \| "user" \| "assistant" \| "tool"` | ✓ | 消息角色 | +| `segments` | `Segment[]` | ✓ | Segment 列表,至少 1 个 | +| `timestamp` | `number` | ✓ | Unix epoch 毫秒时间戳 | + +### 2.3 Segment(段落) + +Segment 是基于 `kind` 字段的**可辨识联合类型**,共 11 种。每个 Segment 对应 LLM 上下文中的一类信息,在 UI 中有独立的视觉呈现。 + +| kind | 含义 | 视觉组件 | 颜色标识 | +|------|------|---------|---------| +| `text` | 普通文本消息 | `MarkdownRenderer` | — | +| `static_var` | 会话级静态变量 | `StaticVarBadge` | 蓝色 | +| `system_prompt` | System Prompt 内容 | `SystemPromptView` | 灰色 | +| `memory` | 长期记忆条目 | `MemoryView` | 紫色 | +| `skills` | 可用 Skills 列表 | `SkillsView` | 绿色 | +| `tool_overview` | 工具声明(JSON Schema) | `ToolOverviewView` | 橙色 | +| `tool_call_request` | 工具调用请求 | `ToolCallRequestView` | 深色终端 | +| `tool_call_result` | 工具调用结果 | `ToolCallResultView` | 绿/红 | +| `document` | 上传的文档 | `DocumentCard` | — | +| `long_text` | 长文本片段 | `LongTextView` | — | +| `media` | 图片/音频/视频 | `MediaView` | — | + +--- + +## 3. Segment 类型详细规范 + +### 3.1 TextSegment — 普通文本 + +最基本的文本消息,使用 Markdown 渲染。 + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `kind` | `"text"` | ✓ | | +| `content` | `string` | ✓ | Markdown 格式文本 | + +```json +{ "kind": "text", "content": "你好,我想讨论一下我的协议方案。" } +``` + +### 3.2 StaticVarSegment — 静态变量 + +会话级配置变量,在 system prompt 中以 `{{name}}` 模板占位符展开。变量本身在 UI 中以蓝色 pill 标签呈现,让用户看到模型"感知"到的配置。 + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `kind` | `"static_var"` | ✓ | | +| `name` | `string` | ✓ | 模板变量名,如 `current_date` | +| `value` | `string` | ✓ | 展开后的值,如 `2026年6月7日` | +| `description` | `string` | | 变量的用途说明 | + +```json +{ + "kind": "static_var", + "name": "current_date", + "value": "2026年6月7日", + "description": "当前对话日期,注入到 System Prompt 模板中" +} +``` + +**模板展开规则**:System prompt 中的 `{{current_date}}` 会被替换为 `2026年6月7日`。展开发生在导出阶段(`exportToOpenAIFormat`),UI 中同时显示原始模板和变量值。 + +### 3.3 SystemPromptSegment — System Prompt + +模型的系统指令。UI 中用灰色 CollapsiblePanel 包裹,默认折叠——体现其"后台配置"的语义。 + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `kind` | `"system_prompt"` | ✓ | | +| `content` | `string` | ✓ | System Prompt 全文,可含 `{{var}}` 模板 | +| `collapsed` | `boolean` | ✓ | 默认折叠状态 | + +```json +{ + "kind": "system_prompt", + "content": "当前日期:{{current_date}}\n回复语言:{{language}}\n\n你是 HCI 课程设计助手...", + "collapsed": true +} +``` + +### 3.4 MemorySegment — 记忆 + +模型的长期记忆,存储关于用户的持久化信息。UI 中用紫色 CollapsiblePanel 包裹。 + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `kind` | `"memory"` | ✓ | | +| `description` | `string` | | 简短解释 memory 的用途 | +| `items` | `MemoryItem[]` | ✓ | 记忆条目列表 | +| `collapsed` | `boolean` | ✓ | 默认折叠状态 | + +**MemoryItem**: + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `title` | `string` | ✓ | 记忆标题,如"用户身份" | +| `content` | `string` | ✓ | 记忆内容 | + +```json +{ + "kind": "memory", + "description": "以下是从过往对话中总结的关于你的信息...", + "items": [ + { "title": "用户背景", "content": "设计系研二学生,正在做 HCI 课程设计" } + ], + "collapsed": true +} +``` + +### 3.5 SkillsSegment — 技能 + +模型可调用的内置能力(slash commands)。遵循 Anthropic SKILL.md 规范的渐进式披露机制: + +- **L1**:`name` + `description` — 始终在上下文中可见 +- **L2**:`body` — skill 被触发时才加载的完整指令 + +UI 中用绿色 CollapsiblePanel 包裹。 + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `kind` | `"skills"` | ✓ | | +| `description` | `string` | | 解释 skills 是什么 | +| `items` | `SkillItem[]` | ✓ | Skill 列表 | +| `collapsed` | `boolean` | ✓ | 默认折叠 | + +**SkillItem**: + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `name` | `string` | ✓ | Skill 名称(L1) | +| `description` | `string` | ✓ | 一句话描述(L1) | +| `body` | `string` | | 完整指令 Markdown(L2,触发时注入) | + +> **注意**:JSON 协议文件中 skills segment 只包含 `name` + `description`(L1 层)。`body` 由运行时加载器从技能注册表补全,**不属于协议数据本身**。body 仅在 skill 被触发时由 agent 框架注入上下文。 + +```json +{ + "kind": "skills", + "description": "Skills 是模型可调用的内置能力...", + "items": [ + { "name": "deep-research", "description": "深度研究 — 多源搜索、交叉验证、生成引用报告" }, + { "name": "code-review", "description": "代码审查 — 发现正确性 bug 和简化/效率优化机会" } + ], + "collapsed": true +} +``` + +### 3.6 ToolOverviewSegment — 工具声明 + +声明模型可调用的工具列表及其 JSON Schema。UI 中用橙色 CollapsiblePanel 包裹,每个 Tool 可展开查看 Schema。 + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `kind` | `"tool_overview"` | ✓ | | +| `items` | `ToolItem[]` | ✓ | 工具列表 | +| `collapsed` | `boolean` | ✓ | | + +**ToolItem**: + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `name` | `string` | ✓ | 工具名称 | +| `description` | `string` | ✓ | 功能描述 | +| `parameters` | `string` | ✓ | 人类可读的参数摘要 | +| `schema` | `object` | | JSON Schema 对象 | + +```json +{ + "kind": "tool_overview", + "items": [ + { + "name": "search", + "description": "搜索学术文献和设计案例", + "parameters": "query: string, limit?: number", + "schema": { + "type": "object", + "properties": { + "query": { "type": "string", "description": "搜索关键词" }, + "limit": { "type": "number", "description": "返回结果数量上限" } + }, + "required": ["query"] + } + } + ], + "collapsed": true +} +``` + +### 3.7 ToolCallRequestSegment — 工具调用请求 + +模型发起工具调用的记录。UI 中以深色终端风格代码块呈现,参数以标签化键值行展示。 + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `kind` | `"tool_call_request"` | ✓ | | +| `toolName` | `string` | ✓ | 被调用的工具名称 | +| `arguments` | `object` | ✓ | 调用参数(键值对) | +| `collapsed` | `boolean` | ✓ | 默认展开(`false`) | + +```json +{ + "kind": "tool_call_request", + "toolName": "search", + "arguments": { "query": "LLM context transparency HCI", "limit": 5 }, + "collapsed": false +} +``` + +### 3.8 ToolCallResultSegment — 工具调用结果 + +工具调用的返回结果。UI 中成功时显示绿色状态条(默认折叠),失败时显示红色状态条(默认展开)。 + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `kind` | `"tool_call_result"` | ✓ | | +| `toolName` | `string` | ✓ | 工具名称 | +| `result` | `string` | ✓ | 返回结果文本 | +| `success` | `boolean` | ✓ | 调用是否成功 | +| `collapsed` | `boolean` | ✓ | 成功时 `true`,失败时 `false` | + +```json +{ + "kind": "tool_call_result", + "toolName": "search", + "success": true, + "result": "Found 5 results:\n\n1. \"Transparent AI...\" — CHI 2024...", + "collapsed": true +} +``` + +### 3.9 DocumentSegment — 文档 + +用户上传的文档。UI 中显示文件图标、文件名、大小、内容摘要。可点击「查看解析」展开 AI 对文档的结构化提取结果。 + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `kind` | `"document"` | ✓ | | +| `fileName` | `string` | ✓ | 文件名 | +| `mimeType` | `string` | ✓ | MIME 类型 | +| `snippet` | `string` | ✓ | 前 200 字符预览 | +| `sizeBytes` | `number` | ✓ | 文件大小(字节) | +| `parsedContent` | `string` | | AI 提取的结构化内容(Markdown) | + +```json +{ + "kind": "document", + "fileName": "2026-Q2-智能助手市场报告.pdf", + "mimeType": "application/pdf", + "sizeBytes": 2845000, + "snippet": "# 2026 年 Q2 智能助手市场研究报告\n\n## 摘要\n\n2026 年 Q2 全球智能助手市场规模预计达到 187 亿美元...", + "parsedContent": "## 文档概览\n\n| 字段 | 内容 |\n..." +} +``` + +### 3.10 LongTextSegment — 长文本 + +超长文本片段(如日志、研究论文全文),折叠态展示前 2 行预览 + 字符数。 + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `kind` | `"long_text"` | ✓ | | +| `content` | `string` | ✓ | 全文内容 | +| `charCount` | `number` | ✓ | 字符总数 | +| `collapsed` | `boolean` | ✓ | 默认 `true`(折叠) | + +```json +{ + "kind": "long_text", + "content": "192.168.1.10 - - [07/Jun/2026:10:15:23 +0800] \"GET /api/users HTTP/1.1\" 200 1234\n...", + "charCount": 2375, + "collapsed": true +} +``` + +### 3.11 MediaSegment — 多媒体 + +图片、音频或视频。UI 中显示类型图标 + 媒体类型标签 + alt 文本。 + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `kind` | `"media"` | ✓ | | +| `mediaType` | `"image" \| "audio" \| "video"` | ✓ | 媒体类型 | +| `url` | `string` | ✓ | 媒体文件 URL | +| `altText` | `string` | | 替代文本描述 | + +```json +{ + "kind": "media", + "mediaType": "image", + "url": "https://cataas.com/cat", + "altText": "用户上传的图片" +} +``` + +--- + +## 4. Skills 系统 + +Skills 遵循 Anthropic SKILL.md 规范的**渐进式披露**机制。 + +### 4.1 SKILL.md 格式 + +```markdown +--- +name: webapp-testing +description: Toolkit for testing local web applications using Playwright. +--- + +# Web Application Testing + +To test local web applications, write native Python Playwright scripts. +... +``` + +YAML frontmatter 提供 `name` + `description`,Markdown body 是完整指令正文。 + +### 4.2 层级模型 + +| 层级 | 内容 | 何时可见 | 上下文大小 | +|------|------|---------|-----------| +| L1 | `name` + `description` | 始终在上下文中 | ~100 词 | +| L2 | `body`(完整指令) | Skill 被触发时加载 | 建议 <500 行 | + +### 4.3 协议中的表示 + +JSON 协议文件的 skills segment **仅包含 L1 数据**(`name` + `description`)。Skill body 由运行时加载器从技能注册表(`skills.ts` / `skills-loader.ts`)按名称查询并补全。 + +**理由**:body 不属于 system prompt 范畴——它不会被立刻发送给模型。body 仅在 skill 被触发时由 agent 框架注入上下文,其展示也由框架逻辑控制。 + +### 4.4 两类 Skill 源 + +| 来源 | 文件 | 数量 | 说明 | +|------|------|------|------| +| 手写 | `src/data/skills.ts` | 8 个 | 自定义 skill(code-review、deep-research、verify 等) | +| SKILL.md 解析 | `src/data/skills-loader.ts` | 4 个 | 从真实 Anthropic SKILL.md 文件解析(webapp-testing、pdf、doc-coauthoring、mcp-builder) | + +--- + +## 5. 导出管线 + +### 5.1 OpenAI Chat Completions 格式映射 + +`exportToOpenAIFormat(envelope)` 将 PromptEnvelope 导出为 OpenAI 兼容的请求体。 + +``` +{ model, messages: OpenAIMessage[], tools?: OpenAITool[] } +``` + +| Protocol Segment | OpenAI 表示 | +|-----------------|------------| +| `text` | `message.content`(string) | +| `static_var` | 展开为变量值,出现在 content 中 | +| `system_prompt` | `system` role 消息的 content | +| `memory` | `system` role 消息的 content(格式化为 `- title: content`) | +| `skills` | `system` role 消息的 content(格式化为 `- /name: description`) | +| `tool_overview` | `system` 消息的 content + 顶层 `tools[]` 数组 | +| `tool_call_request` | assistant 消息,带 `tool_calls[]` | +| `tool_call_result` | `tool` role 消息,带 `tool_call_id` | +| `document` | `[Document: name (size)]\nsnippet` | +| `long_text` | content 原文 | +| `media` | 图片 → `image_url` content part;音频/视频 → altText 回退 | + +### 5.2 关键导出行为 + +**结构性 Segment 聚合**:system_prompt、memory、skills 等结构性 segment 被合并为一条 `role: "system"` 头部消息。 + +**静态变量模板展开**:system prompt 中的 `{{var}}` 占位符在导出时被替换为实际值。`static_var` 本身不写入 content。 + +**多模态消息**:当 user 消息包含 `media` segment(图片)时,`content` 输出为 `OpenAIContentPart[]` 数组: +```json +{ + "role": "user", + "content": [ + { "type": "text", "text": "这张图片是什么?" }, + { "type": "image_url", "image_url": { "url": "https://cataas.com/cat" } } + ] +} +``` + +纯文本消息保持 `content: string` 格式不变,向后兼容。 + +**工具调用配对**:`tool_call_request` 和 `tool_call_result` 通过 `tool_call_id` 配对,按 toolName 建立 FIFO 队列匹配。 + +--- + +## 6. JSON 协议文件格式 + +### 6.1 文件结构 + +``` +src/data/demos/ +├── manifest.json # 场景索引 +├── demo-a.json ~ demo-f.json # 6 个 Demo 场景 +├── prompt-envelope.schema.json # JSON Schema +├── demos.ts # 聚合入口 +└── demos-loader.ts # 加载器 +``` + +### 6.2 最小合法示例 + +```json +{ + "version": "1.0", + "model": "gpt-4-turbo", + "messages": [ + { + "id": "msg-1", + "role": "system", + "segments": [ + { + "kind": "system_prompt", + "content": "你是一个有用的助手。", + "collapsed": true + } + ], + "timestamp": 1780897800000 + }, + { + "id": "msg-2", + "role": "user", + "segments": [ + { "kind": "text", "content": "你好!" } + ], + "timestamp": 1780897900000 + }, + { + "id": "msg-3", + "role": "assistant", + "segments": [ + { "kind": "text", "content": "你好!有什么可以帮助你的吗?" } + ], + "timestamp": 1780898000000 + } + ] +} +``` + +### 6.3 设计约束 + +| 约束 | 说明 | +|------|------| +| 字段名 | camelCase,与 TypeScript 类型一致 | +| 时间戳 | Unix epoch 毫秒(绝对时间),不使用相对偏移 | +| 折叠默认值 | 由 `collapsed` 字段指定,协议数据作为初始值,UI 可运行时切换 | +| Skill body | 不入协议,由加载器按 name 从注册表补全 | + +### 6.4 JSON Schema + +`prompt-envelope.schema.json` 提供完整的 JSON Schema(Draft 2020-12)校验: + +- `version` 必须为 `"1.0"` +- `messages` 非空 +- `role` 仅限 `system` / `user` / `assistant` / `tool` +- `kind` 必须是 11 种之一 +- 每种 Segment 的必填字段约束 +- memory / skills / tool_overview 的 `items` 非空 + +VSCode 可通过 `$schema` 引用自动补全和实时校验。 + +--- + +## 7. 视觉设计规范 + +### 7.1 颜色系统 + +| 颜色 | HEX | 对应 Segment | 语义 | +|------|-----|-------------|------| +| 蓝色 | `#3B82F6` | `static_var` | 配置/变量 | +| 灰色 | `#6B7280` | `system_prompt` | 后台指令 | +| 紫色 | `#8B5CF6` | `memory` | 持久记忆 | +| 绿色 | `#10B981` | `skills` | 能力/技能 | +| 橙色 | `#F59E0B` | `tool_overview` | 工具/接口 | +| 深色 | `#1F2937` | `tool_call_request` | 代码/执行 | +| 绿色(成功) | `#22C55E` | `tool_call_result` | 成功 | +| 红色(失败) | `#EF4444` | `tool_call_result` | 失败 | + +### 7.2 折叠策略 + +| Segment | 默认状态 | 理由 | +|---------|---------|------| +| `system_prompt` | 折叠 | 后台配置,非主要阅读内容 | +| `memory` | 折叠 | 参考信息,按需查看 | +| `skills` | 折叠 | 工具列表,按需展开 | +| `tool_overview` | 折叠 | Schema 细节冗长 | +| `tool_call_request` | **展开** | 调用过程需要可见 | +| `tool_call_result`(成功) | 折叠 | 结果正常 | +| `tool_call_result`(失败) | **展开** | 错误信息需要立即关注 | +| `long_text` | 折叠 | 默认仅显示预览 | +| `text` | N/A | 始终可见 | + +### 7.3 布局 + +双栏布局: +- **左侧**:`ChatView` — 聊天气泡列表,每条消息渲染其 Segments +- **右侧**:`ProtocolPanel` — 双 tab(OpenAI Format / Raw Protocol),显示导出的 JSON,支持复制和下载 +- **顶栏**:Demo 场景切换按钮 + +--- + +## 8. Demo 场景 + +| 索引 | ID | 场景 | 内容 | +|------|----|------|------| +| 0 | a | 场景 A | 基础对话 + System Prompt + Memory | +| 1 | b | 场景 B | 工具调用:请求 → 执行(成功 & 失败) | +| 2 | c | 场景 C 📄 | 文档解析:点击「查看解析」看 AI 提取内容 | +| 3 | d | 场景 D ⭐ | 多模态对话:图片识别(猫) | +| 4 | f | 场景 F 📁 | 真实 Anthropic Skills | +| 5 | e | 场景 E 🔍 | 日志分析:异常检测 + 安全审计 + 性能分析 | + +默认激活场景 F(索引 4)。 + +--- + +## 9. 相关资源 + +| 资源 | 路径 | +|------|------| +| 类型定义 | `src/types/protocol.ts` | +| 导出逻辑 | `src/utils/export.ts` | +| JSON Schema | `src/data/demos/prompt-envelope.schema.json` | +| 加载器 | `src/data/demos/demos-loader.ts` | +| 场景数据 | `src/data/demos/demo-*.json` | +| Skills 注册表 | `src/data/skills.ts` / `src/data/skills-loader.ts` | +| 渲染组件 | `src/components/SegmentRenderer.tsx` |