From a66ab764d9e6bdc637c76795577fc12b3b42a090 Mon Sep 17 00:00:00 2001 From: hhs <386998068@qq.com> Date: Sun, 21 Jun 2026 19:31:17 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E7=BB=9F=E4=B8=80=E6=96=87=E6=A1=A3?= =?UTF-8?q?=E9=A3=8E=E6=A0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/08-Eino框架与编排设计.md | 4 - docs/09-情景切换.md | 4 - ...建情景功能完整文档.md => 12-自定义情景.md} | 355 ++++-------------- 3 files changed, 83 insertions(+), 280 deletions(-) rename docs/{自建情景功能完整文档.md => 12-自定义情景.md} (52%) diff --git a/docs/08-Eino框架与编排设计.md b/docs/08-Eino框架与编排设计.md index bcb48a5..041d103 100644 --- a/docs/08-Eino框架与编排设计.md +++ b/docs/08-Eino框架与编排设计.md @@ -1,9 +1,5 @@ # CamTalk Eino 框架与编排设计 -> 创建日期:2026-06-19 -> 状态:已实施 -> 合并自:`10-Eino重构方案.md` + `11-Eino框架技术文档.md` - ## 1. 概述 ### 1.1 为什么选择 Eino diff --git a/docs/09-情景切换.md b/docs/09-情景切换.md index 259504e..13caab8 100644 --- a/docs/09-情景切换.md +++ b/docs/09-情景切换.md @@ -1,9 +1,5 @@ # 情景切换功能 -**状态**: ✅ 已完成 - ---- - ## 功能概述 情景切换功能允许用户选择不同的对话场景,AI 会根据选择的情景扮演不同的角色: diff --git a/docs/自建情景功能完整文档.md b/docs/12-自定义情景.md similarity index 52% rename from docs/自建情景功能完整文档.md rename to docs/12-自定义情景.md index a9985f2..f742095 100644 --- a/docs/自建情景功能完整文档.md +++ b/docs/12-自定义情景.md @@ -1,24 +1,8 @@ -# 自建情景功能完整文档 +# 自建情景功能 -**最后更新**: 2026-06-21 -**开发者**: Claude Code + cfy -**状态**: ✅ 开发完成(80%),待测试验证 +## 概述 ---- - -## 📊 总体进度 - -**当前状态**: ✅ **Phase 1-4 已完成** -**完成度**: 🟢 **80%** (4/5 Phases) -**剩余**: Phase 5 测试验证 - ---- - -## 一、功能概述 - -### 核心功能 - -用户可以创建自己的情景,而不仅限于系统预置的 5 种情景: +用户可以创建自己的情景,而不仅限于系统预置的 5 种情景。 **系统预置情景**(不可修改): - 💬 自由对话 @@ -34,7 +18,7 @@ - 📖 历史学家 - ... (用户自由创建) -### 用户旅程 +**用户旅程**: ``` 1. 用户点击"创建情景"按钮 @@ -59,29 +43,32 @@ 8. AI 按照用户设定的 Prompt 扮演角色 ``` -**权限隔离**: 每个用户只能看到和管理自己创建的情景,通过 `user_id` 实现数据隔离。 +**核心特性**:完整 CRUD 操作(创建/查看/编辑/删除),通过 `user_id` 实现用户数据完全隔离,Eino Graph 管线深度集成(动态加载自建情景 Prompt),中文/英文/日文全覆盖,Modal 对话框 + 图标选择器 + Prompt 编写指南,创建后立即可用无需刷新。 ---- +## 技术架构 -## 二、技术实现架构 +### 数据流 -### 2.1 数据流图 +**创建情景**: ``` -【创建情景】 用户填写表单 → POST /api/scenarios → Handler 验证 → Repository.Create → PostgreSQL 插入 → 返回情景对象 +``` -【AI 对话使用自建情景】 +**AI 对话使用自建情景**: + +``` WebSocket 连接 → ServeWS 获取 userID → Eino Graph 初始化 → nodes_history 查询 user_scenarios → GetScenarioPrompt(customScenarios) → 构建 System Prompt → LLM 生成回复 ``` -### 2.2 Eino 框架集成 +### Eino 框架集成 + +**数据传递链路**: -**数据传递链路**: ``` JWT Token → userID ↓ @@ -100,19 +87,20 @@ llm.GetScenarioPrompt(scenarioID, language, customScenarios) LLM 使用自建情景 Prompt ``` -**关键修改文件**: -1. `backend/internal/eino/state.go` — PipelineState 添加 `UserID` -2. `backend/internal/eino/types.go` — PipelineInput 添加 `UserID` -3. `backend/internal/eino/graph.go` — 接受 `scenarioRepo` 参数 -4. `backend/internal/eino/adapter.go` — 设置 UserID -5. `backend/internal/eino/nodes_history.go` — 查询自建情景 -6. `backend/internal/ws/handler.go` — 首句引导支持自建情景 +**关键修改文件**: ---- +| 文件 | 变更说明 | +|------|----------| +| `backend/internal/eino/state.go` | PipelineState 添加 `UserID` | +| `backend/internal/eino/types.go` | PipelineInput 添加 `UserID` | +| `backend/internal/eino/graph.go` | 接受 `scenarioRepo` 参数 | +| `backend/internal/eino/adapter.go` | 设置 UserID | +| `backend/internal/eino/nodes_history.go` | 查询自建情景 | +| `backend/internal/ws/handler.go` | 首句引导支持自建情景 | -## 三、数据模型设计 +## 数据模型 -### 3.1 数据库表结构 +### 数据库表结构 **表名**: `user_scenarios` @@ -128,7 +116,7 @@ CREATE TABLE user_scenarios ( language VARCHAR(10) DEFAULT 'zh-CN', created_at TIMESTAMP NOT NULL DEFAULT NOW(), updated_at TIMESTAMP NOT NULL DEFAULT NOW(), - + CONSTRAINT unique_user_scenario UNIQUE(user_id, name), CONSTRAINT check_name_length CHECK (char_length(name) >= 2 AND char_length(name) <= 50), CONSTRAINT check_description_length CHECK (description IS NULL OR char_length(description) <= 100), @@ -141,16 +129,19 @@ CREATE INDEX idx_user_scenarios_created_at ON user_scenarios(created_at DESC); ``` **字段说明**: -- `id`: 情景唯一标识 -- `user_id`: 所属用户,实现数据隔离 -- `name`: 情景名称(2-50 字符) -- `icon`: Emoji 图标(默认 ✨) -- `description`: 简短描述(可选,最多 100 字符) -- `prompt`: 角色 System Prompt(10-2000 字符) -- `greeting`: 首句引导(可选,最多 500 字符) -- `language`: 默认语言(zh-CN / en-US / ja-JP) -### 3.2 后端数据模型 +| 字段 | 说明 | +|------|------| +| `id` | 情景唯一标识 | +| `user_id` | 所属用户,实现数据隔离 | +| `name` | 情景名称(2-50 字符) | +| `icon` | Emoji 图标(默认 ✨) | +| `description` | 简短描述(可选,最多 100 字符) | +| `prompt` | 角色 System Prompt(10-2000 字符) | +| `greeting` | 首句引导(可选,最多 500 字符) | +| `language` | 默认语言(zh-CN / en-US / ja-JP) | + +### 后端数据模型 ```go // backend/internal/models/user_scenario.go @@ -178,7 +169,7 @@ type CreateUserScenarioRequest struct { } ``` -### 3.3 前端数据结构 +### 前端数据结构 ```typescript // frontend/src/lib/api/scenarios.ts @@ -212,11 +203,9 @@ export interface ExtendedScenario { } ``` ---- +## REST API -## 四、REST API 设计 - -### 4.1 API 端点 +### API 端点 | 方法 | 路径 | 说明 | 权限 | |------|------|------|------| @@ -226,9 +215,10 @@ export interface ExtendedScenario { | PATCH | `/api/scenarios/:id` | 更新情景 | 需登录 | | DELETE | `/api/scenarios/:id` | 删除情景 | 需登录 | -### 4.2 API 示例 +### API 示例 + +**创建情景**: -#### 创建情景 ```http POST /api/scenarios Authorization: Bearer @@ -244,36 +234,36 @@ Content-Type: application/json } ``` -**响应**: 201 Created +响应 201 Created: + ```json { "id": "uuid-xxx", "user_id": "uuid-user", "name": "创意写作导师", - "icon": "✨", - ... + "icon": "✨" } ``` -#### 获取列表 +**获取列表**: + ```http GET /api/scenarios Authorization: Bearer ``` -**响应**: 200 OK +响应 200 OK: + ```json { - "scenarios": [...], + "scenarios": [], "total": 3 } ``` ---- +## 前端实现 -## 五、前端实现 - -### 5.1 组件结构 +### 组件结构 ``` frontend/src/ @@ -291,21 +281,21 @@ frontend/src/ └── scenarios.ts # API 调用封装 ``` -### 5.2 核心 Hook +### 核心 Hook ```typescript // useScenarios.ts export function useScenarios(token: string | null) { const [allScenarios, setAllScenarios] = useState([]); - + // 合并系统预置 + 用户自建 useEffect(() => { const systemScenarios = scenarios.map(s => ({...s, isCustom: false})); const customScenarios = customList.map(s => ({...s, isCustom: true})); setAllScenarios([...systemScenarios, ...customScenarios]); }, [customList]); - + return { allScenarios, createScenario, @@ -315,9 +305,10 @@ export function useScenarios(token: string | null) { } ``` -### 5.3 创建情景表单 +### 创建情景表单 + +**表单字段**: -**表单字段**: - 名称(必填,2-50 字符) - 图标(可选,24 个预设 emoji) - 描述(可选,最多 100 字符) @@ -325,175 +316,15 @@ export function useScenarios(token: string | null) { - 首句引导(可选,最多 500 字符) - 语言(可选,默认 zh-CN) -**表单验证**: +**表单验证**: + - 实时字符计数 - 长度限制提示 - 必填项高亮 ---- +## 使用指南 -## 六、实施进度 - -### ✅ Phase 1: 后端基础(100% 完成) - -**1.1 数据库迁移** ✅ -- 文件: `backend/migrations/004_user_scenarios.up.sql` -- 创建 `user_scenarios` 表 -- 添加索引和约束 - -**1.2 数据模型** ✅ -- 文件: `backend/internal/models/user_scenario.go` -- 定义 `UserScenario` 结构体 -- 定义请求/响应模型 - -**1.3 Repository 层** ✅ -- 文件: `backend/internal/store/user_scenario_repository.go` -- 实现 `UserScenarioRepository` 接口 -- CRUD 操作 + 权限校验 - -**1.4 REST API** ✅ -- 文件: `backend/internal/api/user_scenario_handler.go` -- 5 个 HTTP 端点(创建/列表/详情/更新/删除) -- 输入验证和错误处理 - -### ✅ Phase 2: 后端集成(100% 完成) - -**2.1 Prompt 加载逻辑** ✅ -- 修改: `backend/internal/ai/llm/scenarios.go` -- `GetScenarioPrompt` 支持自建情景 -- `GetScenarioGreeting` 支持自建情景 - -**2.2 Eino 框架集成** ✅ -- 修改 7 个文件,完整数据链路 -- PipelineState 添加 UserID -- nodes_history 查询用户自建情景 -- 动态构建 System Prompt - -### ✅ Phase 3: 前端 UI(100% 完成) - -**3.1 API 封装** ✅ -- 文件: `frontend/src/lib/api/scenarios.ts` -- 5 个 API 调用函数 - -**3.2 Hook 封装** ✅ -- 文件: `frontend/src/hooks/useScenarios.ts` -- `useScenarios` Hook -- 合并系统预置 + 自建情景 - -**3.3 组件实现** ✅ -- `CreateScenarioModal` — 创建对话框 -- `EditScenarioModal` — 编辑对话框 -- `ConfigPanel` 改造 — 分组显示 + 编辑/删除 - -**3.4 i18n 支持** ✅ -- 中文/英文/日文翻译(+40 条) - -**3.5 样式实现** ✅ -- Modal、表单、图标选择器样式 - -### ✅ Phase 4: 前端集成(100% 完成) - -**4.1 主应用集成** ✅ -- 文件: `frontend/src/App.tsx` -- 集成 `useScenarios` Hook -- 渲染 Modal 组件 -- 情景选择联动 - -**4.2 编译验证** ✅ -- 前端: 669.96 kB JS + 55.80 kB CSS -- 后端: 48MB 二进制 - -### ⏳ Phase 5: 测试验证(待进行) - -**5.1 后端测试** -- [ ] 数据库迁移验证 -- [ ] REST API CRUD 测试 -- [ ] 权限隔离测试 -- [ ] Eino Graph 自建情景加载测试 - -**5.2 前端测试** -- [ ] 创建情景表单验证 -- [ ] 编辑情景数据预填充 -- [ ] 删除情景二次确认 -- [ ] 情景列表实时更新 - -**5.3 集成测试** -- [ ] 创建自建情景后立即可用 -- [ ] 切换到自建情景显示首句引导 -- [ ] AI 对话使用自建 Prompt -- [ ] 多用户并发隔离 - ---- - -## 七、已完成文件清单 - -### 新增文件(13 个) - -**后端(5 个)**: -1. `backend/migrations/004_user_scenarios.up.sql` -2. `backend/migrations/004_user_scenarios.down.sql` -3. `backend/internal/models/user_scenario.go` -4. `backend/internal/store/user_scenario_repository.go` -5. `backend/internal/api/user_scenario_handler.go` - -**前端(5 个)**: -6. `frontend/src/lib/api/scenarios.ts` -7. `frontend/src/hooks/useScenarios.ts` -8. `frontend/src/components/CreateScenarioModal/index.tsx` -9. `frontend/src/components/EditScenarioModal/index.tsx` - -**文档(3 个)**: -10. `docs/自建情景功能设计方案.md` -11. `docs/自建情景功能-权限隔离说明.md` -12. `docs/自建情景功能实施进度.md` -13. `docs/自建情景功能完整文档.md` (本文件) - -### 修改文件(14 个) - -**后端(8 个)**: -1. `backend/cmd/server/main.go` — 注册 API 路由 + 传递 scenarioRepo -2. `backend/internal/ai/llm/scenarios.go` — Prompt/Greeting 加载支持自建 -3. `backend/internal/eino/state.go` — 添加 UserID 字段 -4. `backend/internal/eino/types.go` — PipelineInput 添加 UserID -5. `backend/internal/eino/graph.go` — 接受并传递 scenarioRepo -6. `backend/internal/eino/adapter.go` — 复制 UserID 到 State -7. `backend/internal/eino/nodes_history.go` — 加载自建情景 -8. `backend/internal/ws/handler.go` — 首句引导支持自建情景 - -**前端(6 个)**: -9. `frontend/src/App.tsx` — 集成自建情景管理 -10. `frontend/src/components/ConfigPanel/index.tsx` — 分组显示 + 编辑/删除 -11. `frontend/src/lib/i18n/zh-CN.ts` — 新增翻译 -12. `frontend/src/lib/i18n/en-US.ts` — 新增翻译 -13. `frontend/src/lib/i18n/ja-JP.ts` — 新增翻译 -14. `frontend/src/App.css` — 新增样式 - ---- - -## 八、问题解决记录 - -### 8.1 CORS 错误 - -**问题**: 前端直接访问 `http://localhost:8080` 触发 CORS -**解决**: 将 `API_BASE` 改为空字符串,使用 Vite 代理 - -### 8.2 验证规则不一致 - -**问题**: 后端要求 `description` 必填,`prompt` 最小 50 字符 -**解决**: 统一为 `description` 可选,`prompt` 最小 10 字符 - -### 8.3 数据库约束错误 - -**问题**: 空字符串 `""` 不满足 `char_length >= 1` 约束 -**解决**: -1. 更新约束允许 `description IS NULL` -2. Repository 使用 `NULLIF($5, '')` 将空字符串转为 NULL - ---- - -## 九、测试指南 - -### 9.1 后端 API 测试 +### 后端 API 测试 ```bash # 1. 注册用户 @@ -528,9 +359,8 @@ curl -X DELETE http://localhost:8080/api/scenarios/ \ -H "Authorization: Bearer $TOKEN" ``` -### 9.2 前端功能测试 +### 前端功能测试 -**操作步骤**: 1. 刷新浏览器(Cmd+Shift+R) 2. 登录账户 3. 打开设置面板(右上角齿轮) @@ -543,72 +373,53 @@ curl -X DELETE http://localhost:8080/api/scenarios/ \ 10. 编辑情景,验证数据预填充 11. 删除情景,验证二次确认 ---- +## 安全与限制 -## 十、功能亮点 - -✅ **完整的 CRUD** — 创建、查看、编辑、删除自建情景 -✅ **权限隔离** — 用户数据完全隔离,无法互相访问 -✅ **Eino 深度集成** — 在 Graph Pipeline 中动态加载自建情景 -✅ **多语言支持** — 中文、英文、日文全覆盖 -✅ **优雅的 UI** — Modal 对话框 + 图标选择器 + Prompt 编写指南 -✅ **实时生效** — 创建后立即可用,无需刷新 -✅ **表单验证** — 字符计数、长度限制、必填项提示 - ---- - -## 十一、安全与限制 - -### 11.1 用户配额 +### 用户配额 ```go const MaxScenariosPerUser = 20 // 每个用户最多 20 个自建情景 ``` -### 11.2 权限控制 +### 权限控制 - 只能查看/编辑/删除自己的情景 - 系统预置情景不可编辑/删除 - 后端验证 `user_id` 匹配 -### 11.3 数据验证 +### 数据验证 -**后端**: -- 名称: 2-50 字符 -- 描述: 可选,最多 100 字符 -- Prompt: 10-2000 字符 -- 首句: 可选,最多 500 字符 +**后端**: + +- 名称:2-50 字符 +- 描述:可选,最多 100 字符 +- Prompt:10-2000 字符 +- 首句引导:可选,最多 500 字符 + +**前端**: -**前端**: - 实时字符计数 - 超长提示 - 必填项高亮 ---- +## 未来优化方向 -## 十二、未来优化方向 +**V1.1**: -### V1.1 功能(推荐) - Prompt 模板库 - 实时预览效果 - 导入导出功能 - 情景搜索和筛选 -### V2.0 功能(长期) +**V2.0**: + - 情景市场 - 情景分享链接 - AI 辅助优化 Prompt - 协作编辑(团队情景) ---- - -## 十三、参考资料 +## 参考资料 - [CLAUDE.md](../CLAUDE.md) — 项目开发指南 - [02-接口文档.md](./02-接口文档.md) — WebSocket 和 REST API - [自建情景功能-权限隔离说明.md](./自建情景功能-权限隔离说明.md) — 安全设计 - ---- - -**开发完成日期**: 2026-06-21 -**下一步行动**: 启动服务进行人工测试验证 \ No newline at end of file