7. 安装验收
POC 部署手册章节。按 2026.10 主线代码核对;命令输出以当次交付的安装器为准。
本章内容:本章回答一个问题——装完的环境到底能不能用。验收分四层:主机侧服务正常;就绪状态读得懂;一次真实业务调用从调用方经网关到模型再回来,并能在控制台按请求标识查到;拒绝路径按预期拒绝且错误码可解读。四层都完成并填好 7.6 节的记录表,才能把环境交给客户开始 POC。读者是实施工程师与客户方验收人。
安装器自带的「装后验收」(第 4.6 节)只证明平台基础服务可用,不代表模型、授权与业务链路已经打通。本章的验收以「装后验收结果 + zenova status + 真实业务调用」三者为准,不以直接访问某个内部端口返回什么为准。
7.1 主机侧检查
适用场景:安装完成后第一次验收;此后每次升级、修改部署配置、重启主机之后也照做一遍。
前提:以 root 登录安装主机;安装已显示完成且装后验收无阻断项。
操作步骤
- 查看各服务状态与当前版本。
# 安装主机 · root · 只读
sudo zenova status
- 查看不以
zenova-开头的基础服务。zenova status只列zenova-开头的服务,下面这些要用 systemctl 单独看(未由安装器部署的项会显示单元不存在,属正常)。
# 安装主机 · root · 只读
systemctl status postgres clickhouse caddy secret-service spicedb --no-pager
systemctl status rustfs --no-pager # 仅对象存储选「自带对象存储」时存在
- 执行全量体检并保存报告,随后查看退出码。
# 安装主机 · root · 写入(仅在 /root/zenova-install 下生成报告文件)
sudo zenova doctor --all --save /root/zenova-install/doctor
echo "doctor 退出码:$?"
- 把报告文件与
zenova status的输出一起归入交付材料。
# 安装主机 · root · 写入(仅在 /root/zenova-install 下生成文件)
sudo zenova status --json > /root/zenova-install/status.json
ls -l /root/zenova-install/doctor* /root/zenova-install/status.json
你会看到
zenova status:列出各zenova-服务的运行状态、当前版本、各实例,以及进行中与最近一次升级。控制面、后台任务、运行时存储这类分槽服务会显示当前接流的槽位(如zenova-control-plane@a)。各列的具体名称以实际输出为准。- systemctl:每个已部署的单元显示
active (running),且为开机自启(enabled)。 zenova doctor --all:列出全部检查项,包括已通过与跳过的项;未通过的项带稳定的诊断代码(如HOST_…、SVC_…)和处理建议。--save后面给的路径没有扩展名时,报告自动保存为.txt。- 退出码:没有阻断项为
0;有阻断项为2。
| doctor 结果 | 含义 | 处理 |
|---|---|---|
| :-- | :-- | :-- |
| 退出码 0,无告警 | 本机与连通性全部正常 | 进入 7.2 节 |
| 退出码 0,有告警项 | 不影响使用,但需记录 | 在 7.6 节记录告警项与诊断代码,确认是否属于本次范围 |
| 退出码 2 | 有阻断项 | 按报告中的诊断代码与处理建议处理后重跑;代码含义查产品文档站「安装与运维诊断代码」页 |
注意:zenova start/stop/restart 只接受 zenova- 开头的服务名;postgres、clickhouse、caddy、secret-service、spicedb 不经 zenova 命令启停。服务未运行时先看日志(第 8.5 节),不要反复重启。
注意:需要排查到某个模型或工具地址的连通性时,加 --target <URL>,按 DNS → TCP → TLS → HTTP 分层检查。报告注明「直连,可能与生产出口不一致」时,结果不代表网关出口的连通性。
7.2 端口与就绪状态的含义
适用场景:验收过程中看到 503、看到某列显示「未核验」、或在 zenova status 里找不到某个服务时,先对照本表再决定要不要处理。
操作步骤
- 遇到下表中的现象,按「含义」列判断是否属于正常状态。
- 不属于正常状态的,回到 7.1 节用
zenova status与zenova doctor定位。
| 现象 | 含义 |
|---|---|
| :-- | :-- |
中心网关节点数据面(3080)的就绪检查返回 503,原因 no_tenant_routes | 正常。还没有租户或还没有配置模型路由。创建租户(第 6.3 节)并完成 7.3 节的模型配置后恢复 |
| 控制面切换槽位后几秒内,内部入口返回 503 | 正常。入口代理会暂存新请求,最长 5 秒 |
| 「模型供应商」列表的「模型真伪」列显示「未核验」 | 与健康状态无关。离线环境无法完成核验时保持「未核验」 |
zenova status 里看不到 postgres、clickhouse、caddy | 正常。它只列 zenova- 开头的服务,其余用 systemctl status <名称> 查看 |
| 「装后验收」中「智能体容器可达性」显示「检查项尚未实现」 | 正常。该项是警告级,当前版本未实现,不影响安装完成 |
| 「网关节点健康」一项等待较久 | 正常。该项最多等 150 秒 |
监听端口的边界:
| 端口 | 监听范围 | 是否允许对外开放 |
|---|---|---|
| :-- | :-- | :-- |
| 业务入口端口(默认 80)、443 | 全部网卡(或安装时指定的绑定网卡) | 允许,安装器在 Linux 上已自动放行 |
| 分离出的管理入口端口 | 同上 | 按客户管理网段要求自行放行,安装器不放行 |
| 3010、3080、3300、3320、3325 | 全部网卡,供本机智能体容器回连 | 不得对外开放 |
| 其余内部服务端口 | 仅回环地址 | 不涉及 |
你会看到:装后验收中的「监听边界」一项已通过;从业务网络只能访问到业务入口(与分离后的管理入口)。
注意:不要用「直接 curl 某个内部端口」来判断平台能不能用。内部端口的返回受租户、路由、槽位切换等状态影响,503 往往是正常状态。能不能用,以装后验收结果、zenova status 与 7.3 节的真实业务调用为准。
注意:3010、3080、3300、3320、3325 监听全部网卡是为了让本机容器回连,安装器不会替你在网络边界上屏蔽它们。请在主机防火墙或云安全组上只对外放行入口端口。
7.3 真实业务调用
适用场景:每个 POC 环境交付前必须完成一次;这是证明「装完能用」的唯一直接依据。
前提:已完成第 6 章(改密、两步验证、创建租户、导入许可证);手上有一个可用的上游模型地址与凭据;租户内已有一名测试成员账号(在租户的「组织与权限」中创建)。模型供应商、模型、模型分组与可用范围由租户管理员操作,平台 root 没有租户归属,不能试跑。
操作步骤
- 添加模型供应商。租户管理员进入「管理控制台 → 模型 → 模型供应商」,选「添加模型供应商」,选择供应商类型、核对「请求地址」与「模型请求格式」、填写凭据,点「验证并获取可用模型」,在模型表中「启用」需要的模型,点「保存模型供应商」。
- 试跑模型。进入「管理控制台 → 模型 → 模型」,打开刚启用的模型详情的「试跑」页签,输入一句话发送,确认返回成功摘要。
- 添加模型分组。进入「管理控制台 → 组织与权限 → 模型分组」,新建模型分组,填写名称,加入刚试跑成功的模型并保存。
- 授权测试成员。在该分组的「可用范围与配额」页签选「编辑可用范围」,勾选测试成员,有效期选「长期有效」或覆盖 POC 周期,保存。
- 测试成员自己创建 API 密钥。测试成员登录,进入「能力中心 → 首页 → API 密钥」,选「创建 key」,填写名称、选择上一步授权的模型分组与计费归属,「确认」后立即复制「API 密钥(仅本次可见)」。管理员不在控制台为成员创建密钥。
- 在业务网络主机上发起真实调用。
# 业务网络中的主机 · 普通用户 · 写入(产生一次真实调用,会计费)
export API_KEY='<测试成员的 API 密钥>'
curl -sS -i "<访问地址>/api/v1/agent-gateway/openai/v1/chat/completions" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"<模型名>","messages":[{"role":"user","content":"你好"}],"max_tokens":32}'
- 记下响应头中的
x-request-id,管理员进入「管理控制台 → 概览」的「网关请求」页签,在搜索框按该请求 ID 搜索,打开详情核对。 - 执行拒绝路径,见 7.4 节。
三种协议的 Base URL(<访问地址> 为安装时填写的访问地址):
| 协议 | Base URL | 鉴权头 |
|---|---|---|
| :-- | :-- | :-- |
| OpenAI | <访问地址>/api/v1/agent-gateway/openai/v1 | Authorization: Bearer <API 密钥> |
| Anthropic | <访问地址>/api/v1/agent-gateway/anthropic | x-api-key: <API 密钥>,也接受 Authorization: Bearer |
| Gemini | <访问地址>/api/v1/agent-gateway/gemini | x-goog-api-key: <API 密钥> 或查询参数 ?key=,也接受 Authorization: Bearer |
你会看到
- 第 1 步:供应商列表中该供应商的「可用」开关为开启,「可用模型」列显示已启用的模型;保存后提示「已保存,模型路由稍后同步」属正常。
- 第 3 步:试跑成功时显示形如「通 · 首字 … · 共 … · … tok · …」的摘要。失败时页面会写明失败发生在本平台侧还是供应商侧,以及按错误码给出的中文原因。
- 第 6 步:预期结果为
HTTP/1.1 200,响应体含模型回复;响应头带x-request-id。 - 第 7 步:「网关请求」中能查到同一次调用,模型、结果、耗时与 Token 用量与本次调用一致。
- 业务方需要其他协议时,用上表的 Base URL 各调一次,预期结果相同。
注意:请求里的 model 必须是该密钥所绑定模型分组中的模型名(模型广场或 GET <OpenAI Base URL>/models 返回的名称),否则返回 404,见 7.4 节。
注意:试跑与真实调用都会真实计费。最近的调用在用量页显示「待计费」,属计费短暂延迟。
注意:交付范围包含 MCP 服务或 API 服务时,再补一次「取一次工具列表 + 一次无副作用的工具调用」,并在 7.6 节单列一行记录。
注意:API 密钥只显示一次,复制后保存在测试机的密钥管理中,不要贴进工单、即时通讯或截图。
7.4 拒绝路径与错误码核对
适用场景:7.3 节正常调用完成之后立即进行。网关「该拒绝的能拒绝、拒绝时说得清原因」与「能调通」同等重要。
操作步骤
- 用不在可用范围内的模型名调用一次:沿用 7.3 节的命令,把
<模型名>换成一个不属于该密钥所绑定模型分组的模型名。 - 用已禁用的密钥调用一次:租户管理员在「管理控制台 → 组织与权限 → 模型分组」的「API 密钥管理」页签找到测试密钥,打开详情点「禁用」(也可由测试成员在「能力中心 → 首页 → API 密钥」中「撤销」一把专门用于测试的密钥),然后用这把密钥再调用一次。
- (可选)把测试成员移出可用范围后调用一次:在「可用范围与配额」中「移除」该成员,再用其有效密钥调用。
- 每次都记录:HTTP 状态码、响应体中的
reason与code、响应头x-request-id与x-should-retry。 - 对能关联到成员的拒绝(如第 1、3 步),按
x-request-id在「网关请求」中查到对应记录,核对结果为失败、原因与响应一致。
# 业务网络中的主机 · 普通用户 · 只读(只看状态行与错误体关键字段)
curl -sS -i "<访问地址>/api/v1/agent-gateway/openai/v1/chat/completions" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"<不在该模型分组中的模型名>","messages":[{"role":"user","content":"你好"}],"max_tokens":8}'
OpenAI 协议的错误体形如 {"error":{"message","type","param","code","reason","request_id"}},其中 reason 是稳定错误码(大写),code 是 OpenAI 兼容码(小写),request_id 与响应头 x-request-id 相同。Anthropic 协议错误体为 {"type":"error","error":{"type","message","reason"},"request_id"};Gemini 协议错误体为 {"error":{"code","message","status","details"}},code 与 HTTP 状态相同。
你会看到(以产品文档站「错误参考」页为准核对)
| 场景 | HTTP 状态 | reason | code(OpenAI 协议) | 预期处理 |
|---|---|---|---|---|
| :-- | :-- | :-- | :-- | :-- |
| 模型名不在密钥绑定的模型分组中 | 404 | LLM_MODEL_NOT_AVAILABLE | model_not_found | 修改请求中的模型名 |
| 密钥已禁用、已撤销、无效或缺失 | 401 | 常见为 UNAUTHENTICATED;401 组内的具体 reason 以实际输出为准 | invalid_api_key | 检查密钥状态、到期时间与鉴权头 |
| 已认证但不在可用范围或授权已过期 | 403 | PERMISSION_DENIED | permission_denied | 管理员核对可用范围与授权有效期 |
| 内容被护栏拦截 | 403 | CONTENT_POLICY_BLOCKED | content_policy_violation | 调整内容后重试 |
| 额度池用尽 | 429 | POOL_EXHAUSTED | insufficient_quota | 错误信息说明对象、周期与恢复时间;管理员调整额度 |
| 命中流量规则限速或并发上限 | 429 | TRAFFIC_RATE_LIMITED、TRAFFIC_CONCURRENCY_LIMITED | rate_limit_exceeded | 稍后重试;仍持续时管理员检查流量规则 |
| 上游限流 | 429 | LLM_RATE_LIMITED | rate_limit_exceeded | 稍后重试 |
| 租户本月 Token 上限用尽 | 402 | MONTHLY_TOKEN_EXCEEDED | insufficient_quota | 平台管理员在「租户管理」中「编辑配额」 |
| 模型路由未配置 | 503 | MODEL_ROUTE_NOT_CONFIGURED | model_route_unavailable | 管理员检查模型供应商、模型的上游与流量规则配置 |
| 流量保护熔断打开 | 503 | TRAFFIC_CIRCUIT_OPEN | circuit_open | 稍后重试;持续时管理员检查流量规则与上游 |
| 上游过载或不可用 | 503 | LLM_OVERLOADED、LLM_PROVIDER_UNAVAILABLE | server_is_overloaded、upstream_unavailable | 稍后重试 |
| 上游服务错误 | 502 | LLM_UPSTREAM_SERVER_ERROR | upstream_server_error | 稍后重试 |
本次验收必须出现的是前两行:第 1 步预期 404 LLM_MODEL_NOT_AVAILABLE,第 2 步预期 401(code 为 invalid_api_key)。其余行是 POC 期间可能遇到的状态,列出供现场判断。
注意:同一个 HTTP 状态码下,不同 reason 的处置完全不同。 例如 403 既可能是可用范围问题(找管理员授权),也可能是护栏拦截(改内容);429 既可能是额度池用尽(重试无用,需调额度),也可能是上游限流(稍后重试即可);503 可能是熔断,也可能是上游过载或模型路由未配置。判断一律看 reason,不看状态码、不解析 message 文本(message 会随版本调整,多数为英文)。
注意:是否值得重试看响应头 x-should-retry:为 true 时可按 Retry-After 等待后重试;为 false 时重试不会改变结果。
注意:401 表示网关没有认出调用方,这类请求不一定能在「网关请求」中按发起人检索到;401 场景以响应本身(状态码、reason、x-request-id)为准记录,控制台能否查到以实际为准。404、403 等已认证的拒绝应能按请求 ID 查到。
注意:「禁用」的密钥不能在控制台重新启用。不要禁用 7.3 节交付给客户使用的那把密钥,拒绝路径请用专门创建的测试密钥。
7.5 可选能力验收
适用场景:本次安装启用了核心之外的能力。只验收本次已采购并启用的能力;产品本身不含、未采购或未启用的能力,在 7.6 节记为「不适用」。
前提:先在控制台「系统维护 › 系统更新」核对能力状态。能力显示「本机已有,未启用」表示未启用;显示「许可证未包含此能力」表示许可证未覆盖。这两种情况都记为「不适用」,不要为了验收临时启用。
操作步骤
按下表逐项核对。
| 能力 | Zentrix 网关 | 完整版 | 验收方法 | 预期结果 |
|---|---|---|---|---|
| :-- | :-- | :-- | :-- | :-- |
| 语义缓存 | 随核心提供 | 随核心提供 | ① 在「系统设置 › 全局设置 ›「常规」页签 › 默认模型」中设置「语义缓存向量模型」和「语义缓存重排模型」,两项均显示「已生效」;② 在「流量 → 流量规则」中给一条不指定转发目标的规则添加「语义缓存」动作;③ 用同一句话、OpenAI Chat Completions 单轮请求调用两次;④ 在「网关请求」中打开第二次调用的详情 | 第二次调用的上游各段显示「命中语义缓存,未请求上游」;用量中出现「语义缓存向量」「语义缓存重排」两类调用 |
| 知识库 | 可选(需许可证包含知识库) | 可选 | ① 管理员在「知识库管理」中创建知识库并设置分发目标;② 维护者上传一份文档,等待状态变为「可用」;③ 在库详情「检索」页签输入文档中的关键词 | 能命中刚上传的内容并查看原文片段;顶部页签出现「知识库」 |
| 文档解析 | 不适用(网关版不含) | 可选 | 在知识库中上传 PDF 或 Office 文档 | 文档状态变为「可用」,检索能命中文档正文;解析失败的文档标注原因 |
| 托管智能体 | 不适用(网关版不含) | 可选 | 创建一个智能体、发布,在对话中调用一次 | 智能体正常回复;具体步骤以完整版用户手册为准 |
| 数据高可用 | 多机方案使用 | 多机方案使用 | 单机 POC 不涉及 | 单机 POC 记为「不适用」 |
你会看到
- 已启用的能力在「系统更新」的能力列表中显示为已启用。
- 两个语义缓存模型未设置时,开启语义缓存的规则无法保存;模型不可用或调用失败时,第二次调用仍会请求上游,请求详情写明原因,例如「未参与:语义缓存向量模型不可用」。
- 保存语义缓存重排模型时,系统用内置样例实际调用该模型并确定命中标准;不能区分同义与非同义问法的模型无法保存,需换用其他重排模型。
- 知识库:许可证不含知识库或部署未安装时,能力中心的「知识库」页签和管理控制台的「知识库管理」菜单都不显示。
注意:语义缓存只对 OpenAI Chat Completions 格式、只有一条用户消息(可另带系统或开发者消息)、请求体不超过 256 KiB 的单轮请求生效。通过 OpenAI 兼容入口(/api/v1/agent-gateway/openai/v1/*)调用时,规则链中带多个转发目标或故障转移、单次请求 Token 上限、挂载插件、响应改写、输出检测或改写请求头时,以及「应用限额」排在内容检测、提示词或请求改写之前时,这次请求不查也不写缓存;其余带限额的规则和转发到单个指定上游的规则不影响缓存。验收时缓存不命中,先在调用详情「路由与改写」页签的「请求去向」中查看「语义缓存」一行写明的原因。语义缓存属于动态路由许可模块,许可证未包含时记为「不适用」。使用 OceanBase 作为平台数据库的部署不支持语义缓存,记为「不适用」。
注意:知识库更换嵌入模型会触发全部文档重建向量索引,重建期间语义检索暂停。验收前先确定嵌入模型。
注意:托管智能体与文档解析需要容器运行时;只有托管智能体需要给服务用户容器运行时权限,该权限等同于宿主机 root 权限,启用托管智能体前须取得客户安全负责人的书面同意(第 3.4 节)。
7.6 验收记录表
适用场景:验收全程边做边填,完成后由实施方与客户方共同签字,随交接材料归档。
操作步骤
- 先填写环境信息。
- 逐行执行并填写「结果」:
完成、未完成(附原因与诊断代码或 reason)、不适用。 - 请求类条目在「结果」中写明
x-request-id。
环境信息:
| 项目 | 填写 |
|---|---|
| :-- | :-- |
| 产品 | Zentrix 网关 / 完整版 |
| 版本号(完整) | |
| 平台与部署形态 | |
| 已启用能力 | |
| 访问地址 | |
| 安装根 | 默认 /opt/zenova |
| 数据依赖部署方式(PG / CH / 对象存储) | |
| 许可证 License ID 与到期时间 |
验收项:
| 验收项 | 方法 | 结果 | 记录人 | 时间 |
|---|---|---|---|---|
| :-- | :-- | :-- | :-- | :-- |
| 装后验收 | 安装完成输出与「部署配置 › 最近一次验收」无阻断项 | |||
| 服务状态 | sudo zenova status,全部 zenova- 服务运行中 | |||
| 基础服务 | systemctl status 查看 postgres、clickhouse、caddy、secret-service、spicedb(及 rustfs) | |||
| 本机体检 | sudo zenova doctor --all --save …,退出码 0;告警项已记录 | |||
| 监听边界 | 3010/3080/3300/3320/3325 未对外开放;仅入口端口对外 | |||
| 网关节点 | 控制台中 office-primary 在线 | |||
| 模型供应商 | 「验证并获取可用模型」成功,已启用模型 | |||
| 模型试跑 | 「试跑」返回成功摘要 | |||
| 可用范围 | 测试成员已加入「可用范围与配额」 | |||
| 成员自建密钥 | 测试成员在「能力中心 → 首页 → API 密钥」创建成功 | |||
| 真实调用(OpenAI) | curl 返回 200 + 模型回复;记录 x-request-id | |||
| 真实调用(Anthropic) | 按需;返回 200 | |||
| 真实调用(Gemini) | 按需;返回 200 | |||
| 调用记录 | 「网关请求」按请求 ID 查到同一次调用,模型/结果/耗时/用量一致 | |||
| 拒绝:模型不在范围 | 404 LLM_MODEL_NOT_AVAILABLE;控制台可查到 | |||
| 拒绝:密钥已禁用 | 401,code 为 invalid_api_key;记录实际 reason | |||
| 拒绝:成员移出范围(可选) | 403 PERMISSION_DENIED | |||
| 工具调用(含 MCP / API 服务时) | 取一次工具列表 + 一次无副作用工具调用 | |||
| 语义缓存 | 第二次同句调用显示「命中语义缓存,未请求上游」 | |||
| 知识库 | 上传文档状态「可用」,检索命中 | |||
| 文档解析 | 网关版记「不适用」 | |||
| 托管智能体 | 网关版记「不适用」 | |||
| 数据高可用 | 单机 POC 记「不适用」 | |||
| 运维通知 | 通知渠道测试消息已收到(未配置时记「未配置」) | |||
| 密钥材料离机备份 | 第 8.1 节完成并登记 | |||
| 首次平台备份 | 第 8.2 节完成,记录备份标识与转存位置 |
签字:
| 角色 | 姓名 | 签字 | 日期 |
|---|---|---|---|
| :-- | :-- | :-- | :-- |
| 实施工程师 | |||
| 客户方系统管理员 |
注意:表中出现「未完成」的条目,必须写明原因、诊断代码或 reason、责任方与计划完成时间,不得留空。依赖客户外部条件(如上游模型出网、许可证尚未签发)的条目,写明条件后记为「未完成」,不要记为「不适用」。
能力说明
| 不提供的能力 | 替代做法 |
|---|---|
| :-- | :-- |
| 一条命令完成端到端业务验收 | 装后验收与 zenova doctor 只覆盖平台与本机;模型、授权、调用与拒绝路径按 7.3、7.4 节在控制台与调用方手动完成 |
| 管理员在控制台替成员创建 API 密钥 | 由测试成员登录后在「能力中心 → 首页 → API 密钥」自己创建;管理员只能检索、轮换、禁用、删除 |
| 用内部端口的返回判断平台是否可用 | 以装后验收、zenova status 与真实业务调用为准(7.2 节) |
| 被禁用的密钥在控制台重新启用 | 新建一把密钥替换;拒绝路径使用专门的测试密钥 |
| 平台 root 账号直接试跑模型 | root 没有租户归属;以租户管理员身份试跑 |
| 「智能体容器可达性」装后验收 | 当前版本显示「检查项尚未实现」,属警告级;按 7.5 节用控制台功能核对对应能力 |
---