Files
gochat/docs/requirements/M10-captain-and-copilot.md
T
2026-06-04 15:44:48 +08:00

339 lines
18 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.
# M10 Captain AI与Copilot 功能梳理
> 版本标注:Chatwoot Enterprise v3.13+
> 模块定位:企业版核心功能,为客服团队提供AI助手(Captain)与智能副驾驶(Copilot)能力
---
## 1. Captain::Assistant CRUD — 助手模型+控制器+路由
### 功能描述
Captain Assistant 是企业版的AI助手实体,每个Account可创建多个Assistant,分别绑定不同Inbox,提供自动回复、FAQ检索、Copilot副驾驶等能力。支持CRUD全生命周期管理及Playground在线调试。
### 用户操作流程
1. 管理员进入 Settings → Captain → Assistants
2. 创建Assistant:填写名称、描述、配置(温度、产品名、功能开关)
3. 将Assistant绑定到特定InboxCaptainInbox关联)
4. 在Playground页面输入消息测试Assistant回复效果
5. 编辑/删除Assistant
### 涉及的API端点
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/api/v1/accounts/{id}/captain/assistants` | 列表 |
| GET | `/api/v1/accounts/{id}/captain/assistants/{id}` | 详情 |
| POST | `/api/v1/accounts/{id}/captain/assistants` | 创建 |
| PATCH | `/api/v1/accounts/{id}/captain/assistants/{id}` | 更新 |
| DELETE | `/api/v1/accounts/{id}/captain/assistants/{id}` | 删除 |
| POST | `/api/v1/accounts/{id}/captain/assistants/{id}/playground` | Playground调试 |
| GET | `/api/v1/accounts/{id}/captain/assistants/tools` | 获取可用工具列表 |
| CRUD | `/api/v1/accounts/{id}/captain/assistants/{id}/inboxes` | 绑定/解绑Inbox |
### 涉及的数据模型+关键字段
- **captain_assistants** 表
- `id`, `account_id`(必填), `name`(必填), `description`(必填)
- `config` (jsonb): `temperature`, `feature_faq`, `feature_memory`, `feature_contact_attributes`, `product_name`
- `guardrails` (jsonb): 限制性规则
- `response_guidelines` (jsonb): 回复指导方针
- 关联:`documents` → Captain::Document, `responses` → Captain::AssistantResponse, `captain_inboxes` → CaptainInbox, `copilot_threads`, `scenarios`
### 涉及的业务逻辑
- Playground调试分两路:v2启用 → AgentRunnerService;否则 → AssistantChatService
- `available_agent_tools` 方法合并内置工具 + account下enabled的CustomTool
- Assistant创建后可作为消息sender`messages, as: :sender`),在对话中自动回复
### 涉及的自动化/规则/事件
- Assistant创建/删除时,通过CaptainInbox自动关联/清理Inbox
- Playground调用实时LLM生成回复
### Chatwoot原实现代码路径
- `enterprise/app/models/captain/assistant.rb`
- `enterprise/app/controllers/api/v1/accounts/captain/assistants_controller.rb`
- `config/routes.rb` → namespace :captain → resources :assistants
---
## 2. Captain::Document 知识库 — 文档上传+嵌入+搜索
### 功能描述
Document是Captain的知识来源,支持两类来源:URL网页抓取和PDF文件上传。文档创建后自动触发抓取/解析Job,内容通过LLM生成FAQAssistantResponse),再经EmbeddingService生成向量嵌入用于语义搜索。
### 用户操作流程
1. 管理员在Assistant详情页上传知识文档(URL或PDF)
2. 系统自动抓取/解析内容,状态从 in_progress → available
3. LLM自动从文档内容生成FAQ对(AssistantResponse),并计算嵌入向量
4. 文档可手动触发重新同步(sync
5. 在对话/Copilot中通过SearchDocumentationService语义检索
### 涉及的API端点
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/api/v1/accounts/{id}/captain/documents` | 列表(支持过滤/搜索/分页) |
| GET | `/api/v1/accounts/{id}/captain/documents/{id}` | 详情 |
| POST | `/api/v1/accounts/{id}/captain/documents` | 创建(URL或PDF |
| DELETE | `/api/v1/accounts/{id}/captain/documents/{id}` | 删除 |
| POST | `/api/v1/accounts/{id}/captain/documents/{id}/sync` | 手动重新同步 |
### 涉及的数据模型+关键字段
- **captain_documents** 表
- `id`, `account_id`(必填), `assistant_id`(必填)
- `external_link`(必填,URL来源), `name`, `content`(最大200K)
- `status`: in_progress(0) / available(1)
- `sync_status`: syncing(0) / synced(1) / failed(2)
- `metadata` (jsonb): `content_fingerprint`, `last_sync_error_code`, `sync_step`, `openai_file_id`
- `content_fingerprint` (string): 内容哈希,用于判断是否需要重新生成FAQ
- `pdf_file`: ActiveStorage附件(PDF类型文档)
- 关联:`responses` → Captain::AssistantResponse (as: documentable), `assistant` → Captain::Assistant
### 涉及的业务逻辑
- 创建后自动触发 `enqueue_crawl_job`URL用FirecrawlService/SimplePageCrawlService抓取)
- PDF文档用 `PdfProcessingService` 解析
- 内容变更后通过 `enqueue_response_builder_job` → FaqGeneratorService 生成FAQ
- FAQ生成后由 `EmbeddingService` 调用RubyLLM计算向量嵌入
- 搜索时先 `TranslateQueryService` 将查询翻译为目标语言,再在approved responses中语义搜索
- 文档数量有上限限制(`LimitExceededError`
### 涉及的自动化/规则/事件
- `after_create_commit :enqueue_crawl_job` — 自动抓取
- `after_create_commit :update_document_usage` — 更新用量统计
- `after_commit :enqueue_response_builder_job` — 自动生成FAQ+嵌入
- `after_destroy :update_document_usage` — 删除后更新用量
- 同步超时阈值:`SYNC_STALE_TIMEOUT = 2.hours`
### Chatwoot原实现代码路径
- `enterprise/app/models/captain/document.rb`
- `enterprise/app/controllers/api/v1/accounts/captain/documents_controller.rb`
- `enterprise/app/services/captain/documents/sync_service.rb`
- `enterprise/app/services/captain/documents/single_page_fetcher.rb`
- `enterprise/app/services/captain/llm/embedding_service.rb`
- `enterprise/app/services/captain/llm/faq_generator_service.rb`
---
## 3. Captain::Llm 聊天服务 — AssistantChatService+OpenAI集成
### 功能描述
AssistantChatService是Captain核心LLM对话引擎,继承BaseAiService,负责构建system prompt + 历史消息 + 工具调用链,与OpenAI(通过RubyLLM)交互生成回复。支持工具调用(function calling)循环直到获得最终文本回复。
### 用户操作流程
1. 用户在Inbox对话中发送消息
2. 系统判定需要Captain回复(通过AssistantActionClassifierService判断动作类型)
3. AssistantChatService构建消息序列:system prompt + 历史 + 用户消息 + 工具定义
4. LLM返回回复,可能包含工具调用(如search_documentation
5. 工具执行后结果回填消息序列,再次调用LLM
6. 最终文本回复发送到对话
### 涉及的API端点
间接调用,主要通过 `POST /api/v1/accounts/{id}/captain/assistants/{id}/playground` 触发
### 涉及的数据模型+关键字段
- 依赖 `Captain::Assistant`config, guardrails, response_guidelines
- 依赖 `Captain::AssistantResponse`FAQ知识对,嵌入向量)
- 依赖 `Captain::CustomTool`(自定义HTTP工具)
### 涉及的业务逻辑
- **System Prompt构建**:由 `SystemPromptsService.assistant_response_generator` 生成,包含产品名、回复指导方针、护栏规则
- **工具构建** (`build_tools`):内置 SearchDocumentationService + account下enabled的CustomTool(→ CustomHttpTool
- **对话循环**`request_chat_completion` → 若返回tool_call → 执行tool → 回填结果 → 再请求 → 直到文本回复
- **消息格式**`generate_response(additional_message:, message_history:, role:)` 拼接历史+新消息
- 继承 `Llm::BaseAiService` 使用RubyLLM与OpenAI通信
- 包含 `Captain::ChatHelper` 模块(共享辅助方法)
### 涉及的自动化/规则/事件
- Assistant自动回复触发:当Inbox配置了Captain Assistant且用户消息到达
- ActionClassifierService判断是否需要AI回复 vs 转人工
- 工具调用循环由RubyLLM的function calling机制驱动
### Chatwoot原实现代码路径
- `enterprise/app/services/captain/llm/assistant_chat_service.rb`
- `enterprise/app/services/captain/llm/system_prompts_service.rb`
- `enterprise/app/services/captain/llm/assistant_action_classifier_service.rb`
- `enterprise/app/services/captain/open_ai_message_builder_service.rb`
- `app/services/llm/base_ai_service.rb`
---
## 4. Captain::Tools 工具注册 — SearchDocumentationService+BaseTool+CustomTool
### 功能描述
Captain工具系统为LLM提供function calling能力。BaseTool是所有工具的基类(继承RubyLLM::Tool),SearchDocumentationService是内置核心工具(语义搜索知识库),CustomTool允许企业自定义HTTP API工具。ToolRegistryService负责注册和管理工具集合。
### 用户操作流程
1. 系统自动注册内置工具(search_documentation
2. 管理员可在 Settings → Captain → Custom Tools 创建自定义HTTP工具
3. 自定义工具配置:名称、描述、HTTP方法、端点URL、参数Schema、认证方式(none/bearer/basic/api_key
4. 工具在Assistant对话/Copilot对话中被LLM自动调用
### 涉及的API端点
| 方法 | 路径 | 说明 |
|------|------|------|
| CRUD | `/api/v1/accounts/{id}/captain/custom_tools` | 自定义工具管理 |
| POST | `/api/v1/accounts/{id}/captain/custom_tools/test` | 测试自定义工具 |
### 涉及的数据模型+关键字段
- **Captain::Tools::BaseTool** (非DB模型,继承RubyLLM::Tool)
- `assistant`, `@user` 属性
- `active?` 方法(默认true
- `user_has_permission(permission)` 权限检查
- prepend `Captain::Tools::Instrumentation`(监控埋点)
- **captain_custom_tools** 表
- `id`, `account_id`, `slug`(唯一), `title`, `description`
- `endpoint_url`, `http_method`(GET/POST), `auth_type`(none/bearer/basic/api_key)
- `auth_config` (jsonb), `param_schema` (jsonb), `request_template`, `response_template`
- `enabled`(bool, 默认true)
- 每account上限15个(`MAX_PER_ACCOUNT = 15`
### 涉及的业务逻辑
- **SearchDocumentationService**:接收query参数 → TranslateQueryService翻译 → 在assistant.responses.approved中语义搜索 → 格式化返回FAQ+来源链接
- **CustomHttpTool**:将CustomTool配置转为LLM可调用的工具定义 → LLM触发时执行HTTP请求 → 按response_template格式化结果
- **ToolRegistryService**`register_tool(tool_class)` → 检查active? → 存入@tools字典 → 支持 `method_missing` 动态调用
- 工具名slug有64字符限制(OpenAI function name限制)
### 涉及的自动化/规则/事件
- CustomTool创建前自动生成slug`before_validation :generate_slug`
- CustomTool创建前检查数量上限(`before_create :ensure_within_limit`
- Instrumentation模块自动记录工具调用监控数据
### Chatwoot原实现代码路径
- `enterprise/app/services/captain/tools/base_tool.rb`
- `enterprise/app/services/captain/tools/search_documentation_service.rb`
- `enterprise/app/services/captain/tools/custom_http_tool.rb`
- `enterprise/app/services/captain/tool_registry_service.rb`
- `enterprise/app/services/captain/tools/instrumentation.rb`
- `enterprise/app/models/captain/custom_tool.rb`
---
## 5. Copilot对话 — CopilotMessage+CopilotThread+ChatService
### 功能描述
Copilot是面向客服代理(Agent)的AI副驾驶,在侧边栏提供实时对话辅助。每个代理拥有独立的CopilotThread(对话线程),消息通过CopilotMessage记录,ChatService构建含上下文(当前查看对话、历史消息)+ 多工具的LLM请求。
### 用户操作流程
1. Agent在对话详情页点击Copilot侧边栏
2. 创建新Thread或继续已有Thread
3. 输入问题(如"如何处理这个客户?")
4. Copilot根据当前查看的对话上下文+知识库搜索给出建议
5. 可在Thread中持续追问
### 涉及的API端点
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/api/v1/accounts/{id}/captain/copilot_threads` | Thread列表(仅当前用户) |
| POST | `/api/v1/accounts/{id}/captain/copilot_threads` | 创建Thread+首条消息 |
| GET | `/api/v1/accounts/{id}/captain/copilot_threads/{id}/copilot_messages` | 消息列表 |
| POST | `/api/v1/accounts/{id}/captain/copilot_threads/{id}/copilot_messages` | 发送消息 |
### 涉及的数据模型+关键字段
- **copilot_threads** 表
- `id`, `account_id`(必填), `user_id`(必填), `assistant_id`(可关联Assistant)
- `title`(必填,默认为首条消息内容)
- **copilot_messages** 表
- `id`, `copilot_thread_id`(必填), `account_id`
- `message` (jsonb, 必填): `{ content: "..." }`
- `message_type`: user(0) / assistant(1) / assistant_thinking(2)
### 涉及的业务逻辑
- **Thread创建**CopilotThreadsController.create 事务中同时创建Thread + 首条user消息 → enqueue_response_job
- **消息创建**CopilotMessagesController.create 创建user消息 → `enqueue_response_job` 触发Copilot::ResponseJob
- **ResponseJob** → 调用 `Captain::Copilot::ChatService.generate_response`
- **ChatService构建**
- system_message: `SystemPromptsService.copilot_response_generator`(含产品名+工具摘要)
- account_id_context: 注入当前account信息
- previous_history: 从copilot_thread.previous_history加载
- current_viewing_history: 如果有conversation_id,注入当前对话内容作为上下文
- **工具集**SearchDocumentation + Copilot专用工具(GetConversation, SearchConversations, GetContact, GetArticle, SearchArticles, SearchContacts, SearchLinearIssues
- 回复生成后 `account.increment_response_usage` 计量
### 涉及的自动化/规则/事件
- `after_create_commit :broadcast_message` — 消息创建后通过ActionCable实时推送
- CopilotMessage创建 → `enqueue_response_job` → ResponseJob异步执行
- Thread创建时检查用量限制(`usage_limits[:captain][:responses][:current_available]`
- 用量耗尽时返回限制提示消息而非AI回复
### Chatwoot原实现代码路径
- `enterprise/app/models/copilot_thread.rb`
- `enterprise/app/models/copilot_message.rb`
- `enterprise/app/controllers/api/v1/accounts/captain/copilot_threads_controller.rb`
- `enterprise/app/controllers/api/v1/accounts/captain/copilot_messages_controller.rb`
- `enterprise/app/services/captain/copilot/chat_service.rb`
- `enterprise/app/services/captain/tools/copilot/` (7个专用工具)
---
## 6. Copilot建议 — 建议生成+嵌入搜索+对话上下文
### 功能描述
Copilot建议功能允许Agent在查看对话时一键获取AI生成的回复建议。系统基于当前对话上下文 + 知识库语义搜索 + 对话历史,自动生成针对客户问题的建议回复,Agent可直接采纳或修改后发送。
### 用户操作流程
1. Agent打开一个对话,看到客户消息
2. 点击Copilot侧边栏或"建议回复"按钮
3. 系统自动基于对话上下文生成建议
4. Agent选择采纳建议,或在此基础上编辑后发送
### 涉及的API端点
| 方法 | 路径 | 说明 |
|------|------|------|
| POST | `/api/v1/accounts/{id}/captain/tasks/reply_suggestion` | 生成回复建议 |
| POST | `/api/v1/accounts/{id}/captain/tasks/summarize` | 对话摘要 |
| POST | `/api/v1/accounts/{id}/captain/tasks/rewrite` | 重写回复 |
### 涉及的数据模型+关键字段
- 复用 `Captain::Assistant`, `Captain::AssistantResponse`(嵌入向量)
- 复用 `CopilotThread`, `CopilotMessage`
- Tasks控制器处理独立建议任务(不走Thread流程)
### 涉及的业务逻辑
- **回复建议生成**:基于当前对话最后几条消息 + SearchDocumentationService搜索相关FAQ → 构建prompt → LLM生成建议回复
- **对话摘要**:提取对话内容 → LLM压缩为关键信息摘要
- **回复重写**:Agent输入草稿 → LLM润色优化语气/格式
- **上下文注入**`current_viewing_history(conversation_id)` 将当前对话消息注入system context
- **Copilot工具**提供对话/联系人/文章/工单检索能力,使建议基于真实数据
### 涉及的自动化/规则/事件
- 建议生成异步执行(通过Captain::Copilot::ResponseJob
- 回复建议可配置自动触发或手动触发
- 用量限制检查:每次建议生成消耗response_usage
### Chatwoot原实现代码路径
- `enterprise/app/controllers/api/v1/accounts/captain/tasks_controller.rb`
- `enterprise/app/services/captain/copilot/chat_service.rb`
- `enterprise/app/services/captain/tools/copilot/` (7个上下文检索工具)
- `enterprise/app/services/captain/llm/search_reply_documentation_service.rb`
---
## 交叉依赖与架构总览
```
Captain::Assistant (核心实体)
├── Captain::Document (知识库)
│ ├── EmbeddingService (向量嵌入)
│ ├── FaqGeneratorService (FAQ自动生成)
│ └── AssistantResponse (FAQ对 + 向量)
├── Captain::CustomTool (自定义HTTP工具)
├── Captain::Llm::AssistantChatService (对话引擎)
│ ├── SystemPromptsService (prompt构建)
│ ├── Tools: SearchDocumentationService + CustomHttpTool
│ └── BaseAiService → RubyLLM → OpenAI
└── Copilot (副驾驶)
├── CopilotThread + CopilotMessage (对话线程)
├── Captain::Copilot::ChatService (专用引擎)
│ ├── 7个Copilot专用工具
│ └─ current_viewing_history (对话上下文注入)
└── Tasks (独立建议:reply_suggestion/summarize/rewrite)
```
### 关键技术选型
- **LLM SDK**: RubyLLM(统一OpenAI/其他Provider接口)
- **嵌入模型**: 可配置(`CAPTAIN_EMBEDDING_MODEL`),默认`LlmConstants::DEFAULT_EMBEDDING_MODEL`
- **向量搜索**: 基于AssistantResponse的嵌入向量,通过pgvector或类似机制语义检索
- **异步Job**: Sidekiqcrawl_job, response_builder_job, copilot_response_job
- **实时推送**: ActionCableCopilotMessage broadcast_message
### 企业版限制
- 所有Captain/Copilot功能仅Enterprise版本可用
- Document数量上限(`LimitExceededError`
- CustomTool每account上限15个
- Copilot回复有用量配额限制(`usage_limits[:captain][:responses][:current_available]`