ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

把知识库搬进 CI/CD:WeKnora 官方 CLI 的脚本化玩法

把知识库搬进 CI/CD:WeKnora 官方 CLI 的脚本化玩法

把知识库搬进 CI/CD:WeKnora 官方 CLI 的脚本化玩法

【免费下载链接】WeKnoraOpen-source LLM knowledge platform: turn raw documents into a queryable RAG, an autonomous reasoning agent, and a self-maintaining Wiki.项目地址: https://gitcode.com/GitHub_Trending/we/WeKnora

知识库类产品最常见的尴尬在于:Web 界面点起来很顺,一旦要接入 CI/CD、定时任务或 Agent 自动化,就立刻暴露出「人机交互深度绑定」的原罪——没有稳定的输出契约、错误要靠猜退出码、破坏性操作在无人值守时无从设防。腾讯开源的企业级 LLM 知识平台 WeKnora 给出了一个不同方向的答案:在仓库的cli/目录里维护了一个以 AI Agent 为首要消费者的官方命令行工具weknora,把知识库的创建、文档上传、混合检索、流式问答全部收敛成可脚本化、可机器判读的契约。

本文以仓库源码为证据,拆解这套 CLI 的三个关键设计:JSON Envelope 输出契约、exit-10 高风险写保护协议,以及如何在 CI/CD 与沙箱环境中用无状态凭证编排完整知识库流程。

安装与命令面:为 Agent 而非终端设计的命令行

weknora位于仓库根目录下的 cli/ 独立 Go 模块,与 SDK(根目录client/)解耦。当前官方推荐的安装方式是源码构建,cli/Makefile 通过-ldflags注入版本、commit 与构建时间:

cd cli make build # 产出 ./bin/weknora

构建后的二进制是一个多子命令的 cobra 树,覆盖知识库(kb)、文档(doc)、分块(chunk)、会话(session)、消息(message)、自定义 Agent(agent)、模型(model)、检索(search)、流式问答(chat)等核心操作,完整清单见 cli/README.md。其中三个命令是「面向机器」的标志:

  • weknora exit-codes:直接输出完整退出码矩阵(默认 JSON 格式),见 cli/cmd/exitcodes.go。Agent 不必翻文档,该命令本身就是契约的机器可读形态。
  • weknora schema:枚举每个叶子命令的used_for/required_flags/examples/output/risk/flags,见 cli/cmd/schema.go。Agent 可以像查 API 文档一样自发现整个命令面,无需解析人类帮助文本。
  • weknora doctor:4 项自检(连通性、凭证、版本偏差、密钥存储后端),是所有脚本编排的第一步。

这套命令面遵循「Options + Narrow Service」模式:每个命令只声明自己需要的极窄 SDK 接口,测试注入 5 行 fake 即可完成单元测试,cli/AGENTS.md 中有完整说明。

JSON Envelope:stdout 永远干净,错误走 stderr

脚本化最大的敌人是「输出里混进了错误信息」。weknora的第一条铁律是通道分离:stdout 是纯数据通道,永远只承载 JSON Envelope 或人类可读文本;stderr 承载日志、进度、警告与错误。非空的 stderr 并不代表失败——必须读退出码,这是 cli/AGENTS.md Wire Contract 一节的开篇约定。

成功路径上,所有命令在--format json(默认)下输出对称信封:

{"ok":true,"data":[{"id":"kb_x","name":"Eng"}],"meta":{"count":1},"profile":"prod"}

data对 list 是数组、对 view 是对象、对纯变更成功被省略;meta携带count、has_more、dry_run、plan等计数与批处理结果。--jq作用于整个信封,weknora kb list --format json --jq '.data[].id'可以无副解析地抽取字段。

失败路径的形态是类型化错误信封(stderr):

{"ok":false,"error":{"type":"auth.unauthenticated","message":"fetch current user: HTTP error 401","hint":"run `weknora auth login`","retry_argv":["weknora","auth","login"],"risk":{"level":"destructive","action":"kb.delete"}}}

这套错误模型的实现集中在 cli/internal/cmdutil/errors.go:ErrorCode是命名空间的稳定标识符(auth.*、resource.*、input.*、server.*、network.*、local.*、operation.*),ClassifyHTTPStatus/ClassifyHTTPError把 HTTP 状态码与 SDK 传输错误映射为类型化代码。一个值得注意的细节:serverNotFoundRE用正则"code":1003精确匹配服务端结构化错误信封,避免在 500 响应体的堆栈文本里把 "config file not found" 误判为resource.not_found——这正是「错误必须可判读」在工程上的具体体现。

exit-10 协议:把「人在环」编码进退出码

无人值守脚本最怕的既不是超时也不是限流,而是误删。weknora用退出码10(input.confirmation_required)把「高风险写操作需要显式确认」变成线级信号。其行为矩阵在 cli/internal/cmdutil/confirm.go 的ConfirmDestructive中实现:

  • 显式传-y/--yes→ 放行;
  • 非 TTY 或 JSON 输出模式且无-y→ 返回input.confirmation_required(exit 10),并携带retry_argv(如["weknora","kb","delete","kb_x","-y"])与risk:{level:"destructive",action:"kb.delete"};
  • 交互 TTY → 弹确认提示;用户拒绝则local.user_aborted。

以 cli/cmd/kb/delete.go 为例,kb delete的 help 文本直接写明:无-y时 CLI 退出 10 并写入input.confirmation_required,Agent 不得擅自补-y。所有删除类命令(kb/doc/chunk/session/agent delete)、覆盖类更新与weknora api的 DELETE 方法均走此闸门。

配套的还有 cli/AGENTS.md 中整整一节的Exit-10 anti-patterns,六条红线值得每个写自动化脚本的人细读:不得自动加-y重试、不得直接执行retry_argv、不得把 exit 10 当瞬态错误套指数退避、不得回退到破坏性更小的动词、不得沿用上一次的批准、不得用切 JSON 模式绕过闸门(JSON 模式同样会返回该错误信封)。这是把「人类审批」显式嵌入机器协议的设计范本。

与退出码配套的类型化判定集中在 cli/internal/cmdutil/exit.go 的ExitCode:auth.*→3、resource.not_found→4、input.*(除 confirmation_required)→5、server.rate_limited→6、server.*/network.*→7、operation.timeout→124、信号取消→130。retryableForCode更进一步为每个错误码标注「重试是否可能成功」,确定性错误返回false、瞬态错误返回true、未知的保持缺省——脚本可以据此决定重试、退避还是直接上抛。

在 CI/CD 与沙箱里编排完整知识库流程

把上面的契约串起来,就能得到一条完全无交互的流水线。首先是无状态凭证:Agent 或 CI 场景不需要profile add+auth login的持久化流程,只设置两个环境变量即可,见 cli/README.md 与 cli/skills/weknora-shared/SKILL.md:

export WEKNORA_API_KEY="sk-…" # 或 WEKNORA_TOKEN(Bearer JWT) export WEKNORA_HOST="https://kb.example.com" weknora kb list # 直接已认证,零磁盘写入

需要持久化命名 profile 时,echo "$WEKNORA_API_KEY" | weknora auth login --with-token是非交互的 stdin 管道式认证,实现在 cli/cmd/auth/login.go——它会先用只读的/auth/me探测 key 有效性再落盘,坏 key 在登录时即快速失败。

接着是典型的「建库 → 传文档 → 等待解析 → 检索/问答」编排。weknora link --kb <name>把当前目录绑定到知识库,后续命令自动解析--kb;--dry-run让任何变更命令先输出meta.plan且零副作用,cli/internal/cmdutil/dryrun.go 中明确保证 dry-run 路径完全离线——不触 SDK、不写 keyring、不写.weknora/project.yaml,甚至可在无活跃 profile 时工作。

解析等待是 CI 流水线的关键一环,cli/cmd/doc/wait.go 的doc wait实现了生产级轮询语义:多目标并发(上限 5,可xargs -P扩展)、指数退避加抖动(初始--interval,上限 15s)、退出码优先级failed(1) > timeout(124) > completed(0),且对parse_status=draft的文档快速失败并给出精确的解锁命令(weknora doc reparse <id>)——避免了 CI 挂死到超时的尴尬。它还把「wait 的聚合结果」设计成 stdout 分区信封 + 静默错误(WithSilent),防止 stderr 上再出现一条与 stdout 矛盾的失败信封,脚本只需读退出码和data.failed。

下图为 WeKnora 的文档处理与检索管线示意,doc upload → doc wait → search/chat的 CLI 编排正是围绕这条链路展开:

更进一步,cli/skills/weknora-shared/SKILL.md 还内置了两份 Agent Skills(weknora-shared与weknora-rag-search),它们随二进制嵌入、weknora skills install即可分发,frontmatter 记录tested_against版本,且internal/skillparity有 CI 测试保证技能引用的命令、flag、MCP 工具永不与 CLI 实际命令面脱节。技能文档中甚至给出了「chat vs session ask vs search chunks」的决策表,并标注了--kb解析顺序(flag →WEKNORA_KB_ID→ 目录链接 → 报错),确保脚本永远不会静默检索到错误的语料库。

小结

WeKnora 的 CLI 不是 Web 管理端的一层薄壳,而是一套以「AI Agent / 脚本为首要消费者」重新设计的接口面:JSON Envelope 保证 stdout 永远可jq,类型化错误 + 退出码矩阵让失败可自动分诊,exit-10 把人工审批编码成协议层信号,--dry-run与doc wait则分别解决「动手前预览」与「异步解析等待」两个流水线痛点。对于任何想把企业知识库接入发布流水线、定时任务或 Agent 工作流的团队,这套「把知识库搬进 CI/CD」的玩法,值得直接照搬——契约已经替你写好了。

【免费下载链接】WeKnoraOpen-source LLM knowledge platform: turn raw documents into a queryable RAG, an autonomous reasoning agent, and a self-maintaining Wiki.项目地址: https://gitcode.com/GitHub_Trending/we/WeKnora

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进