Files
gochat/docs/requirements/M09-knowledge-base.md
T
rogee 0dabb8cfa5 docs: 整理文档目录结构 — 清理过时文档、归集功能子目录、统一命名规范
清理:
- 删除 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 相关修改
2026-07-09 14:53:27 +08:00

27 KiB
Raw Blame History

M9: 知识库与帮助中心(Portal / Category / Article / Help Center / Kbase Search

参照仓库:chatwoot-reference
产出日期:2026-05-22
版本基准:Chatwoot v3.x


目录

  1. Portal CRUD + 设置 + Logo + 自定义域名
  2. Category / Folder 管理
  3. Article CRUD + 关联文章 + 排序 + 搜索
  4. RelatedCategory 关联分类
  5. Help Center 前端展示(Portal布局/SEO/追踪像素)
  6. Kbase 文本搜索(PgSearch
  7. Article Embedding 向量搜索(企业版)
  8. Article 批量操作(状态/删除/翻译)
  9. 权限策略(PortalPolicy / ArticlePolicy / CategoryPolicy
  10. AI辅助:Help Center 策展 + Article Writer(企业版)

1. Portal CRUD + 设置 + Logo + 自定义域名

功能描述

Portal 是帮助中心的顶层容器,每个 Portal 属于一个 Account,可绑定一个 WebWidget 渠道用于在线聊天。Portal 拥有完整的配置体系:名称、slug(唯一标识)、自定义域名、品牌颜色、header 文字、首页链接、布局模式(classic/documentation)、多语言设置、社交链接、SSL 配置等。

用户操作流程

  1. 创建 Portal:管理员进入 Settings → Help Center → 点击 "Create Portal",填写名称、slug、颜色、布局、默认语言等;系统自动创建 Portal,可选绑定 WebWidget 渠道
  2. 查看 Portal 列表:按账户加载所有 Portal(含 logo、archived 状态等)
  3. 更新 Portal 设置:修改名称、header_text、homepage_link、custom_domain、颜色、布局、多语言配置(allowed_locales/default_locale/draft_locales)、社交链接等
  4. 删除 Portal:级联删除 Categories、Articles、Folders、Inbox 关联(nullify
  5. 归档 Portal:将 Portal 标记为 archivedarchived=true),归档后前端不展示
  6. 上传/移除 LogoPortal 支持品牌 LogoActiveStorage attachment),创建/更新时传入 blob_id
  7. 发送 DNS 配置邮件:为自定义域名发送 DNS 设置指引邮件(send_instructions),接收方按邮件指引配置 CNAME
  8. 查看 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) — 品牌主题色,默认 #1f93ff
    • header_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_async
    • has_many :folders, through: :categories
    • has_many :articles, dependent: :destroy_async
    • has_one_attached :logo — ActiveStorage Logo
    • has_many :inboxes, dependent: :nullify — Inbox 可关联 Portal
    • belongs_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 attachment
  • PortalsController#archive — 设置 archived=true
  • PortalsController#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。

用户操作流程

  1. 创建 Category:在 Portal 管理页面选择 "Add Category",填写名称、描述、图标、locale、父分类(可选);同时可指定关联分类(related_category_ids
  2. 查看 Category 列表:按 Portal + locale 加载分类列表,按 position 排序
  3. 更新 Category:修改名称、描述、图标、关联分类等
  4. 删除 Category:级联删除 FoldersArticles 的 category_id 被设为 NULL
  5. 排序 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 slug
    • position (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_async
    • has_many :articles, dependent: :nullify
    • has_many :category_related_categories (RelatedCategory), dependent: :destroy_async
    • has_many :related_categories (Category), through: :category_related_categories
    • has_many :sub_categories (Category), foreign_key: :parent_category_id
    • belongs_to :parent_category (Category), optional: true
    • belongs_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)、排序、浏览量统计。

用户操作流程

  1. 创建 Article:在 Portal 管理页面选择 "Add Article",填写标题、内容、描述、locale、作者、分类;默认状态为 draft;可选择关联已有文章(associated_article_id
  2. 查看 Article 列表:按 Portal + 可选 category_slug/locale/author/status 过滤,支持全文搜索(query),有分类时按 position 排序,否则按 updated_at 排序
  3. 查看 Article 详情:获取单篇文章完整内容
  4. 编辑 Article:获取编辑数据(edit 接口)
  5. 更新 Article:修改标题、内容、状态、分类等
  6. 删除 Article:删除单篇文章
  7. 排序 Articles:通过 reorder 接口批量更新 position
  8. 查看浏览量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 slug
    • status (integer) — 状态枚举:draft(0), published(1), archived(2)
    • position (integer) — 排序位置
    • views (integer) — 浏览次数
    • meta (jsonb) — 元数据 JSON
    • account_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: :nullify
    • belongs_to :root_article (Article), foreign_key: :associated_article_id
    • belongs_to :category, optional: true
    • belongs_to :folder, optional: true
    • belongs_to :portal
    • belongs_to :author (User)
  • 搜索 scope

    • search_by_category_slug, search_by_category_locale, search_by_locale, search_by_author, search_by_status
    • order_by_updated_at, order_by_position, order_by_views
    • pg_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) — 查找根文章 ID
    • Article.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_article
  • ArticlesController#set_article_count — 不含 status/author_id 的搜索计算各种状态文章数

4. RelatedCategory 关联分类

功能描述

RelatedCategory 是分类之间的关联关系表,用于在帮助中心展示"相关分类"推荐。这是一种多对多关系:一个 Category 可以关联多个其他 Category(通过 RelatedCategory 中间表)。

用户操作流程

  1. 创建/更新 Category 时指定关联分类:在 category 参数中传入 related_category_ids 数组
  2. 前端展示相关分类:在分类详情页面展示关联的其他分类

涉及的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_async
    • has_many :related_categories (Category), through: :category_related_categories

5. Help Center 前端展示(Portal布局/SEO/追踪像素)

功能描述

帮助中心有公开的 Portal 前端,通过 /hc/{slug}/{locale} 系列路由对外展示。支持两种布局模式(classic / documentation),支持 SEOOG 图片、sitemap)、自定义域名、暗/亮主题切换、iframe 嵌入、追踪像素(tracking pixel)统计浏览量。

用户操作流程

  1. 访问帮助中心首页/hc/{slug} 自动重定向到 /hc/{slug}/{default_locale},加载 Portal 配置、分类、热门文章、精选文章
  2. 浏览分类页/hc/{slug}/{locale}/categories/{category_slug},展示分类下的已发布文章
  3. 阅读文章/hc/{slug}/articles/{article_slug},渲染文章内容、OG SEO 信息
  4. 搜索文章/hc/{slug}/{locale}/articles?query=xxx,前端搜索+排序+分页
  5. Markdown 输出/hc/{slug}/articles/{article_slug}.md,纯 Markdown 格式(供 AI/工具调用)
  6. Tracking Pixel/hc/{slug}/articles/{article_slug}.png,1x1 像素追踪浏览量(24h private cache
  7. Sitemap/hc/{slug}/sitemap.xmlSEO 爬虫用
  8. 自定义域名Portal 配置 custom_domain 后,DNS CNAME 指向 ChatwootSSL 自动配置

涉及的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_datadocumentation 布局)— 加载 visible_categories、popular_topics、featured articles、recently_articles
    • 自定义域名验证:ensure_custom_domain_request
    • 布局选择:set_portal_layoutclassic/documentation
    • 视图变体:set_view_variantdocumentation 布局使用 :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 PNG24h 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 模型使用 PgSearchPostgreSQL 全文搜索)实现知识库文本搜索。搜索权重:标题(A)> 描述(B)> 正文(C),使用 tsearch prefix 模式(支持前缀匹配),normalization=2 防止长文堆叠关键词。

用户操作流程

  1. 管理端搜索:在 Portal 管理页面的文章列表中输入搜索词(query 参数),结合 category_slug/locale/author/status 过滤
  2. 公众端搜索:在帮助中心前端搜索框输入关键词,搜索已发布文章

搜索实现细节

  • 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篇文章。

用户操作流程

  1. 自动嵌入生成:文章保存后自动触发 Portal::ArticleIndexingJob → 生成搜索词 → Captain::Llm::EmbeddingService 调用 LLM API 生成向量 → 存入 article_embeddings
  2. 向量搜索:公众端搜索时,若 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 :article
    • has_neighbors :embedding, normalize: true — Neighbor 模式(cosine 距离)

涉及的业务逻辑

  • Enterprise::Concerns::Articleprepend 到 Article 模型):

    • after_save :add_article_embedding — 当 title/description/content 变更时触发
    • self.vector_search(params)
      1. 调用 Captain::Llm::EmbeddingService 将 query 生成向量
      2. 在已过滤文章范围内,使用 ArticleEmbedding.nearest_neighbors(:embedding, embedding, distance: 'cosine').limit(5) 找最近的5篇
      3. 返回匹配文章
  • Enterprise::Public::Api::V1::Portals::ArticlesControllerprepend):

    • search_articles 覆盖:若 help_center_embedding_search 开关开启且有 query,使用 vector_search;否则走原始文本搜索
  • Portal::ArticleIndexingJob

    • perform(article) → 调用 article.generate_and_save_article_seach_terms 生成搜索词
  • ArticleEmbedding#update_response_embeddingafter_commit):

    • 当 term 变更或 embedding 为 nil 时,调用 Captain::Llm::UpdateEmbeddingJob 重新生成向量

8. Article 批量操作(状态/删除/翻译)

功能描述

提供文章的批量操作能力:批量修改状态(draft/published/archived)、批量删除、批量翻译(企业版,调用 Captain LLM 翻译服务)。

用户操作流程

  1. 批量修改状态:在文章列表选中多篇文章,选择目标状态(draft/published/archived),调用 update_status
  2. 批量删除:选中多篇文章,调用 delete_articles
  3. 批量翻译(企业版):选中多篇文章 + 目标 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_all
    • translate — 基础版返回 not_implemented
  • Enterprise::BulkActionsControllerprepend):

    • translate 覆盖实现:
      1. 验证 captain_tasks 功能开关
      2. 验证 locale 在 Portal allowed_locales 中
      3. 验证目标分类存在且 locale 匹配
      4. 检查翻译是否已存在(find_existing_translations),若有返回 409 conflict(含重复文章列表),可 force=true 覆盖
      5. 为每篇文章异步执行 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::ArticlePolicyprepend):

    • 所有 CRUD 操作增加 knowledge_base_manage 自定义权限检查
    • knowledge_base_manage 权限的自定义角色用户也可操作

10. AI辅助:Help Center 策展 + Article Writer(企业版)

功能描述

企业版提供 AI 辅助的帮助中心内容生成能力:

  1. Help Center 策展(Curation:给定一组 URL,AI 自动筛选出适合作为帮助中心文章的页面,生成分类+文章结构
  2. Article Writer:给定 URL,AI 抓取网页内容并重写为帮助中心文章格式
  3. Onboarding 自动生成:新用户注册后,系统可自动从其网站抓取内容生成帮助中心

涉及的业务逻辑

  • Captain::Llm::HelpCenterCurationService

    • 输入:account + linksURL列表)
    • 使用 GPT-4.1 模型,分析 URL 列表,筛选出适合做帮助中心文章的页面
    • 输出:{ categories: [...], articles: [...] } 结构
  • Captain::Llm::ArticleWriterService

    • 输入:account + 原始内容/URL
    • 使用 LLM 将内容重写为帮助中心文章格式
  • Onboarding::HelpCenterArticleBuilderenterprise):

    • 初始化参数:account, portal, user, article(含 urls, title, category_id
    • 流程:scrape → normalize → rewrite → 保存文章
    • 抓取指定 URL 的页面内容,处理后生成帮助中心文章
  • Onboarding::HelpCenterArticleWriterJob / Onboarding::HelpCenterArticleGenerationJob

    • 异步执行文章生成,失败时记录错误上下文
  • Captain::Tools::FaqLookupToolAI 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.configjsonb):allowed_locales, default_locale, draft_locales, layout, social_profiles
  • Portal.ssl_settingsjsonb):自定义域名 SSL 配置

技术要点

  1. PgSearch 全文搜索tsearch prefix 模式 + 权重分级(A/B/C + normalization=2
  2. pgvector 向量搜索ivfflat 索引 + cosine 距离 + 1536维 OpenAI embedding
  3. 多语言架构Portal.allowed_locales → Category.locale → Article.locale + associated_article_id 关联链
  4. Tracking Pixel1x1 PNG + 24h private cache + 浏览量计数
  5. Layout 模式classic(传统) / documentation(文档风格),通过 request.variant 区分视图模板
  6. 自定义域名 + SSLDNS CNAME 指向 + 自动 SSL 证书管理
  7. AI IntegrationGPT-4.1 策展 + Article Writer + Embedding Service + Translation Service