清理: - 删除 34 份过时文档(gap reports/QA临时报告/验收报告/阶段性文档) - 删除 docs/.hermes/skills 第三方 skills 副本(16 文件) - 删除 skills-lock.json 目录归集: - 根目录仅保留 README.md 索引 - product/ — 产品与架构设计(PRD + ARCHITECTURE + P2设计文档 + AI/企业路线图) - tracking/ — Chatwoot parity 开发跟踪 - requirements/ — M01-M12 模块需求 - plans/ — 历史实现计划 - parity/ — 路由 parity 与前端契约 - qa/ — QA 报告与测试计划 - ops/ — 运维部署 命名规范: - 全小写 kebab-case,禁止全大写文件名 - product/tracking/ops 用 NN- 序号前缀 - requirements 用 MNN- 两位零填充模块号 - plans/qa 用 YYYY-MM-DD- 日期前缀 - requirements M1-M9 零填充为 M01-M09(修复字典序) 同步更新: - backend/cmd/route_parity/main.go 路径默认值 - backend/scripts/parity_frontend_smoke.sh 报告路径 - 所有 docs 内部交叉引用 - .gitignore 排除编译产物 (backend/gochat, backend/route_parity) - 新增迁移 000052/000053 - 前端 WS 相关修改
27 KiB
M9: 知识库与帮助中心(Portal / Category / Article / Help Center / Kbase Search)
参照仓库:chatwoot-reference
产出日期:2026-05-22
版本基准:Chatwoot v3.x
目录
- Portal CRUD + 设置 + Logo + 自定义域名
- Category / Folder 管理
- Article CRUD + 关联文章 + 排序 + 搜索
- RelatedCategory 关联分类
- Help Center 前端展示(Portal布局/SEO/追踪像素)
- Kbase 文本搜索(PgSearch)
- Article Embedding 向量搜索(企业版)
- Article 批量操作(状态/删除/翻译)
- 权限策略(PortalPolicy / ArticlePolicy / CategoryPolicy)
- AI辅助:Help Center 策展 + Article Writer(企业版)
1. Portal CRUD + 设置 + Logo + 自定义域名
功能描述
Portal 是帮助中心的顶层容器,每个 Portal 属于一个 Account,可绑定一个 WebWidget 渠道用于在线聊天。Portal 拥有完整的配置体系:名称、slug(唯一标识)、自定义域名、品牌颜色、header 文字、首页链接、布局模式(classic/documentation)、多语言设置、社交链接、SSL 配置等。
用户操作流程
- 创建 Portal:管理员进入 Settings → Help Center → 点击 "Create Portal",填写名称、slug、颜色、布局、默认语言等;系统自动创建 Portal,可选绑定 WebWidget 渠道
- 查看 Portal 列表:按账户加载所有 Portal(含 logo、archived 状态等)
- 更新 Portal 设置:修改名称、header_text、homepage_link、custom_domain、颜色、布局、多语言配置(allowed_locales/default_locale/draft_locales)、社交链接等
- 删除 Portal:级联删除 Categories、Articles、Folders、Inbox 关联(nullify)
- 归档 Portal:将 Portal 标记为 archived(archived=true),归档后前端不展示
- 上传/移除 Logo:Portal 支持品牌 Logo(ActiveStorage attachment),创建/更新时传入 blob_id
- 发送 DNS 配置邮件:为自定义域名发送 DNS 设置指引邮件(send_instructions),接收方按邮件指引配置 CNAME
- 查看 SSL 状态:检查自定义域名的 SSL 证书状态
涉及的API端点
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/v1/accounts/{account_id}/portals |
列出所有 Portal |
| POST | /api/v1/accounts/{account_id}/portals |
创建 Portal |
| GET | /api/v1/accounts/{account_id}/portals/{id} |
查看 Portal 详情(含 articles) |
| PATCH | /api/v1/accounts/{account_id}/portals/{id} |
更新 Portal 设置 |
| DELETE | /api/v1/accounts/{account_id}/portals/{id} |
删除 Portal |
| PATCH | /api/v1/accounts/{account_id}/portals/{id}/archive |
归档 Portal |
| DELETE | /api/v1/accounts/{account_id}/portals/{id}/logo |
移除 Logo |
| POST | /api/v1/accounts/{account_id}/portals/{id}/send_instructions |
发送 DNS 配置邮件 |
| GET | /api/v1/accounts/{account_id}/portals/{id}/ssl_status |
查看 SSL 状态 |
涉及的数据模型 + 关键字段
-
Portal 模型(表
portals):id(bigint, PK)name(string, not null) — 帮助中心名称slug(string, not null, unique) — 唯一标识,用于 URL 路径archived(boolean, default false) — 归档标记color(string) — 品牌主题色,默认#1f93ffheader_text(text) — 头部文案homepage_link(string) — 首页链接page_title(string) — SEO 页面标题custom_domain(string, unique) — 自定义域名config(jsonb) — 配置 JSON:{ allowed_locales, default_locale, draft_locales, layout, social_profiles }ssl_settings(jsonb, not null) — SSL 证书配置account_id(integer, not null, FK) — 所属账户channel_web_widget_id(bigint, FK) — 关联的 WebWidget 渠道(可选,用于嵌入在线聊天)created_at,updated_at
-
关联:
has_many :categories, dependent: :destroy_asynchas_many :folders, through: :categorieshas_many :articles, dependent: :destroy_asynchas_one_attached :logo— ActiveStorage Logohas_many :inboxes, dependent: :nullify— Inbox 可关联 Portalbelongs_to :channel_web_widget— 可选绑定在线聊天
-
关键方法:
default_locale— 从 config 中读取默认语言allowed_locale_codes— 返回 Portal 支持的语言列表public_locale_codes— 已发布文章可见语言(排除 draft_locale)layout— 返回布局模式(classic / documentation)social_profiles— 社交链接配置config_json_format— before_validation 回调,将 config 规范化(确保 locale 列表有效)
涉及的业务逻辑
PortalsController#create— 构建 Portal + 合并 live_chat_widget_params(可选创建 WebWidget 渠道)PortalsController#update— 事务更新 Portal + 处理 Logo attachmentPortalsController#archive— 设置archived=truePortalsController#send_instructions— 验证邮箱格式后发送 DNS 配置邮件PortalsController#show— 加载 Portal 及其 articles(可按 locale 搜索)Portal#validate_slug_uniqueness— slug 全局唯一校验Portal#normalize_empty_string_to_nil— 将 custom_domain/homepage_link 空字符串转为 nil
2. Category / Folder 管理
功能描述
Category(分类)是 Portal 下的内容组织单元,支持层级结构(parent_category / sub_categories)和多语言。每个 Category 属于一个 Portal 和一种 locale。Folder(文件夹)是 Category 内的进一步分组,Article 可以归属于 Folder。
用户操作流程
- 创建 Category:在 Portal 管理页面选择 "Add Category",填写名称、描述、图标、locale、父分类(可选);同时可指定关联分类(related_category_ids)
- 查看 Category 列表:按 Portal + locale 加载分类列表,按 position 排序
- 更新 Category:修改名称、描述、图标、关联分类等
- 删除 Category:级联删除 Folders,Articles 的 category_id 被设为 NULL
- 排序 Category:通过 reorder 接口批量更新 position
涉及的API端点
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/v1/accounts/{account_id}/portals/{portal_id}/categories |
列出分类(可按 locale 过滤) |
| POST | /api/v1/accounts/{account_id}/portals/{portal_id}/categories |
创建分类 |
| GET | /api/v1/accounts/{account_id}/portals/{portal_id}/categories/{id} |
查看分类详情 |
| PATCH | /api/v1/accounts/{account_id}/portals/{portal_id}/categories/{id} |
更新分类 |
| DELETE | /api/v1/accounts/{account_id}/portals/{portal_id}/categories/{id} |
删除分类 |
| POST | /api/v1/accounts/{account_id}/portals/{portal_id}/categories/reorder |
批量排序 |
涉及的数据模型 + 关键字段
-
Category 模型(表
categories):id(bigint, PK)name(string) — 分类名称description(text) — 分类描述icon(string, default "") — 图标标识locale(string, default "en") — 语言slug(string, not null) — URL slugposition(integer) — 排序位置account_id(integer, not null, FK)portal_id(integer, not null, FK)parent_category_id(bigint, FK) — 父分类 ID(层级结构)associated_category_id(bigint, FK) — 关联分类 ID(跨语言关联)
-
索引:
(slug, locale, portal_id)联合唯一索引 -
关联:
has_many :folders, dependent: :destroy_asynchas_many :articles, dependent: :nullifyhas_many :category_related_categories (RelatedCategory), dependent: :destroy_asynchas_many :related_categories (Category), through: :category_related_categorieshas_many :sub_categories (Category), foreign_key: :parent_category_idbelongs_to :parent_category (Category), optional: truebelongs_to :associated_category (Category), optional: true— 同内容的另一种语言版本belongs_to :portal
-
Folder 模型(表
folders):id(bigint, PK)name(string) — 文件夹名称account_id(integer, not null, FK)category_id(integer, not null, FK)- 关联:
has_many :articles, dependent: :nullify
-
关键方法:
Category.search(params)— 按 locale 过滤 + 分页 + position 排序Category.update_positions(portal, positions_hash)— 批量更新 position- Category 创建时自动从 Portal 继承
account_id - Category 校验
locale必须在 Portal 的allowed_locales范围内 (slug, locale, portal_id)联合唯一约束
3. Article CRUD + 关联文章 + 排序 + 搜索
功能描述
Article(文章)是帮助中心的核心内容单元,属于 Portal + Category(可选 Folder),支持草稿/发布/归档三种状态。文章可关联"根文章"(associated_article_id)实现多语言翻译链接,支持全文搜索(PgSearch)、排序、浏览量统计。
用户操作流程
- 创建 Article:在 Portal 管理页面选择 "Add Article",填写标题、内容、描述、locale、作者、分类;默认状态为 draft;可选择关联已有文章(associated_article_id)
- 查看 Article 列表:按 Portal + 可选 category_slug/locale/author/status 过滤,支持全文搜索(query),有分类时按 position 排序,否则按 updated_at 排序
- 查看 Article 详情:获取单篇文章完整内容
- 编辑 Article:获取编辑数据(edit 接口)
- 更新 Article:修改标题、内容、状态、分类等
- 删除 Article:删除单篇文章
- 排序 Articles:通过 reorder 接口批量更新 position
- 查看浏览量:Article.views 字段,每次公开页面访问时通过 tracking pixel 增量
涉及的API端点
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/v1/accounts/{account_id}/portals/{portal_id}/articles |
列出文章(支持搜索+过滤) |
| POST | /api/v1/accounts/{account_id}/portals/{portal_id}/articles |
创建文章 |
| GET | /api/v1/accounts/{account_id}/portals/{portal_id}/articles/{id} |
查看文章详情 |
| GET | /api/v1/accounts/{account_id}/portals/{portal_id}/articles/{id}/edit |
编辑数据 |
| PATCH | /api/v1/accounts/{account_id}/portals/{portal_id}/articles/{id} |
更新文章 |
| DELETE | /api/v1/accounts/{account_id}/portals/{portal_id}/articles/{id} |
删除文章 |
| POST | /api/v1/accounts/{account_id}/portals/{portal_id}/articles/reorder |
批量排序 |
涉及的数据模型 + 关键字段
-
Article 模型(表
articles):id(bigint, PK)title(string) — 标题content(text) — 正文内容description(text) — 简短描述(用于列表展示+搜索权重B)locale(string, default "en", not null) — 语言slug(string, not null, unique) — URL slugstatus(integer) — 状态枚举:draft(0), published(1), archived(2)position(integer) — 排序位置views(integer) — 浏览次数meta(jsonb) — 元数据 JSONaccount_id(integer, not null, FK)portal_id(integer, not null, FK)category_id(integer, FK) — 所属分类(可选)folder_id(integer, FK) — 所属文件夹(可选)author_id(bigint, FK) — 作者(User)associated_article_id(bigint, FK) — 根文章 ID(多语言关联)
-
关联:
has_many :associated_articles (Article), foreign_key: :associated_article_id, dependent: :nullifybelongs_to :root_article (Article), foreign_key: :associated_article_idbelongs_to :category, optional: truebelongs_to :folder, optional: truebelongs_to :portalbelongs_to :author (User)
-
搜索 scope:
search_by_category_slug,search_by_category_locale,search_by_locale,search_by_author,search_by_statusorder_by_updated_at,order_by_position,order_by_viewspg_search_scope :text_search— 全文搜索(title:A, description:B, content:C),tsearch prefix 模式
-
关键方法:
Article.search(params)— 组合过滤 + 全文搜索Article.associate_root_article(associated_article_id)— 建立多语言关联链Article.find_root_article_id(article)— 查找根文章 IDArticle.update_positions(portal, positions_hash)— 批量排序Article#increment_view_count— 浏览量 +1(跳过 validation)before_validation钩子:确保 account_id、slug、locale 自动填充
涉及的业务逻辑
ArticlesController#index— 先计算统计数(all_count、mine_count、published_count、draft_count),再执行搜索 + 分页ArticlesController#create— 默认 status=draft,创建后调用associate_root_articleArticlesController#set_article_count— 不含 status/author_id 的搜索计算各种状态文章数
4. RelatedCategory 关联分类
功能描述
RelatedCategory 是分类之间的关联关系表,用于在帮助中心展示"相关分类"推荐。这是一种多对多关系:一个 Category 可以关联多个其他 Category(通过 RelatedCategory 中间表)。
用户操作流程
- 创建/更新 Category 时指定关联分类:在 category 参数中传入
related_category_ids数组 - 前端展示相关分类:在分类详情页面展示关联的其他分类
涉及的API端点
同 Category CRUD(通过 related_category_ids 参数)
涉及的数据模型 + 关键字段
- RelatedCategory 模型(表
related_categories):id(bigint, PK)category_id(bigint, FK) — 源分类related_category_id(bigint, FK) — 关联分类created_at,updated_at
- 索引:
(category_id, related_category_id)和(related_category_id, category_id)双向唯一索引 - 关联:
belongs_to :related_category (Category)belongs_to :category (Category)
- Category 中:
has_many :category_related_categories (RelatedCategory), dependent: :destroy_asynchas_many :related_categories (Category), through: :category_related_categories
5. Help Center 前端展示(Portal布局/SEO/追踪像素)
功能描述
帮助中心有公开的 Portal 前端,通过 /hc/{slug}/{locale} 系列路由对外展示。支持两种布局模式(classic / documentation),支持 SEO(OG 图片、sitemap)、自定义域名、暗/亮主题切换、iframe 嵌入、追踪像素(tracking pixel)统计浏览量。
用户操作流程
- 访问帮助中心首页:
/hc/{slug}自动重定向到/hc/{slug}/{default_locale},加载 Portal 配置、分类、热门文章、精选文章 - 浏览分类页:
/hc/{slug}/{locale}/categories/{category_slug},展示分类下的已发布文章 - 阅读文章:
/hc/{slug}/articles/{article_slug},渲染文章内容、OG SEO 信息 - 搜索文章:
/hc/{slug}/{locale}/articles?query=xxx,前端搜索+排序+分页 - Markdown 输出:
/hc/{slug}/articles/{article_slug}.md,纯 Markdown 格式(供 AI/工具调用) - Tracking Pixel:
/hc/{slug}/articles/{article_slug}.png,1x1 像素追踪浏览量(24h private cache) - Sitemap:
/hc/{slug}/sitemap.xml,SEO 爬虫用 - 自定义域名:Portal 配置 custom_domain 后,DNS CNAME 指向 Chatwoot,SSL 自动配置
涉及的API端点(Public)
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /hc/{slug} |
Portal 首页(重定向到 locale 版) |
| GET | /hc/{slug}/sitemap.xml |
Sitemap |
| GET | /hc/{slug}/{locale} |
Portal 首页(指定语言) |
| GET | /hc/{slug}/{locale}/articles |
文章搜索列表 |
| GET | /hc/{slug}/{locale}/categories |
分类列表(JSON) |
| GET | /hc/{slug}/{locale}/categories/{category_slug} |
分类详情+文章 |
| GET | /hc/{slug}/{locale}/categories/{category_slug}/articles |
分类下文章 |
| GET | /hc/{slug}/articles/{article_slug} |
文章详情页 |
| GET | /hc/{slug}/articles/{article_slug}.md |
Markdown 输出 |
| GET | /hc/{slug}/articles/{article_slug}.png |
Tracking Pixel |
涉及的业务逻辑
-
Public::Api::V1::PortalsController:
show— 加载 Portal + 文章 + 分类,按 locale 过滤load_home_data(documentation 布局)— 加载 visible_categories、popular_topics、featured articles、recently_articles- 自定义域名验证:
ensure_custom_domain_request - 布局选择:
set_portal_layout(classic/documentation) - 视图变体:
set_view_variant(documentation 布局使用 :documentation variant)
-
Public::Api::V1::Portals::CategoriesController:
index— HTML 重定向到 locale 版,JSON 返回分类列表show— 加载分类详情 + 已发布文章(documentation 布局)
-
Public::Api::V1::Portals::ArticlesController:
index— 搜索 + 排序(sort: newest/popular) + 限制结果数show— 渲染文章内容(OG 图片)show_markdown— 纯 Markdown 输出(仅已发布文章)tracking_pixel— 增加浏览量 + 返回 1x1 PNG(24h private cache)
-
Public::Api::V1::Portals::BaseController:
PORTAL_LAYOUTS = %w[classic documentation]- Locale 切换:
switch_locale_with_portal/switch_locale_with_article - 主题:dark/light 通过 params[:theme]
- iframe 允许:
allow_iframe_requests - 功能开关:
ensure_portal_feature_enabled
6. Kbase 文本搜索(PgSearch)
功能描述
Article 模型使用 PgSearch(PostgreSQL 全文搜索)实现知识库文本搜索。搜索权重:标题(A)> 描述(B)> 正文(C),使用 tsearch prefix 模式(支持前缀匹配),normalization=2 防止长文堆叠关键词。
用户操作流程
- 管理端搜索:在 Portal 管理页面的文章列表中输入搜索词(query 参数),结合 category_slug/locale/author/status 过滤
- 公众端搜索:在帮助中心前端搜索框输入关键词,搜索已发布文章
搜索实现细节
-
pg_search_scope :text_search:
against: { title: 'A', description: 'B', content: 'C' }— 权重分级using: { tsearch: { prefix: true, normalization: 2 } }— 前缀匹配 + log(document_length) 归一化ranked_by: ':tsearch'
-
Article.search(params):
- 先 left_outer_joins(:category) + 各种 scope 过滤
- 再
text_search(params[:query])如果 query 存在 - 返回结果集
-
公众端搜索:
Public::Api::V1::Portals::ArticlesController#index- 仅搜索已发布文章(
published状态) - 支持 sort 参数(newest/popular)
- 企业版覆盖
search_articles→ 使用向量搜索(见下节)
7. Article Embedding 向量搜索(企业版)
功能描述
企业版提供基于向量嵌入(Embedding)的语义搜索功能。当文章标题/描述/内容变更时,自动生成 embedding 向量存入 article_embeddings 表(使用 pgvector 扩展,1536维 cosine 距离)。公众端搜索时可使用向量搜索替代文本搜索,返回语义最相关的5篇文章。
用户操作流程
- 自动嵌入生成:文章保存后自动触发
Portal::ArticleIndexingJob→ 生成搜索词 →Captain::Llm::EmbeddingService调用 LLM API 生成向量 → 存入article_embeddings - 向量搜索:公众端搜索时,若 Portal 账户开启了
help_center_embedding_search功能开关,使用vector_search替代文本搜索
涉及的数据模型 + 关键字段
- ArticleEmbedding 模型(表
article_embeddings):id(bigint, PK)embedding(vector(1536)) — 向量数据(pgvector 扩展)term(text, not null) — 搜索词文本article_id(bigint, not null, FK)created_at,updated_at
- 索引:
ivfflat索引(向量近似搜索) - 关联:
belongs_to :articlehas_neighbors :embedding, normalize: true— Neighbor 模式(cosine 距离)
涉及的业务逻辑
-
Enterprise::Concerns::Article(prepend 到 Article 模型):
after_save :add_article_embedding— 当 title/description/content 变更时触发self.vector_search(params):- 调用
Captain::Llm::EmbeddingService将 query 生成向量 - 在已过滤文章范围内,使用
ArticleEmbedding.nearest_neighbors(:embedding, embedding, distance: 'cosine').limit(5)找最近的5篇 - 返回匹配文章
- 调用
-
Enterprise::Public::Api::V1::Portals::ArticlesController(prepend):
search_articles覆盖:若help_center_embedding_search开关开启且有 query,使用vector_search;否则走原始文本搜索
-
Portal::ArticleIndexingJob:
perform(article)→ 调用article.generate_and_save_article_seach_terms生成搜索词
-
ArticleEmbedding#update_response_embedding(after_commit):
- 当 term 变更或 embedding 为 nil 时,调用
Captain::Llm::UpdateEmbeddingJob重新生成向量
- 当 term 变更或 embedding 为 nil 时,调用
8. Article 批量操作(状态/删除/翻译)
功能描述
提供文章的批量操作能力:批量修改状态(draft/published/archived)、批量删除、批量翻译(企业版,调用 Captain LLM 翻译服务)。
用户操作流程
- 批量修改状态:在文章列表选中多篇文章,选择目标状态(draft/published/archived),调用
update_status - 批量删除:选中多篇文章,调用
delete_articles - 批量翻译(企业版):选中多篇文章 + 目标 locale + 目标分类,调用
translate;系统检查是否已存在翻译(若有则返回冲突提示,可 force 覆盖),然后异步执行Captain::Articles::TranslateJob
涉及的API端点
| 方法 | 路径 | 说明 |
|---|---|---|
| PATCH | /api/v1/accounts/{account_id}/portals/{portal_id}/articles/bulk_actions/update_status |
批量修改状态 |
| DELETE | /api/v1/accounts/{account_id}/portals/{portal_id}/articles/bulk_actions/delete_articles |
批量删除 |
| POST | /api/v1/accounts/{account_id}/portals/{portal_id}/articles/bulk_actions/translate |
批量翻译(企业版) |
涉及的业务逻辑
-
BulkActionsController(核心版):
update_status— 验证状态有效性,事务更新所有选中文章delete_articles— 批量 destroy_alltranslate— 基础版返回not_implemented
-
Enterprise::BulkActionsController(prepend):
translate覆盖实现:- 验证 captain_tasks 功能开关
- 验证 locale 在 Portal allowed_locales 中
- 验证目标分类存在且 locale 匹配
- 检查翻译是否已存在(
find_existing_translations),若有返回 409 conflict(含重复文章列表),可 force=true 覆盖 - 为每篇文章异步执行
Captain::Articles::TranslateJob
-
Captain::Articles::TranslateJob:
- 调用
Captain::Llm::ArticleTranslationService分别翻译标题和内容 - 若已有翻译则更新,否则创建新文章(关联到根文章)
- 调用
9. 权限策略(PortalPolicy / ArticlePolicy / CategoryPolicy)
功能描述
知识库相关资源的权限策略:基础版仅管理员可操作(CRUD),普通账户成员可查看(index/show)。企业版扩展了自定义角色权限 knowledge_base_manage。
涉及的权限策略
-
PortalPolicy:
index?/show?/ssl_status?→ 账户成员即可create?/update?/destroy?/edit?/logo?/send_instructions?→ 仅管理员
-
CategoryPolicy:
index?→ 账户成员create?/update?/destroy?/show?/edit?/reorder?→ 仅管理员
-
ArticlePolicy:
index?→ 账户成员create?/update?/destroy?/show?/edit?/reorder?→ 仅管理员
-
Enterprise::ArticlePolicy(prepend):
- 所有 CRUD 操作增加
knowledge_base_manage自定义权限检查 - 有
knowledge_base_manage权限的自定义角色用户也可操作
- 所有 CRUD 操作增加
10. AI辅助:Help Center 策展 + Article Writer(企业版)
功能描述
企业版提供 AI 辅助的帮助中心内容生成能力:
- Help Center 策展(Curation):给定一组 URL,AI 自动筛选出适合作为帮助中心文章的页面,生成分类+文章结构
- Article Writer:给定 URL,AI 抓取网页内容并重写为帮助中心文章格式
- Onboarding 自动生成:新用户注册后,系统可自动从其网站抓取内容生成帮助中心
涉及的业务逻辑
-
Captain::Llm::HelpCenterCurationService:
- 输入:account + links(URL列表)
- 使用 GPT-4.1 模型,分析 URL 列表,筛选出适合做帮助中心文章的页面
- 输出:
{ categories: [...], articles: [...] }结构
-
Captain::Llm::ArticleWriterService:
- 输入:account + 原始内容/URL
- 使用 LLM 将内容重写为帮助中心文章格式
-
Onboarding::HelpCenterArticleBuilder(enterprise):
- 初始化参数:account, portal, user, article(含 urls, title, category_id)
- 流程:scrape → normalize → rewrite → 保存文章
- 抓取指定 URL 的页面内容,处理后生成帮助中心文章
-
Onboarding::HelpCenterArticleWriterJob / Onboarding::HelpCenterArticleGenerationJob:
- 异步执行文章生成,失败时记录错误上下文
-
Captain::Tools::FaqLookupTool(AI Copilot 工具):
- 输入:query(问题关键词)
- 使用语义搜索在已审批的 FAQ Responses 中查找匹配答案
- 返回格式化的问答内容,包含外部链接(如果是帮助中心文章则显示 Source)
模块间依赖关系
Account
└── Portal (1:N)
├── Category (1:N)
│ ├── Folder (1:N)
│ ├── RelatedCategory (M:N via related_categories)
│ ├── SubCategory (1:N, parent_category_id)
│ └── Article (1:N, category_id, nullable)
├── Article (1:N)
│ ├── ArticleEmbedding (1:N, enterprise)
│ └── AssociatedArticle (多语言关联链)
├── Channel::WebWidget (1:1, 可选绑定在线聊天)
└── Inbox (1:N, nullable)
关键配置/功能开关
help_center_embedding_search— 开启向量语义搜索(企业版)captain_tasks— 开启 AI 翻译/写作能力(企业版)- Portal.config(jsonb):
allowed_locales,default_locale,draft_locales,layout,social_profiles - Portal.ssl_settings(jsonb):自定义域名 SSL 配置
技术要点
- PgSearch 全文搜索:tsearch prefix 模式 + 权重分级(A/B/C) + normalization=2
- pgvector 向量搜索:ivfflat 索引 + cosine 距离 + 1536维 OpenAI embedding
- 多语言架构:Portal.allowed_locales → Category.locale → Article.locale + associated_article_id 关联链
- Tracking Pixel:1x1 PNG + 24h private cache + 浏览量计数
- Layout 模式:classic(传统) / documentation(文档风格),通过 request.variant 区分视图模板
- 自定义域名 + SSL:DNS CNAME 指向 + 自动 SSL 证书管理
- AI Integration:GPT-4.1 策展 + Article Writer + Embedding Service + Translation Service