339 lines
18 KiB
Markdown
339 lines
18 KiB
Markdown
# 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绑定到特定Inbox(CaptainInbox关联)
|
||
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生成FAQ(AssistantResponse),再经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**: Sidekiq(crawl_job, response_builder_job, copilot_response_job)
|
||
- **实时推送**: ActionCable(CopilotMessage broadcast_message)
|
||
|
||
### 企业版限制
|
||
- 所有Captain/Copilot功能仅Enterprise版本可用
|
||
- Document数量上限(`LimitExceededError`)
|
||
- CustomTool每account上限15个
|
||
- Copilot回复有用量配额限制(`usage_limits[:captain][:responses][:current_available]`) |