Files
Prompt-Envelope-Protocol/docs/protocol-spec.md
T

592 lines
20 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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` | | 完整指令 MarkdownL2,触发时注入) |
> **注意**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 个 | 自定义 skillcode-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 SchemaDraft 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` — 双 tabOpenAI 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` |