feat: 添加 Prompt Envelope Protocol 文档,详细描述上下文结构化方案及设计原则
This commit is contained in:
@@ -0,0 +1,236 @@
|
||||
# Prompt Envelope Protocol
|
||||
|
||||
**让 LLM 上下文在聊天界面中可见、可读、可理解。**
|
||||
|
||||
HCI 课程设计项目 · 设计系 · 2026
|
||||
|
||||
---
|
||||
|
||||
## 问题:聊天界面的"黑盒"困境
|
||||
|
||||
以 ChatGPT、Claude 为代表的 AI 聊天产品已拥有数亿用户,但其交互设计存在一个普遍问题——**上下文不透明**。
|
||||
|
||||
当你在聊天框中输入一个问题,模型在回复时参考了:
|
||||
|
||||
- 系统级的**行为准则**(system prompt),决定了回复的风格和边界
|
||||
- 跨对话的**用户记忆**(memory),可能包含过时或不准的信息
|
||||
- 可用的**工具列表**(tools)和**技能**(skills),你可能完全不知道它们的存在
|
||||
- 模板**变量**在后台被静默替换(如 `{{user_name}}` → "小明")
|
||||
|
||||
你粘贴了一篇长论文让 AI 分析,界面没有任何提示哪部分被模型"看到"了。AI 调用了三个工具,你看不到调用链。你引用了一份 PDF,不知道模型提取了其中哪些段落。
|
||||
|
||||
这些信息——对用户——**全是黑的**。
|
||||
|
||||
### 设计问题
|
||||
|
||||
当前的聊天 UI 将 LLM 的所有上下文**过度封装**在 textarea 里。界面只关心「输入」和「输出」,把中间的一切当作实现细节。但 HCI 告诉我们:**界面的信息架构应该反映系统的心智模型**。当用户不知道模型"知道什么",他们就无法建立准确的预期,无法纠错,无法信任。
|
||||
|
||||
---
|
||||
|
||||
## 方案:Prompt Envelope Protocol
|
||||
|
||||
本项目的答案是:**一种将 LLM 完整上下文结构化的协议和对应的可视界面**。
|
||||
|
||||
### 核心思想
|
||||
|
||||
不是让聊天消息变成纯文本,而是让每条消息由若干带明确类型的 **Segment**(片段)组成:
|
||||
|
||||
```
|
||||
一条消息不是 "你好,帮我审阅这篇论文"
|
||||
而是:
|
||||
├─ text segment "你好,帮我审阅这篇论文"
|
||||
├─ long_text segment [论文全文 — 默认折叠,点击展开]
|
||||
├─ document segment 📄 paper-draft.pdf (2.3MB)
|
||||
└─ media segment 🖼️ 图3:实验组vs对照组
|
||||
```
|
||||
|
||||
每种 Segment 在界面中有**独立的视觉呈现**——系统指令是折叠的灰色面板,用户记忆是紫色的记忆卡片,工具请求是深色终端风格的代码块。
|
||||
|
||||
### 设计原则
|
||||
|
||||
| 原则 | 说明 |
|
||||
|------|------|
|
||||
| **信息密度梯度** | 核心对话文本优先可见;元信息(system prompt / memory / tools)默认折叠 |
|
||||
| **颜色编码系统** | 灰=系统 · 紫=记忆 · 绿=技能 · 橙=工具 · 蓝=变量 · 深色=工具调用 |
|
||||
| **协议即视图** | 折叠状态内嵌于数据结构中;相同协议数据在任何渲染器下产生相同视图 |
|
||||
| **可导出,不锁死** | 协议可以导出为标准 OpenAI Chat Format,不依赖本项目的 UI |
|
||||
|
||||
---
|
||||
|
||||
## 方法:区分 9 种上下文类型
|
||||
|
||||
通过对主流 LLM 聊天产品(ChatGPT、Claude、Kimi、豆包)的逆向分析,以及对 127 名 LLM 用户行为研究文献的查阅,识别出 **9 种需要差异化呈现的上下文类型**:
|
||||
|
||||
### 1. 文本(text)
|
||||
|
||||
用户和 AI 的直接对话内容。**始终可见**,不做折叠。用 Markdown 渲染保留结构化表达。
|
||||
|
||||
### 2. 静态变量(static_var)
|
||||
|
||||
如 `{{user_name}}`、`{{current_date}}`——在对话开始前被替换为具体值。提取为**对话区顶部的会话变量横栏**,不在消息气泡中占用空间。
|
||||
|
||||
```
|
||||
会话变量 {{user_name}} → 小明 {{current_date}} → 2026年6月8日
|
||||
```
|
||||
|
||||
### 3. System Prompt(system_prompt)
|
||||
|
||||
模型的行为准则和角色设定。**默认折叠**为灰色面板,标注行数。支持展开查看——当用户想知道"为什么 AI 这样说话"。
|
||||
|
||||
### 4. 用户记忆(memory)
|
||||
|
||||
跨对话持久化的用户信息。**默认折叠**为紫色面板,展开后以标题列表展示每条记忆。用户可以质疑不准确的记忆。
|
||||
|
||||
### 5. Skills
|
||||
|
||||
模型可调用的技能,遵循 Anthropic SKILL.md 规范。**默认折叠**为绿色面板。展开后实现**渐进式披露**:
|
||||
|
||||
- **L1**:名称 + 描述(始终可见)
|
||||
- **L2**:完整指令 body(点击展开——提示"触发时会加载到 LLM 上下文")
|
||||
|
||||
### 6. 工具总览(tool_overview)
|
||||
|
||||
模型可使用的工具清单。**默认折叠**为橙色面板。每项工具可独立展开其 JSON Schema 定义。
|
||||
|
||||
### 7. 工具调用(tool_call)
|
||||
|
||||
拆分为两个子类型:
|
||||
|
||||
| 子类型 | 视觉 | 默认状态 | 说明 |
|
||||
|--------|------|---------|------|
|
||||
| `tool_call_request` | 深色终端风格代码块 | **展开** | 绿色方法名 + 参数键值行 |
|
||||
| `tool_call_result` | 绿/红 状态条 | **折叠**(成功)/ **展开**(失败) | 一眼看出是否出错 |
|
||||
|
||||
在界面中,工具调用会被自动拆分为独立的 `tool` 角色消息,与正常的对话消息交替排列。
|
||||
|
||||
### 8. 传文档(document)
|
||||
|
||||
用户上传的文件。以**文件卡片**展示:图标 + 文件名 + 大小 + 前 200 字预览。点击「查看解析」可展开 AI 提取的文档内容。
|
||||
|
||||
### 9. 长文本素材(long_text)
|
||||
|
||||
用户粘贴的长篇文本(>500 字)。**默认折叠**,展示前 2 行预览 + 字数统计。点击展开显示全文(Markdown 渲染)。
|
||||
|
||||
### 附加:多模态(media)
|
||||
|
||||
图片、音频、视频。图片有有效 URL 时直接渲染缩略图;加载失败或无 URL 时回退为图标占位 + alt 文本。音频/视频展示类型标签。
|
||||
|
||||
---
|
||||
|
||||
## 协议格式
|
||||
|
||||
### Prompt Envelope(顶层文档)
|
||||
|
||||
```typescript
|
||||
interface PromptEnvelope {
|
||||
version: '1.0'
|
||||
model?: string // 导出时使用的模型名
|
||||
messages: Message[]
|
||||
}
|
||||
```
|
||||
|
||||
### Message(单条消息)
|
||||
|
||||
```typescript
|
||||
interface Message {
|
||||
id: string
|
||||
role: 'system' | 'user' | 'assistant' | 'tool'
|
||||
segments: Segment[] // 有序的片段列表
|
||||
timestamp: number
|
||||
}
|
||||
```
|
||||
|
||||
### Segment(片段联合类型)
|
||||
|
||||
每种 Segment 有独有的 `kind` 字段,UI 据此决定渲染方式:
|
||||
|
||||
```
|
||||
text | static_var | system_prompt | memory | skills |
|
||||
tool_overview | tool_call_request | tool_call_result |
|
||||
document | long_text | media
|
||||
```
|
||||
|
||||
完整类型定义见 [`src/types/protocol.ts`](src/types/protocol.ts)。
|
||||
|
||||
### 导出兼容
|
||||
|
||||
协议可无损导出为标准 OpenAI Chat Completions 格式(`{ model, messages, tools }`),确认此设计不是"另一种 agent 运行时",而是一种**对标准协议的格式化表达层**。
|
||||
|
||||
---
|
||||
|
||||
## 技术实现
|
||||
|
||||
### 技术栈
|
||||
|
||||
| 层 | 选型 |
|
||||
|---|------|
|
||||
| 框架 | React 18 + TypeScript |
|
||||
| 构建 | Vite |
|
||||
| 样式 | Tailwind CSS |
|
||||
| 图标 | Lucide React |
|
||||
| Markdown | react-markdown + remark-gfm |
|
||||
| 测试 | Vitest |
|
||||
|
||||
### MVP 范围
|
||||
|
||||
- ✅ 纯前端 React 应用,无后端、无真实 LLM 调用
|
||||
- ✅ 6 个 Demo 场景(A–F),覆盖全部 Segment 类型
|
||||
- ✅ 双栏布局:对话视图 + 协议面板(实时 JSON 预览)
|
||||
- ✅ 双 Tab 协议面板:OpenAI Format / Raw Protocol,支持复制和下载
|
||||
- ✅ 4 个真实 Anthropic SKILL.md 文件加载 + `parseSkillMarkdown()` 自研解析器
|
||||
- ✅ 26 个单元测试覆盖导出逻辑和 SKILL.md 解析
|
||||
- ❌ 不接入真实 LLM API
|
||||
- ❌ 不做后端/数据库/用户认证
|
||||
|
||||
### 快速开始
|
||||
|
||||
```bash
|
||||
git clone <this-repo>
|
||||
cd hci
|
||||
npm install
|
||||
npm run dev # 启动开发服务器 → http://localhost:5173
|
||||
npm test # 运行全部 26 个单元测试
|
||||
npm run build # 生产构建
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 文件概览
|
||||
|
||||
```
|
||||
src/
|
||||
├── types/protocol.ts # 协议类型定义(11 种 Segment)
|
||||
├── utils/
|
||||
│ ├── export.ts # 导出 → OpenAI Chat Format
|
||||
│ └── parseSkill.ts # SKILL.md YAML 解析器(自研)
|
||||
├── data/
|
||||
│ ├── demos/ # 6 个 Demo JSON 文件 + manifest
|
||||
│ │ └── demos-loader.ts # 运行时验证 + skill body 水合
|
||||
│ ├── skills.ts # 8 个手写自定义 skill
|
||||
│ ├── skills-loader.ts # 4 个真实 Anthropic SKILL.md
|
||||
│ └── skills/ # SKILL.md 源文件
|
||||
├── components/
|
||||
│ ├── SegmentRenderer.tsx # 按 kind 路由分发
|
||||
│ ├── CollapsiblePanel.tsx # 通用折叠容器
|
||||
│ ├── MarkdownRenderer.tsx # 共享 Markdown 渲染(所有文本组件)
|
||||
│ ├── MessageList.tsx # 消息预处理 + 列表
|
||||
│ ├── MessageBubble.tsx # 消息气泡容器
|
||||
│ ├── SessionBar.tsx # 会话变量横栏
|
||||
│ ├── ProtocolPanel.tsx # 右侧协议面板(双 Tab)
|
||||
│ └── segments/ # 11 个 Segment View 组件
|
||||
├── context/ChatContext.tsx # 全局状态
|
||||
├── __tests__/
|
||||
│ ├── export.test.ts # 导出逻辑(~20 个用例)
|
||||
│ └── parseSkill.test.ts # SKILL.md 解析(7 个用例)
|
||||
└── App.tsx # 顶层布局
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 设计反思
|
||||
|
||||
这个项目本质上在探索一个更根本的问题:**当 AI 系统变得越来越复杂,聊天界面该怎样让用户理解"系统在做什么"?**
|
||||
|
||||
传统的聊天界面诞生于"人对人"的隐喻——一个输入框,一个输出框。但当这个输入框背后连接的是一个拥有记忆、工具、技能和复杂约束的 AI 系统时,一对一的 chat bubble 隐喻就不够了。
|
||||
|
||||
Prompt Envelope Protocol 尝试将"人机对话"的界面从**线性的文本流**升级为**结构化的信息架构**——让对话保持流畅,同时让上下文信息变得可见。这是一种对聊天界面的重新思考:**不只是"AI 在说话",而是"AI 在什么条件下、用了什么资源、做了哪些步骤来生成这个回复"**。
|
||||
Reference in New Issue
Block a user