构建自定义知识库
Alauda Hyperflux 插件自带一个内置的 system 知识库,涵盖 Alauda Container Platform (ACP)和 Alauda 产品文档。除此之外,Hyperflux 还维护一个独立的 user 知识库, 你可以将自己的内容填充进去——内部 runbook、SRE playbook、设计文档、未包含在打包语料中的 Alauda 产品文档版本,或者任何其他私有 Git 仓库。Hyperflux 在每次提问时都会同时从 两个知识库中检索,并合并结果,因此添加自定义语料会对打包的产品知识进行增强, 而不是替换它。
本指南介绍由管理员驱动的路径:使用 pod 内置 builder,将 Git 仓库列表批量导入 user 知识库。 (对于终端用户通过 chat UI 上传文件,请使用 v1.3.1 新增的 BYO Knowledge 工具——目标相同, 入口不同。)
该工作流在部署好的 smart-doc pod 内部运行。镜像中已经包含 builder 源码、
embedding model 以及正确的 Python 环境,并且 pod 已经具备到 user knowledge-base PostgreSQL 的连接。
你只需要一个待导入的仓库清单,以及对 global cluster 执行 kubectl exec 的权限。
目录
embedding 管道的工作方式前提条件第 1 步 — 描述你的语料第 2 步 — 将 manifest 复制到 smart-doc pod 中第 3 步 — 在 pod 内运行prepare第 4 步 — 在 pod 内运行 embed第 5 步 — 在 user 知识库上创建 BM25 index(一次性)(可选)多集群:dump 和 restore替换打包的 system 知识库(高级)重新生成频率注意事项embedding 管道的工作方式
smart-doc builder 分两阶段将 Git 仓库列表转换为向量化知识库:
- Prepare —— 克隆仓库,按标题和 chunk 大小拆分每个
.md/.mdx文档,然后调用 LLM (与运行中的 Hyperflux 插件已配置的那个相同)为每个文档生成一段摘要和若干代表性问题。 输出:documents.json。 - Embed —— 加载
gte-multilingual-baseembedding model,分别对 chunk 和按文档的摘要进行 embedding,并将它们写入 user-knowledge-base PostgreSQL(docvec_user_kb),使用运行中的服务端 读取的 collection 名称(默认是user_defined_kb)。
完成 embedding 后,运行中的服务端会在下一次查询时获取新内容——无需修改 chart,也无需重启 pod。 system 知识库不会受到影响。
注意: 混合检索使用的 BM25 index 不会由 embed 步骤构建。打包的 system-KB dump 中包含 预先构建好的 BM25 index,但 user-KB 数据库在安装时是空的。如果你的部署启用了混合检索(默认如此), 你必须为 user-KB collection 一次性创建 BM25 index——请参见第 5 步。
前提条件
- 对运行 Hyperflux 的集群(global cluster)拥有
kubectl访问权限,并且对cpaas-system命名空间中 的smart-docpod 具备exec权限。 - 对你要导入的每个 Git 仓库具有读权限。如果是私有仓库,请准备好 HTTPS 用户/令牌对。
- 一个配额足够的 LLM endpoint。 prepare 阶段会针对每个源文档调用一次 LLM(对于 ACP 规模的知识库, 大约需要 1,000–3,000 次调用)。默认情况下,pod 内命令会复用已为 Hyperflux 配置的 LLM endpoint (即安装时通过 LLM Base URL / LLM API Key / LLM Model Name 设置的那个)。 如果你的账号有速率限制,请准备一个配额更高的独立 endpoint,并在 exec 会话中覆盖环境变量(第 3 步)。
你不需要单独的工作站 Python 环境、下载好的 gte-multilingual-base 副本、独立的 PostgreSQL 实例,
也不需要克隆 smart-doc 仓库——smart-doc 容器里已经内置了所有这些内容。
第 1 步 — 描述你的语料
创建一个 JSON manifest,列出你要导入的每个 Git 仓库。将其保存在本地机器上,命名为
my-kb.json(名称可自定义——第 2 步会将其复制到 pod 中)。
如需在一次运行中导入多个仓库,继续添加更多 repos 条目即可。
字段说明:
第 2 步 — 将 manifest 复制到 smart-doc pod 中
第 3 步 — 在 pod 内运行 prepare
在 serve 容器中打开交互式 shell,并运行 prepare 阶段:
有用的标志:
--dryrun—— 克隆仓库并打印文档列表,但不调用 LLM。请先使用此选项确认你的sub_dirs和doc_type过滤条件符合预期。
注意:
prepare不会在多次运行之间缓存 LLM 响应——每次调用都会为每个源文档重新发起一次 LLM 调用。 请为每次重跑预留完整的按文档成本,并且只有在源语料实际发生变化时才重新运行 prepare(否则只需基于现有的documents.json重新运行embed)。
第 4 步 — 在 pod 内运行 embed
保持在同一个 shell 中(这样第 3 步设置的环境变量仍然有效):
chart 已经导出 EMB_MODEL_NAME=/opt/gte-multilingual-base、DEVICE=cpu,以及
PG_USER_KB_CONN_STR(指向 user-KB 数据库 docvec_user_kb),因此你不需要传入
--emb-model 或 --device。不过请显式传入 --pg-conn-str "${PG_USER_KB_CONN_STR}",
因为脚本默认使用的是 system-KB 连接字符串(PG_SYS_KB_CONN_STR)。
各标志的作用如下:
警告: 当
--vector-types包含doc_summary,但documents.json是在未设置ENABLE_GEN_QUESTIONS=true的prepare运行中生成时,embed 会悄无声息地输出零个摘要向量, 只会在最后记录no_summary=N。如果你看到较高的no_summary数值,请先使用ENABLE_GEN_QUESTIONS=true重新运行prepare,然后再重新运行 embed。
注意: serve 容器默认在 CPU 上运行(
DEVICE=cpu)。在 CPU 上 embedding 5,000 个 chunk 大约需要一小时; 对于较小的内部语料(几百个文档),则只需几分钟。如果你需要 GPU 吞吐量,请在 GPU 调度的 pod 上运行构建 (不在本指南范围内),并使用后文描述的多集群 dump-and-restore 路径。
embed 步骤不会调用 LLM;你可以基于同一个 documents.json 低成本地重跑它,以尝试不同的 chunk 大小,
或为现有 collection 追加新文档。
第 5 步 — 在 user 知识库上创建 BM25 index(一次性)
user-KB 数据库在安装时是空的——不同于打包的 system-KB dumps,它不会预先包含 BM25 index。 如果启用了混合检索(默认如此),请在首次 embed 运行后创建一次 index:
如果没有这个 index,混合检索路径会在 user KB 上静默回退为仅 dense 检索(仍然会返回结果,只是没有精确关键词召回)。
就是这样——不需要修改 chart,也不需要重启 pod。运行中的服务端已经在每次查询时从
docvec_user_kb / user_defined_kb 读取内容,因此你的自定义语料会立即开始参与回答。你可以通过 chat UI
发起一个代表性问题来确认。
(可选)多集群:dump 和 restore
如果你希望只构建一次语料并将其推送到多个集群,可以在第 4 步之后对 user KB 执行 pg_dump,
然后在每个目标集群上恢复:
然后在每个目标集群上执行第 5 步(BM25 index)——该 index 是按数据库维护的,单独恢复到空数据库时不会自动保留
(如果恢复到一个已有内容的数据库,且 dump 中包含 BM25,则会合并 BM25;对于全新的 user KB,请在恢复后执行
CREATE INDEX)。
注意: 将 user-KB dump 使用
pg_restore恢复到一个已经有 user-KB 内容的目标集群(例如之前的 BYO 上传) 时,会在 langchain 表的CREATE操作上发生冲突。若要进行干净覆盖,建议使用 chart 的 swap 机制,或者先在目标端 删除并重新创建docvec_user_kb。只有在目标 user KB 为空时,直接pg_restore才是最安全的方式。
替换打包的 system 知识库(高级)
上面的工作流是向 user KB 追加内容,并保留打包的产品知识不变。如果你的需求不同——例如,打包的 Alauda 产品文档 与你的环境不符,你希望用内部版本替换它们——请重复相同的 pod 内工作流,但将目标指向 system KB:
--pg-conn-str "${PG_SYS_KB_CONN_STR}"--collection-name <your-system-kb-collection-name>- 在 chart 中更新
pgconnect.pgCollectionName,使其指向你的 collection 名称,并重新部署。
这一路径需要修改 chart,并会禁用未来 Hyperflux 版本中的 system-KB 自动升级(自动 swap 规则扫描将无法匹配你的自定义 collection 名称)。只有在 user-KB 扩展不足以满足需求时才使用它。
重新生成频率
自定义知识库比产品文档变化更快。请根据源仓库的变更节奏,规划定期重新运行 prepare → embed:
- 每日变化的 runbook → 每晚通过 cron(一个运行相同 pod 内命令的一次性 Kubernetes
CronJob)重新 embedding 到 同一个user_defined_kbcollection。 - 每季度更新的架构文档 → 在每个发布边界手动重新生成。
对同一个 collection 名称重新运行 embed 时,会使用确定性的行 ID(smart_doc_builder.py:38-48 中的
make_row_id),因此未变化的 chunk 会幂等 upsert,而变化的 chunk 会覆盖——但对于在 manifest 中被移除
的文档,其对应行会变成孤儿行。若要进行干净替换,请在重新 embedding 之前删除并重新创建 collection:
然后重新运行第 4 步进行重建。langchain_pg_embedding 上的 BM25 index 会自动继续应用于新行,因此你不需要
重新运行第 5 步——除非你同时删除了数据库本身(例如用于上文的多集群 pg_restore 覆盖场景)。
注意事项
- 自定义语料与 BYO Knowledge 工具上传共享同一个 user KB。 终端用户通过 chat UI 上传的文件(v1.3.1 引入)
会落入与你管理员整理的语料相同的
user_defined_kbcollection。只要 URL 不冲突,它们可以共存;实际上这通常没问题, 因为 BYO 上传使用的是不同的 URL 方案。如果你确实删除并重新创建了 collection(见“重新生成频率”部分),该 collection 中的 BYO 上传也会与你的语料一起被清除——如果你在意这些内容,请先备份。 - system KB 的版本过滤不适用于 user KB。 当用户提出与版本相关的问题(例如 ACP 4.3)时,system KB 会被过滤到该 版本,但 user KB 会返回跨所有版本的匹配。如果你的自定义语料包含多个版本,回答中可能会出现跨版本的 chunk。
- embedding model 不匹配 是最常见的静默失败原因:使用除 pod 内
/opt/gte-multilingual-base之外的模型构建 的向量虽然可检索,但得分会始终接近 0,因此答案会退化为“我没有足够信息”,而不会出现明显错误。这里描述的 pod 内工作流默认使用内置模型——只有在你明确知道自己在做什么时才覆盖EMB_MODEL_NAME。