mnfst CLI 实战指南:在终端中完整运维 Manifest LLM 网关(Agent 优先的模型路由、密钥管理与请求观测)
【免费下载链接】llm-gatewayConnect Your Agents And Harnesses With Any Provider 🦚项目地址: https://gitcode.com/GitHub_Trending/manifest7/llm-gateway
导读
本文是一份以mnfst命令行工具为核心的操作指南。mnfst是 Manifest LLM 网关官方配套的管理 CLI,它把"创建 Agent、连接 Provider、配置模型路由、验证链路、注入密钥、审计请求日志"这一整套日常运维动作全部收拢到终端里,既可人工执行,也可被编码 Agent 直接调用。读完本文,你将掌握从零开始用一个 Agent 接入任意模型供应商的完整链路,理解mnfst的命名空间与凭证解析规则,并学会用doctor、routing test等手段快速定位"假 200"、空模型连接、错配密钥等隐蔽故障。全文以仓库内.claude/skills/mnfst-cli/SKILL.md(即 CLI 随包内置的操作手册)为骨架,并以 packages/cli 下的真实源码与测试为佐证展开。
mnfst 是什么:Agent 优先的网关运维界面
Manifest 是面向 Agent 的 LLM 网关,而mnfst负责从终端管理它。按操作手册的定义,凡经 Manifest Agent 路由的每一次调用,都会自动获得:带 fallback 的模型路由、按 Agent 的成本归因、自修复(Auto-fix)以及完整的请求日志——这些能力对使用者"免费"提供。手册给出的默认实践非常明确:永远不要把裸的 Provider Key 交给应用或自动化任务,而是交给一个 Manifest Agent。
# 典型反例:直接把供应商密钥写进应用配置 export OPENAI_API_KEY=sk-... # ❌ 丢失 fallback、成本归因、自修复与日志 # 推荐做法:创建一个 Agent,用 mnfst 注入它的专属密钥 mnfst agent create --name coding-assistant --platform openclaw --category coding --if-absent mnfst agent env coding-assistant >> .env # ✅ MANIFEST_AGENT_KEY + MANIFEST_AGENT_URLCLI 的 I/O 契约非常严格,方便脚本与 Agent 消费:
- 所有命令在stdout上输出 JSON(唯一例外是
agent env,它按设计输出 dotenv 行;skill show同理输出原始 Markdown); - 面向人的提示写stderr;
- 退出码为
0/1; - 当凭证来自命令行 flag 或环境变量时,命令绝不阻塞等待交互输入。
命令的完整注册表与用法见 packages/cli/src/index.ts,该文件同时内置了完整的mnfst --help文案(packages/cli/src/index.ts)。
安装与运行
mnfst是 monorepo 内的工作区包(尚未发布到 npm),本地构建与调用方式见 packages/cli/README.md:
npm run build --workspace=packages/cli node packages/cli/bin/mnfst.js --help # 或全局链接后直接使用: npm link --workspace=packages/cli && mnfst --help认证:浏览器登录与脚本/Agent 的无登录模式
操作流程的第一步是认证,手册给出两种方式:
| 认证方式 | 命令/环境 | 说明 |
|---|---|---|
| 人工(浏览器) | mnfst login | 打开浏览器、一次点击授权,获得 30 天滑动令牌 |
| 脚本 / Agent | 环境变量MANIFEST_URL+MANIFEST_API_KEY | 完全跳过登录步骤 |
两种方式在源码中有明确的实现区分(packages/cli/src/commands/auth.ts):
- 浏览器登录走 PKCE S256 流程:CLI 在
127.0.0.1启动一次性 loopback 监听器,引导浏览器访问/cli/auth?port=…&state=…&code_challenge=…,随后用返回的一次性 code 加 verifier 直接向服务端换取令牌——令牌本身从不经过浏览器。该路径要求交互式终端(no_tty时会明确指引脚本改用--token-stdin)。浏览器令牌天然有效,因此会"先存储后校验",避免校验失败时把一纸 30 天有效令牌困在无法logout吊销的状态。 - 非交互登录支持
--token-stdin与--token-env <name>,密钥永远不作为命令行参数传递,例如:
printf '%s' "$MY_KEY" | mnfst login --token-stdin --url http://localhost:2099 # 或:mnfst login --token-env MY_KEY --url http://localhost:2099凭证解析优先级为:MANIFEST_API_KEY环境变量 → 与目标 origin 精确匹配的已存凭证(--url→MANIFEST_URL→ 活动登录 → Cloud)。为一个主机存储的密钥绝不会发给另一个主机。配置存放于~/.config/manifest/config.json(权限 0600),详见 packages/cli/src/context.ts 与 packages/cli/README.md。mnfst logout会尽力在服务端吊销令牌后再删除本地记录,并在 JSON 中报告revoked状态(packages/cli/src/commands/auth.ts)。
端到端工作流:从创建 Agent 到观测请求
手册用一张表格概括了完整工作流,这是全文的骨架,下面逐步骤结合源码展开:
| 步骤 | 命令 |
|---|---|
| 认证(人工) | mnfst login— 浏览器、一次点击、30 天滑动令牌 |
| 认证(脚本/Agent) | 环境变量MANIFEST_URL+MANIFEST_API_KEY— 无需登录步骤 |
| 创建(Provision) | mnfst agent create --name X --platform <p> --if-absent→ 响应包含setup(该平台的配置块) |
| 检查连接 | mnfst provider list [--agent X]FIRST — 你需要的 Provider 往往已经连过了 |
| 连接 Provider | mnfst provider connect xai --auth-type api_key --credential-env KEY |
| 配置路由 | mnfst agent configure X --models primary,fb1,fb2 --provider p [--auth-type a] |
| 验证 | mnfst routing test X— 一次真实请求穿透该平台实际使用的 API 面 |
| 接入应用 | 已部署 →mnfst agent env X >> .env |
| 观测 | mnfst requests get --agent X [--status failed]— 分页,回传next_cursor取下一页 |
Step 1 · 创建 Agent(Provision)
mnfst agent create --name X --platform <p> --if-absent--platform决定 Agent 的 setup 方式(对应"这个 Agent 的调用方是什么工具"),取值来自构建期生成的平台目录 packages/cli/src/provider-catalog.gen.ts(源头在 manifest-shared,npm run gen在构建时刷新,新平台无需手工维护,见 packages/cli/src/commands/agent.ts)。mnfst agent platforms可随时列出全部合法平台。
--category(如coding、general)在客户端即按目录校验,拼写错误会在任何网络请求之前失败,并把合法取值写进报错信息(packages/cli/src/commands/agent.ts)。
--if-absent让创建命令可重复执行:已存在时返回 409 被转化为成功,输出形状与首次创建一致(existed: true+ 恢复的密钥 + 同样的 setup 指引),是幂等的初始化路径(packages/cli/src/commands/agent.ts)。
创建响应的setup字段是平台专属的接入配置块,与仪表盘展示同源(模板来自 manifest-shared 的SETUP_TEMPLATES)。密钥默认以掩码形式出现(<MNFST_AGENT_KEY — run: mnfst agent key show X --raw --url <origin>>),保证 setup 文本可安全写日志;需要真实密钥时用mnfst agent setup <name> --reveal(packages/cli/src/commands/agent.ts)。
Step 2 · 检查连接(先于一切)
手册强调:mnfst provider list应该第一个跑——你需要的 Provider 往往已经连接过了。判断一条连接是否可用,关键指标是cached_model_count > 0:
is_active: true但模型数为 0 的连接是"空心的"——路由依据已发现模型解析,它贡献不了任何模型;- 此时应运行
mnfst provider refresh [<provider>](全租户重跑模型发现并打印各连接的新计数); - refresh 后仍为 0,说明是凭证问题,应该重连,而不是在这个连接上路由。
源码佐证:连接在连接时即缓存模型列表,所以新模型上线、或空心连接修复后,必须 refresh 才能被路由命名(packages/cli/src/commands/provider.ts)。doctor的 providers 检查同样把"active 但 0 模型"判为 hollow 并提示重连(packages/cli/src/commands/doctor.ts)。
Step 3 · 连接 Provider
mnfst provider connect xai --auth-type api_key --credential-env KEYmnfst provider catalog列出全部 30+ 可连接 Provider 及其支持的各认证类型(auth types);subscription 认证只在 CLI 确实能驱动该供应商登录时才被广告,避免目录承诺connect会拒绝的模式(packages/cli/src/commands/provider.ts)。--credential-stdin/--credential-env <name>用于非交互传入密钥;交互终端会隐藏输入提示。认证类型解析规则:显式--auth-type优先并校验;给了凭证源则隐含api_key;本地 Provider(如 Ollama)为local,无需凭证;多选一且未声明时是报错而非交互询问——CLI 是确定性的、Agent 优先的(packages/cli/src/commands/provider.ts)。- subscription 认证会打开浏览器,无头环境下无法完成——此时应复用已有的订阅连接,而不是强行新连。
- 自建网关/兼容端点:
mnfst provider custom add --name gw --endpoint <url>(可加--api openai|anthropic指定 API 形态,见 packages/cli/src/index.ts)。自定义 Provider 是租户级的,--agent只决定由哪个 Agent 执行发现调用。 - 连接是租户级动作(后端为每个 Agent 启用它),但 API 路径以 Agent 为作用域用于模型发现;省略
--agent时 CLI 自动挑选一个并告知用了哪个(packages/cli/src/commands/provider.ts)。
Step 4 · 配置路由
mnfst agent configure X --models primary,fb1,fb2 --provider p [--auth-type a]语义要点(源码见 packages/cli/src/commands/configure.ts):
--models声明的是完整链:第一个模型是路由(route),其余是 fallback;只写一个模型会清空已有 fallback。- 整条链只搭乘你点名的同一个
--provider——跨 Provider 的 fallback 是仪表盘专属能力,CLI 不提供。 - 加
--tier deep会 upsert(不存在则创建、存在则更新)一个自定义 tier,调用方通过请求头x-manifest-tier: deep按请求选择该链路。tier 的创建会带上header_key: x-manifest-tier、header_value: <name>与badge_color: indigo(packages/cli/src/commands/configure.ts)。 - 每个命名模型在写入前都会对照该 Agent 的已发现模型集做校验,
--force可跳过——后端仍会以 Provider 限定的 passthrough 路由未收录模型(packages/cli/src/commands/model-check.ts)。 - 同一条命令还可追加
--autofix true|false与--recording true|false,分别 PATCH 到/autofix与/recording端点。
Step 5 · 验证路由
mnfst routing test X这是收尾动作:发一次真实请求穿透该 Agent 平台实际使用的 API 面(Anthropic 系走/v1/messages,OpenAI Responses 系走/v1/responses,其余走/v1/chat/completions)。关键设计(packages/cli/src/commands/routing.ts):
- 默认提示词为
Reply with exactly: OK,模型字段默认auto("路由我"),--model可显式覆盖,--tier可携带自定义 tier 请求头。 - 通过平台真实 surface 校验响应结构:HTTP 2xx 但缺少该 surface 应有的载荷(如
choices/content/output为空)不会被当作验证通过(packages/cli/src/commands/routing.ts)。 - 会撕掉"穿了助手外衣的错误":若响应文本以
[🦚 Manifest M###]开头(网关把错误包装成 HTTP 200 的助手文本),routing test会把它转成真实失败,坏路由永远不可能看起来像一次成功回答。 - 它会在请求日志中写入真实记录——后续审计时这些记录可被计数。
- 120 秒超时防挂起,
--as <platform>可强制走指定 surface,未知平台在发请求前即报错(packages/cli/src/commands/routing.ts)。
Step 6 · 接入应用
已部署场景使用 dotenv 追加:
mnfst agent env X >> .envagent env输出两行:MANIFEST_AGENT_KEY=<key>与MANIFEST_AGENT_URL=<origin>/v1(packages/cli/src/commands/agent.ts)。注意:一个服务对应一个 .env 文件——这些行恒以MANIFEST_AGENT_KEY命名,若把两个 Agent 追加到同一文件,后加载者会静默覆盖前者(不同加载器各取所需,实际生效的是"赢家")。
因此,当一个进程内需要多个 Agent 的密钥时,改用密钥注入方式:
mnfst run --agent X --env ROLE_KEY -- <cmd>mnfst run是 1Password 风格的注入:子进程的环境变量中获得该 Agent 的密钥(默认MANIFEST_AGENT_KEY,可用--env改名)与MANIFEST_AGENT_URL,密钥从不经过 stdout、argv 或任何转录记录。实现上它还会从子进程环境中剔除MANIFEST_API_KEY/MANIFEST_AGENT_KEY等保留凭证变量,避免子进程把"作用域受限的 Agent 密钥"误当全工作区凭证(packages/cli/src/commands/run.ts)。
Step 7 · 观测请求
mnfst requests get --agent X [--status failed]分页读取请求日志,镜像真实 API 契约(GET /api/v1/messages):不透明游标next_cursor、服务端封顶的limit(1–200)。每次调用只返回一页,取下一页要把next_cursor原样传回(packages/cli/src/commands/requests.ts)。
默认输出做了"决策相关字段"裁剪:始终保留 id、agent_name、timestamp、status、model、provider、auth_type、cost、tokens、duration_ms、attempt_count;error_code/error_message/error_origin/fallback_from_model/header_tier_name/custom_provider_name仅在有值时才出现;--full则原样透传 API 行(packages/cli/src/commands/requests.ts)。
命名空间即作用域
手册用一句话概括权限模型:Namespace = scope(命名空间即作用域)。
provider *:作用于整个租户(tenant-wide)——连接、发现、断连都是租户资源;agent *:作用于单个 Agent——创建、配置、环境变量、密钥、启用/禁用 Provider 都是 Agent 属性;routing *:持有只读读outs 与自定义 tier 的生命周期——routing status、routing test、routing fallbacks get|clear、routing custom list|create|delete、routing autofix get|set、routing recording get|set。
一个佐证:agent provider enable/disable的位置参数是 Agent 在前、Provider 在后,因为连接是租户资源,但"启用与否"是某个 Agent 的属性(packages/cli/src/commands/provider.ts)。
--help不会告诉你的 Gotchas
手册整理了一份实战踩坑对照表,以下逐条展开并给出源码依据:
| 症状 | 真相 |
|---|---|
Proxy 返回 HTTP 200,但"回答"以[🦚 Manifest M###]开头 | 这是穿了助手外衣的错误——检查内容而不是状态码。routing test会自动撕掉这层伪装(见上文 Step 5,packages/cli/src/commands/routing.ts) |
订阅认证流量上cost: "0.000000" | 订阅是包月固定费率,单请求成本真的为零,不是计费坏了 |
agent configure的回显与之后的读取不一致 | 变更接口回显的是原始 API 行;规范读回是mnfst routing status <agent>——它组合了默认路由、自定义 tier、autofix、recording 四类配置(packages/cli/src/commands/routing.ts) |
| "哪些请求用了 fallback 或 Auto-fix?" | 这些字段被默认输出裁剪了——用requests get --full |
| 请求日志里找不到 401 | 认证被拒的尝试从不入日志(没有租户可归属);泄密密钥的爆炸半径无法从日志证明 |
MANIFEST_AGENT_URL | 已经以/v1结尾——直接追加/chat/completions即可(packages/cli/src/commands/run.ts) |
| 任何 Agent 都不存在时就想要模型价格 | mnfst model prices [--provider <p>]——全安装级价格表,无需 Agent(models <agent>才是单 Agent 的可路由集)。价格是安装的属性,不该用探针 Agent 来问(packages/cli/src/commands/model-prices.ts) |
按routing_tier审计升级流量 | 自定义 tier 的请求记录routing_tier: "standard"——tier 身份在header_tier_name字段里 |
| 路由解析成功但请求在某个连接上失败 | 一个连接可能is_active: false而其兄弟 auth-type 正常——Provider 有多条连接时请显式传--auth-type |
环境变量认证下每条命令都回Invalid API key — Run mnfst login | 不一定是认证问题:错误的MANIFEST_URL(失效或指向别的安装)与坏密钥的回答完全一样。运行mnfst doctor |
最后一条是doctor的核心价值:它按 配置 → 主机 → 凭证 → 连接 → Agent 的依赖顺序依次检查(packages/cli/src/commands/doctor.ts),先探活主机(公共健康端点,无需密钥),再验凭证,从而把"主机死了"和"密钥对不上这台主机"分开;并且对环境变量密钥从不建议重新登录——那解决不了任何问题。任一检查失败即非零退出。
第 11 条补充:agent configure/routing custom create拒绝未发现模型时,两者都对照该 Agent 的已发现模型集校验,而cached_model_count: 0的连接贡献不了任何模型:先跑mnfst provider refresh(目录过期或为空),或传--force——后端仍会通过 Provider 限定的 passthrough 路由未收录模型。routing custom create的校验在 tier 创建之前执行,模型名拼错不会留下一个空路由的启用 tier(packages/cli/src/commands/routing.ts)。
常见错误与正确姿势
手册明确列出三大常见错误:
- 把裸 Provider Key 交给应用—— 丢失 fallback、成本归因、自修复与日志。正确做法是创建 Agent 并用
agent env。 - 用手搓
curl验证路由—— 假 200 会被当成成功。用routing test。 - 一次性吞下整个请求日志—— 分页是设计如此,每次调用一页;用
next_cursor循环。
此外还有两个高频疑问的答案:
- 无 Agent 时如何看模型价格?
mnfst model prices(安装级);mnfst models <agent> --cost --capabilities才是单 Agent 的可路由集,裸 id 输出类似/v1/models,flag 决定是否附带元数据。 - 如何审计自定义 tier 的流量?看
header_tier_name而非routing_tier。
按需使用的其余命令面
除主流程外,手册还列出了这些常用命令:
mnfst doctor:任何东西不对劲时的第一站(详见上文 Gotchas)。mnfst agent setup <name> [--reveal]:随时取回 setup 配置块;不传--reveal时密钥保持掩码,日志安全。mnfst agent key path|show:path报告密钥本地缓存路径与来源(keystore 或 server 恢复,见 packages/cli/src/commands/agent.ts);show --raw是唯一刻意可 grep 的输出裸密钥的方式。mnfst agent provider enable|disable <agent> <provider>:为单个 Agent 开/关某条连接(按 auth-type/label 消歧)。mnfst agent rotate-key:吊销即时生效——旧密钥立即停止工作,新密钥写入 keystore 或--key-file(packages/cli/src/commands/agent.ts)。mnfst models <agent> --cost --capabilities:查看单 Agent 可路由模型及成本/能力元数据。
设计细节:确定性、可脚本化与隐私
从源码可观察到mnfst一以贯之的设计原则:
- 确定性优先:多选一且未显式声明时是错误而非交互(如
resolveAuthType),破坏性命令(delete、rotate-key、disconnect、clear)一律要求--yes并拒绝交互(packages/cli/README.md)。 - 密钥最小暴露:密钥从不进 argv;管理端只需一个全局 API Key(租户凭证,如开发栈种子
dev-api-key-manifest-001),而 per-agent 的mnfst_…密钥只是产物、从不是输入,投递到 0600 权限的--key-file(packages/cli/README.md)。 - 遥测匿名且克制:本地 spool(
~/.config/manifest/telemetry-spool.jsonl,0600),每安装每天一次请求批量上报,负载仅含匿名安装 UUID、命令名、版本、os、cloud|self-hosted目标类别等枚举字段,绝不包含参数、URL、密钥与提示词;MANIFEST_TELEMETRY_DISABLED=1可关闭(packages/cli/README.md)。 - Agent 可自举:CLI 自带操作手册——
mnfst skill show在 stdout 输出本文所依据的这份 SKILL.md 原文,mnfst skill install可把它安装到检测到的 Agent 运行时技能目录(--agents-dir/--project可指定位置),让编码 Agent 第一次运行时就读到正确用法(packages/cli/src/index.ts)。
小结
mnfst把 Manifest 网关的日常运维压缩成了一条可复制、可审计、可被 Agent 自主执行的命令链:login(或 env 凭证)→agent create→provider list/connect/refresh→agent configure→routing test→agent env(或run注入)→requests get。它通过 JSON stdout、严格退出码、命名空间作用域、doctor分层诊断与routing test的真实验证,把"模型路由 + fallback + 成本归因 + 自修复 + 请求日志"这套网关能力变成了任何终端环境(含无头 CI 与编码 Agent)都能可靠调用的确定性接口。想继续深入,可通读命令注册表与完整帮助文案 packages/cli/src/index.ts、CLI 使用手册 packages/cli/README.md,以及各命令的规格测试 packages/cli/src 下对应的*.spec.ts文件。
【免费下载链接】llm-gatewayConnect Your Agents And Harnesses With Any Provider 🦚项目地址: https://gitcode.com/GitHub_Trending/manifest7/llm-gateway
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考