feat(copilot): finish configuration center

This commit is contained in:
2026-07-13 14:57:28 +08:00
parent 0a69d80f7c
commit 8b9eedc0e2
60 changed files with 3040 additions and 1042 deletions
+72 -85
View File
@@ -5,8 +5,8 @@
> 不提供总开关,不定义 Captain/Copilot 环境变量或 YAML Provider 配置;Provider、
> Base URL、API Key 与模型仅通过页面写入数据库。API Key 明文存储,API/UI 仅返回配置状态和掩码。
> 调研日期:2026-07-08(初版)/ 2026-07-09 更新
> 基于代码库:main 分支 @ 805402f
> 调研日期:2026-07-08(初版)/ 2026-07-12 更新
> 基于代码库:2026-07-12 Copilot 配置中心实现状态
> 对标项目:Chatwoot Captain AI (enterprise edition)
> 注:2026-07-09 状态更新 — Eino 框架已替换手写 LLM 层,多 LLM Provider(OpenAI/Anthropic)已接入,
> Function Calling 已实现,Help Center pgvector 语义搜索已实现,AutoReplyRule 已集成到消息流程。
@@ -27,20 +27,21 @@
## 1. 评估摘要
GoChat 已搭建了一套对标 Chatwoot Captain AI 的完整基础设施,覆盖了 LLM Provider 抽象层、
数据模型、Service 业务逻辑、Handler/路由、前端 UI 组件和后台 Worker。**约 90% 的 AI 代码
已经写好**,但存在若干"最后一公里"接缝未缝合的问题,导致部分功能无法实际运行。
GoChat 已搭建一套对标 Chatwoot Captain AI 的完整基础设施,覆盖 LLM Provider 抽象层、
数据库驱动的 Copilot 配置中心、数据模型、Service、Handler/路由、前端 UI 和后台 Worker。
Provider 配置与运行链路已闭环,保存后无需重启即可生效。
核心结论:
- **可用功能**:Copilot 侧边栏对话、回复建议、会话摘要、改写润色、标签建议、跟进任务、
会话洞察、文档同步、批量 AI 操作、助手 CRUD/Playground、帮助中心文章 AI 翻译
- **代码就绪但未接入**:RAG 知识库问答(路由未注册)、自动回复规则(未接入消息流程)、
CaptainConversationService(被 `_ =` 忽略)
- **完全缺失**:帮助中心语义搜索、AgentBot + Captain 端到端 AI 客服、多 LLM Provider 支持
- **配置缺口**:缺少数据库驱动的 Copilot 配置页面,Provider/API Key 与实际运行链路尚未闭环
- **已闭环**:Copilot 配置中心、OpenAI/Anthropic/OpenAI-compatible、Chat/Embedding 分离、
运行时热切换、账户功能模型、回复行为、连接测试、Embedding 重建和无密钥审计。
- **可用功能**:Copilot 对话、回复建议、摘要、改写、标签/跟进、RAG、帮助中心语义搜索、
自动回复规则、Captain Conversation、AgentBot + Captain、Function Calling、文档同步和 AI 翻译。
- **后续重点**:Token 用量/配额、调用级可观测性与质量评估、动态模型发现、多 Provider fallback、
独立语音转写 Provider。
整体评估:基础设施成熟度高(9/10),功能可用度中等(5/10),需补齐配置与接缝工作。
整体评估:基础设施成熟度高,核心功能已进入可配置、可验证、可热更新状态;后续工作以运营、
成本、质量与容灾能力为主。
---
@@ -48,7 +49,8 @@ GoChat 已搭建了一套对标 Chatwoot Captain AI 的完整基础设施,覆
### 2.1 LLM Provider 层
**文件**:`backend/internal/llm/provider.go` + `openai_provider.go`
**文件**:`backend/internal/llm/provider.go`、`openai_provider.go`、`anthropic_provider.go`、
`provider_manager.go`
- `Provider` 接口定义三个核心能力:
- `ChatCompletion` — 同步对话补全
@@ -61,7 +63,8 @@ GoChat 已搭建了一套对标 Chatwoot Captain AI 的完整基础设施,覆
- API 错误结构化解析(`APIError` 类型)
- 数据结构:`ChatRequest`/`ChatResponse`/`ChatMessage`/`EmbeddingRequest`/`EmbeddingResponse`/
`StreamChunk`/`ToolDefinition`/`ToolFunction`
- **问题**:`ToolDefinition` 已定义但从未在调用时传入 LLM
- `ProviderManager` 原子替换 Chat/Embedding Provider Snapshot;账户模型按功能解析后进入请求。
- `ToolExecutionService` 已将 Custom Tool 转为 `ToolDefinition`,执行 tool-call 循环并回传结果。
### 2.2 数据模型层
@@ -152,7 +155,7 @@ bulk_actions POST
| 组件/文件 | 路径 | 说明 |
|-----------|------|------|
| Captain 设置页 | `routes/dashboard/settings/captain/Index.vue` | 模型选择 + 功能开关(label_suggestion/help_center_search/audio_transcription) |
| Copilot 配置页 | `routes/dashboard/settings/captain/Index.vue` | 平台 Provider、账户模型/功能、回复行为、连接测试与 Embedding 重建 |
| ModelSelector | `routes/dashboard/settings/captain/components/ModelSelector.vue` | 按 feature 选择 LLM 模型 |
| FeatureToggle | `routes/dashboard/settings/captain/components/FeatureToggle.vue` | AI 功能开关 |
| CopilotContainer | `components/copilot/CopilotContainer.vue` | 侧边栏 Copilot 聊天面板 |
@@ -160,7 +163,8 @@ bulk_actions POST
| useCaptain | `composables/useCaptain.js` | Captain 功能开关/配额/错误处理 |
| useCopilotReply | `composables/useCopilotReply.js` | 回复建议/改写/摘要的 composable |
| useLabelSuggestions | `composables/useLabelSuggestions.js` | 标签建议 |
| API 客户端 | `api/captain/` | 12 个文件:assistant/document/tasks/copilotThreads/copilotMessages/preferences/scenarios/tools/bulkActions/inboxes/customTools/response |
| 配置 API 客户端 | `api/copilotConfig.js` | 平台配置/测试/重建与账户聚合配置 |
| Captain API 客户端 | `api/captain/` | Assistant、Document、Task、Copilot Thread/Message、Tool 等业务 API |
**Feature Flags**(`featureFlags.js`):
- `CAPTAIN` = `captain_integration`
@@ -175,7 +179,7 @@ bulk_actions POST
|--------|------|----------|------|
| CaptainDocumentWorker | `captain_document_worker.go` | 6 种任务 | 文档同步/爬取/页面解析/embedding 更新/调度 |
| CopilotResponseWorker | `copilot_response_worker.go` | 1 种任务 | 异步 Copilot 响应生成 |
| CaptainConversationWorker | `captain_conversation_service.go` 内 | 1 种任务 | 会话响应构建(但 service 被 `_ =` 忽略) |
| CaptainConversationWorker | `captain_conversation_service.go` 内 | 1 种任务 | 会话响应构建、tool-call 与 handoff;已接入 AgentBot Listener |
### 2.7 配置层
@@ -196,89 +200,77 @@ Captain/Copilot 模型字段,也不读取相关环境变量或 YAML 配置。
| Rewrite(改写润色) | ✅ 完整 | 含流式,7 种操作 |
| Label Suggestion(标签建议) | ✅ 完整 | 单会话 + 批量 |
| Follow-up Task(跟进任务) | ✅ 完整 | 批量 |
| Knowledge Base / RAG(知识库问答) | ⚠️ 代码完整,路由未注册 | RAGService + RAGHandler 存在但未接入 |
| Knowledge Base / RAG(知识库问答) | ✅ 完整 | RAGService、Handler 和 `/captain/rag/*` 路由已注册 |
| Document Sync(文档爬取同步) | ✅ 完整 | 6 种 Worker 任务 |
| Custom Tools(Function Calling 定义) | ✅ 模型+服务完整 | 但 LLM 调用时未传 tools 参数 |
| Custom Tools(Function Calling) | ✅ 完整 | ToolDefinition、HTTP 执行和 tool-call 循环已接入 |
| Captain Preferences(AI 偏好) | ✅ 完整 | tone/language/auto_label/auto_reply |
| Auto-Reply Rules(自动回复规则) | ⚠️ 模型完整,未接入 | 模型+基础 service,无路由,无消息钩子 |
| Auto-Reply Rules(自动回复规则) | ✅ 完整 | CRUD、条件匹配、static/llm/mixed 和消息 Listener 已接入 |
| Conversation Insight(会话洞察) | ✅ 完整 | 参与者分析/行动项/标签 |
| Bulk Actions(批量 AI 操作) | ✅ 完整 | |
| Help Center 语义搜索 | ❌ 缺失 | ArticleEmbedding 表存在但无搜索方法 |
| AgentBot + Captain(端到端 AI 客服) | ❌ 缺失 | AgentBot 仅支持 webhook 类型 |
| Captain Conversation Auto-Response | ⚠️ 代码存在,被忽略 | bootstrap.go:594 `_ = captainConversationService` |
| Help Center 语义搜索 | ✅ 完整 | pgvector 搜索、文章向量生成和重建进度已接入 |
| AgentBot + Captain(端到端 AI 客服) | ✅ 完整 | `captain` BotType 路由到 CaptainConversationService |
| Captain Conversation Auto-Response | ✅ 完整 | Worker、Listener、tool-call 与 handoff 已接入 |
| Article AI 翻译 | ✅ 完整 | LLMArticleTranslationBackend |
| Multi-Provider LLM | ❌ 仅 OpenAI | 无 Anthropic/国内模型 provider 实现 |
| Multi-Provider LLM | ✅ 完整 | OpenAI、Anthropic、OpenAI-compatible,支持自定义兼容端点 |
| Token 用量统计与配额 | ❌ 缺失 | 前端有 captainLimits 结构,后端无统计 |
| AI 审计日志 | ❌ 缺失 | |
| AI 配置审计 | ✅ 完整 | Provider 配置变更审计不记录 Key/掩码;调用级审计仍属后续能力 |
---
## 4. 关键缺口分析
## 4. 已完成闭环与剩余缺口
### 缺口 G1:缺少数据库驱动的 Copilot 配置中心
### 已完成 G1:数据库驱动的 Copilot 配置中心
- **影响**:Provider/API Key 不能从页面配置,账户模型选择与实际运行 Provider 脱节
- **位置**:前端 Captain 设置页、`installation_configs`、`bootstrap.go` 固定 Provider 注入
- **修复成本**:中(配置 API、页面、Provider Manager 和模型解析)
- Provider/API Key 由“设置 → Copilot 配置”写入 `installation_configs`。
- API Key 明文存储,但读取接口、页面和审计只暴露状态/掩码。
- `ProviderManager` 热替换运行时 Provider;账户功能模型进入实际请求。
### 缺口 G2:RAG 路由未注册
### 已完成 G2:RAG 路由与运行服务
- **影响**:知识库问答 API 无法访问
- **位置**:`RAGHandler` 代码完整(`rag_handler.go`),但 `bootstrap.go` 未实例化
`RAGService`/`RAGHandler`,`router.go` 未注册 `/captain/rag/*` 路由
- **修复成本**:低(~20 行 bootstrap + router 代码)
- `RAGService`/`RAGHandler` 已实例化并注册 `/captain/rag/query` 与索引路由。
### 缺口 G3:AutoReplyRule 未接入
### 已完成 G3:AutoReplyRule 消息闭环
- **影响**:无法实现"消息进来 → AI 自动回复"
- **位置**:`auto_reply_rule_models.go` 模型完整(static/llm/mixed),但:
- 无完整的条件匹配引擎
- 无消息接收时的规则匹配钩子
- 无路由注册
- **修复成本**:中(需实现条件匹配 + 消息流程集成)
- 已实现规则 CRUD、条件匹配、static/llm/mixed 回复和消息 Listener。
### 缺口 G4:CaptainConversationService 被忽略
### 已完成 G4:CaptainConversationService 接入
- **影响**:会话级 AI 自动响应(handoff 模式)不可用
- **位置**:`bootstrap.go:594` `_ = captainConversationService`
- **修复成本**:中(需接入消息接收流程 + handoff 逻辑)
- 已注入 Handler、Worker、AgentBot Listener 和 ToolExecutionService,支持 handoff。
### 缺口 G5:AgentBot 仅支持 Webhook
### 已完成 G5:AgentBot + Captain
- **影响**:无法实现"AgentBot 绑定 Captain Assistant → 端到端 AI 客服"
- **位置**:`agent_bot.go` 只有 webhook 推送模式
- **修复成本**:中高(需扩展 AgentBot 类型 + 消息路由)
- `captain` BotType 已路由到 CaptainConversationService;Webhook Bot 行为保持兼容。
### 缺口 G6:Help Center 语义搜索缺失
### 已完成 G6:Help Center 语义搜索
- **影响**:帮助中心文章无法语义搜索
- **位置**:`ArticleEmbedding` 表存在,`article_service.go` 无搜索方法
- **修复成本**:中(需实现 embedding 生成 + pgvector 搜索 + API + 前端)
- ArticleService 已生成查询/文章 Embedding 并通过 pgvector 搜索;维度可动态迁移并后台重建。
### 缺口 G7:Function Calling 未实际使用
### 已完成 G7:Function Calling
- **影响**:CustomTool 定义了但 LLM 调用时未传 tools 参数,AI 无法调用工具
- **位置**:`llm/provider.go` 的 `ToolDefinition` 已定义;
`captain_task_service.go` / `captain_conversation_service.go` 的 `ChatRequest` 未设置 `Tools` 字段
- **修复成本**:中(需实现 tool_call 循环 + HTTP 执行 + 结果回传)
- ToolExecutionService 已完成工具定义转换、HTTP 执行、结果回传和多轮 tool-call loop。
### 缺口 G8:多 LLM Provider 支持
### 已完成 G8:多 LLM Provider
- **影响**:仅支持 OpenAI 兼容 API,无法直接使用 Anthropic/本地模型
- **位置**:`llm/` 下只有 `openai_provider.go`
- **修复成本**:中(每个 provider ~200 行实现 + 接口适配)
- OpenAI、Anthropic 和 OpenAI-compatible 均可通过数据库配置并热切换。
### 剩余缺口
- Token 用量、成本和账户配额。
- AI 调用级审计、Langfuse/OpenTelemetry 观测和质量评估。
- Provider 动态模型发现与缓存、多 Provider fallback。
- 独立语音转写 Provider 和账户级配额策略。
---
## 5. 开发路线图
### 阶段 1:激活现有 AI 功能(P0,1-2 天)
### 阶段 1:激活现有 AI 功能(P0,已完成)
**目标**:让已写好的 90% 代码真正跑起来,实现"配置即可用"。
**前提**:需要一个可用的 LLM API Key(OpenAI 或兼容端点)。
#### 任务 1.1:通过页面配置 Copilot Provider
#### 任务 1.1:通过页面配置 Copilot Provider(✅ 已完成)
在“设置 → Copilot 配置”中保存 Provider、Base URL、API Key 和默认模型。
配置写入数据库并热替换运行时 Provider,不使用环境变量或 `config*.yaml`。
@@ -289,7 +281,7 @@ Captain/Copilot 模型字段,也不读取相关环境变量或 YAML 配置。
**验收**:保存后无需重启,新请求立即使用页面配置的 Provider。
#### 任务 1.2:注册 RAG 路由
#### 任务 1.2:注册 RAG 路由(✅ 已完成)
**文件修改**:
@@ -311,18 +303,13 @@ Captain/Copilot 模型字段,也不读取相关环境变量或 YAML 配置。
**验收**:`curl -X POST /api/v1/accounts/1/captain/rag/query -d '{"assistant_id":1,"question":"test"}'`
返回非 404。
#### 任务 1.3:取消 CaptainConversationService 忽略
#### 任务 1.3:接入 CaptainConversationService(✅ 已完成)
**文件**:`backend/internal/app/bootstrap.go:594`
服务已注入 Handler、Worker、AgentBot Listener 和 ToolExecutionService。
将 `_ = captainConversationService` 改为注入到 Handlers 或消息处理流程。
**验收**:会话级响应、tool-call 和 handoff 路径均有自动化覆盖。
最小改动:将其传入 `CaptainAssistantHandler` 或新建一个 handler 方法,
供后续阶段 2 的 AgentBot 集成使用。
**验收**:编译通过,`captainConversationService` 不再被忽略。
#### 任务 1.4:端到端验证
#### 任务 1.4:端到端验证(✅ 配置链路已完成)
配置真实 LLM API Key 后测试:
1. Playground 对话:`POST /captain/assistants/:id/playground`
@@ -335,11 +322,11 @@ Captain/Copilot 模型字段,也不读取相关环境变量或 YAML 配置。
---
### 阶段 2:自动回复与端到端 AI 客服(P1,3-5 天)
### 阶段 2:自动回复与端到端 AI 客服(P1,核心链路已完成)
**目标**:实现"客户消息进来 → AI 自动响应"的闭环。
#### 任务 2.1:AutoReplyRule 完整接入
#### 任务 2.1:AutoReplyRule 完整接入(✅ 已完成)
**子任务**:
@@ -377,7 +364,7 @@ Captain/Copilot 模型字段,也不读取相关环境变量或 YAML 配置。
**验收**:创建一条 llm 模式规则 → 发送匹配消息 → AI 自动回复。
#### 任务 2.2:AgentBot + Captain 集成
#### 任务 2.2:AgentBot + Captain 集成(✅ 已完成)
**子任务**:
@@ -399,7 +386,7 @@ Captain/Copilot 模型字段,也不读取相关环境变量或 YAML 配置。
**验收**:配置一个 captain 类型 AgentBot → 客户发消息 → AI 自动回复 → AI 判断需转人工时 handoff。
#### 任务 2.3:CaptainConversationService 完整接入
#### 任务 2.3:CaptainConversationService 完整接入(✅ 已完成)
**子任务**:
@@ -419,7 +406,7 @@ Captain/Copilot 模型字段,也不读取相关环境变量或 YAML 配置。
### 阶段 3:增强 AI 能力深度(P2,1-2 周)
#### 任务 3.1:Help Center 语义搜索
#### 任务 3.1:Help Center 语义搜索(✅ 已完成)
**子任务**:
@@ -432,14 +419,14 @@ Captain/Copilot 模型字段,也不读取相关环境变量或 YAML 配置。
**验收**:搜索"如何重置密码"能找到相关文章(即使标题不含"重置")。
#### 任务 3.2:Function Calling 完整实现
#### 任务 3.2:Function Calling 完整实现(✅ 已完成)
详见阶段 2 任务 2.3 的工具调用实现。此阶段将其推广到所有 AI 服务:
- `CopilotService` — Copilot 对话中可调用工具
- `CaptainTaskService` — 回复建议时可调用 FAQ 查询工具
- `CaptainAssistantService.GenerateResponse` — Playground 对话中可调用工具
#### 任务 3.3:多 LLM Provider 支持
#### 任务 3.3:多 LLM Provider 支持(✅ 已完成)
**子任务**:
@@ -504,7 +491,7 @@ Captain/Copilot 模型字段,也不读取相关环境变量或 YAML 配置。
| 风险 | 影响 | 缓解措施 |
|------|------|----------|
| LLM API 调用超时/失败 | AI 功能不可用 | 已有重试机制(3 次指数退避);需加 fallback 策略(降级到静态回复) |
| pgvector 维度不匹配 | RAG 搜索失败 | 当前固定 1536 维(text-embedding-3-small);更换 embedding 模型时需迁移 |
| pgvector 维度不匹配 | RAG 搜索失败 | 使用动态维度迁移、保存确认和后台 Embedding 重建进度控制 |
| Token 消耗成本 | 生产环境费用 | 阶段 4 实现配额限制;阶段 1-3 开发环境用 gpt-4o-mini 控制成本 |
| SSE 连接稳定性 | 流式响应中断 | 已有 `X-Accel-Buffering: no`;需加心跳机制和断线重连 |
| 并发 LLM 调用 | 速率限制 | 需实现请求队列 + 限流(令牌桶) |
@@ -546,12 +533,12 @@ ModelSelector、FeatureToggle)。阶段 1-2 的前端改动极小,主要是
| `backend/internal/service/copilot_context_service.go` | 会话上下文组装 |
| `backend/internal/service/rag_service.go` | RAG 全流程 |
| `backend/internal/service/conversation_insight_service.go` | 会话洞察 |
| `backend/internal/service/captain_conversation_service.go` | 会话级 AI 响应(被忽略) |
| `backend/internal/service/captain_conversation_service.go` | 会话级 AI 响应、tool-call 与 handoff |
| `backend/internal/service/captain_document_service.go` | 文档同步 |
| `backend/internal/service/captain_document_worker.go` | 文档 Worker |
| `backend/internal/service/copilot_response_worker.go` | Copilot 响应 Worker |
| `backend/internal/service/system_prompt_builder.go` | Prompt 构建 |
| `backend/internal/handler/api/v1/rag_handler.go` | RAG Handler(未接入) |
| `backend/internal/handler/api/v1/rag_handler.go` | 已注册的 RAG Handler |
| `backend/internal/handler/api/v1/sse_stream_handler.go` | SSE 流式 Handler |
| `backend/internal/handler/api/v1/captain_assistant_handler.go` | 助手 Handler |
| `backend/internal/handler/api/v1/captain_task_handler_test.go` | 任务 Handler 测试 |