134 lines
7.2 KiB
Markdown
134 lines
7.2 KiB
Markdown
# CLAUDE.md
|
||
|
||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||
|
||
**项目语言:中文。所有注释、文档、commit message、UI 文案均使用中文。**
|
||
|
||
## 项目概述
|
||
|
||
HCI 课程设计项目:**Prompt Envelope Protocol** — 一套让 LLM 上下文在聊天界面中可见的协议与 UI。
|
||
|
||
核心思想:每条聊天消息由若干带类型的 **Segment** 组成(而非原始文本)。每种 Segment 有独立的视觉呈现,让 system prompt、memory、tools、skills、变量、文档、多媒体成为可见的一等元素,而非隐藏的上下文。
|
||
|
||
MVP 为纯前端 React 应用,使用 mock 数据演示。无后端、无真实 LLM 调用。
|
||
|
||
## 命令
|
||
|
||
```bash
|
||
npm run dev # Vite 开发服务器 → http://localhost:5173
|
||
npm run build # tsc 类型检查 + vite 构建
|
||
npm test # vitest 运行全部测试(26 个,位于 export.test.ts 和 parseSkill.test.ts)
|
||
npm run preview # 预览生产构建
|
||
npx vitest run src/__tests__/export.test.ts # 运行单个测试文件
|
||
npx vitest run src/__tests__/parseSkill.test.ts
|
||
```
|
||
|
||
## 架构
|
||
|
||
### 数据模型 (`src/types/protocol.ts`)
|
||
|
||
`PromptEnvelope { version, model, messages: Message[] }` — 顶层协议文档。
|
||
|
||
`Message { id, role: "system"|"user"|"assistant"|"tool", segments: Segment[], timestamp }` — 单条聊天消息。
|
||
|
||
`Segment` 是基于 `kind` 的可辨识联合类型,共 11 种变体:`text`、`static_var`、`system_prompt`、`memory`、`skills`、`tool_overview`、`tool_call_request`、`tool_call_result`、`document`、`long_text`、`media`。
|
||
|
||
部分 Segment 类型(MemorySegment、SkillSegment)有可选 `description` 字段,用于在 UI 中解释这些项的用途。
|
||
|
||
ToolItem 有可选 `schema` 字段(JSON Schema 对象),在工具总览面板中可展开查看。
|
||
|
||
DocumentSegment 有可选 `parsedContent` 字段,点击「查看解析」可展开 AI 对文档内容的提取结果。
|
||
|
||
### Skills 系统
|
||
|
||
Skills 遵循 Anthropic SKILL.md 规范,实现渐进式披露:
|
||
|
||
```
|
||
SKILL.md 文件 (YAML frontmatter + Markdown body)
|
||
│
|
||
├─ parseSkillMarkdown() → ParsedSkill { name, description, body, ... }
|
||
│ (src/utils/parseSkill.ts) YAML 通过极简手写解析器提取(不依赖外部库)
|
||
│
|
||
├─ skills-loader.ts → PARSED_SKILLS (Record<string, ParsedSkill>)
|
||
│ (src/data/skills-loader.ts) 通过 Vite ?raw 导入 4 个真实 SKILL.md 文件
|
||
│
|
||
├─ skills.ts → ALL_SKILLS (Record<string, SkillItem>)
|
||
│ (src/data/skills.ts) 8 个内置自定义 skill,用于 Demo C/D/E
|
||
│
|
||
└─ UI: SkillsView → L1 名称+描述(始终可见),L2 body(点击展开)
|
||
```
|
||
|
||
**两类 skill 数据源:**
|
||
- `src/data/skills.ts` — 8 个手写 SkillItem(code-review、deep-research、verify 等),通过 `getSkills(names)` 按名称选取
|
||
- `src/data/skills-loader.ts` — 4 个真实 Anthropic SKILL.md 文件(webapp-testing、pdf、doc-coauthoring、mcp-builder),通过 `parseSkillMarkdown()` 解析,`getRealSkills(names)` 获取
|
||
|
||
**parseSkillMarkdown 测试:** 位于 `src/__tests__/parseSkill.test.ts`,覆盖 YAML 解析、body 提取、必填字段校验、可选字段、统计信息等 7 个用例。
|
||
|
||
### 渲染管线
|
||
|
||
```
|
||
SegmentRenderer (按 segment.kind 分发)
|
||
├─ TextSegmentView → MarkdownRenderer(react-markdown + GFM)
|
||
├─ StaticVarBadge → 蓝色内联 pill 标签
|
||
├─ SystemPromptView → CollapsiblePanel(灰色,默认折叠)
|
||
├─ MemoryView → CollapsiblePanel(紫色,默认折叠)
|
||
├─ SkillsView → CollapsiblePanel(绿色,默认折叠)
|
||
├─ ToolOverviewView → CollapsiblePanel(橙色,默认折叠,可展开 JSON Schema)
|
||
├─ ToolCallRequestView → 深色终端风格代码块,参数以标签化键值行展示
|
||
├─ ToolCallResultView → 绿色/红色状态条(失败时默认展开,成功时默认折叠)
|
||
├─ DocumentCard → 文件图标 + 文件名 + 大小 + 摘要预览
|
||
├─ LongTextView → 折叠态展示前2行预览 + 展开态用 MarkdownRenderer 渲染
|
||
└─ MediaView → 图标 + 类型标签 + alt 文本
|
||
```
|
||
|
||
`CollapsiblePanel` 是共享折叠容器组件。折叠/展开状态通过 `useState(segment.collapsed)` 管理——协议数据提供默认值,UI 控制运行时切换。
|
||
|
||
`MarkdownRenderer` 封装 `react-markdown` + `remark-gfm`。所有 HTML 元素(h1–h4、p、code、pre、table、blockquote 等)均有自定义 Tailwind 样式,针对聊天气泡内嵌场景做了紧凑化处理。
|
||
|
||
### 状态管理
|
||
|
||
`ChatContext`(`src/context/ChatContext.tsx`)持有当前 `envelope` 和 `activeDemo` 索引。切换 Demo 场景时替换整个 envelope。ChatInput 已禁用(MVP 无真实输入)。
|
||
|
||
### 导出管线 (`src/utils/export.ts`)
|
||
|
||
`exportToOpenAIFormat(envelope)` 输出 OpenAI 兼容 JSON,结构为 `{ model, messages, tools? }`:
|
||
|
||
- 结构性 Segment(`system_prompt`、`memory`、`skills`、`tool_overview`)提取为一条 `role: "system"` 的头部消息
|
||
- `tool_overview` 的 items 转为顶层 `tools` 数组(OpenAI function-calling 格式)
|
||
- `tool_call_request` → 带 `tool_calls` 数组的 assistant 消息;`tool_call_result` → `role: "tool"` 消息
|
||
- `static_var` 展开为变量值
|
||
- `text` 和 `long_text` 原文输出
|
||
- `media` 用 `altText` 作为回退文本
|
||
- `segmentToText()` 对结构性/tool Segment 返回 `null`——它们在消息级别统一处理
|
||
|
||
### Demo 数据 (`src/data/demos.ts` → `src/data/demos/`)
|
||
|
||
6 个场景(A–F),每个场景是一个完整的 `PromptEnvelope`,对话内容为中文。默认激活索引 4(场景 F——真实 Anthropic Skills 加载)。
|
||
|
||
| 索引 | 场景 | 内容 |
|
||
|------|--------|---------------------------------------------------|
|
||
| 0 | 场景 A | 基础对话 + System Prompt + Memory |
|
||
| 1 | 场景 B | 工具调用:请求 → 执行(成功 & 失败) |
|
||
| 2 | 场景 C | 文档解析:点击「查看解析」看 AI 如何提取文档内容 |
|
||
| 3 | 场景 D | 综合:覆盖全部 11 种 Segment |
|
||
| 4 | 场景 F | 真实 Anthropic Skills(SKILL.md 文件加载 + parseSkillMarkdown 解析) |
|
||
| 5 | 场景 E | 日志分析:异常检测 + 安全审计 + 性能分析 |
|
||
|
||
每个场景文件位于 `src/data/demos/demo-{a..f}.ts`,`demos.ts` 仅做聚合导出。
|
||
|
||
### 颜色系统
|
||
|
||
| 颜色 | 对应 Segment |
|
||
|--------|--------------------------------------|
|
||
| 蓝色 | `static_var` |
|
||
| 灰色 | `system_prompt` |
|
||
| 紫色 | `memory` |
|
||
| 绿色 | `skills` |
|
||
| 橙色 | `tool_overview` |
|
||
| 深色 | `tool_call_request`(代码块) |
|
||
| 绿/红 | `tool_call_result`(成功/失败) |
|
||
|
||
### 布局
|
||
|
||
双栏:左侧 `ChatView`(MessageList + ChatInput),右侧 `ProtocolPanel`(实时 OpenAI Format JSON 视图,支持复制/下载)。顶栏有 Demo 场景切换按钮。
|