news 2026/9/10 14:03:39

Codewhale 手册级实战:用 Opt-in Live Smoke 在真实模型链路上验证运行收据

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Codewhale 手册级实战:用 Opt-in Live Smoke 在真实模型链路上验证运行收据

Codewhale 手册级实战:用 Opt-in Live Smoke 在真实模型链路上验证运行收据

【免费下载链接】CodewhaleOpen-source coding agent for your terminal, built in Rust and on a journey of continuous community improvement. Issues and PRs welcome.项目地址: https://gitcode.com/GitHub_Trending/de/Codewhale

本文是 CodeWhale 官方《Live Smoke》指南的深度解读。CodeWhale 是一个用 Rust 构建的终端开源编码代理,其自动化测试套件刻意保持“无外部模型供应商依赖”;而本篇介绍的live smoke(实时冒烟运行)是一套手动、可选、永不自动触发的诊断流程,用于回答一个非常狭窄的问题:在这台机器上,一条通往真实模型的路由是否返回了格式良好的运行收据(receipt)?读完本文你将掌握:如何用一次性隔离目录与隐藏式凭据输入发起真实模型调用、如何区分--json一次性收据与stream-json流式元数据收据、以及该流程“能证明什么、不能证明什么”的严格边界。

Live Smoke 是什么:与 CI 无供应商套件的边界

CodeWhale 仓库的自动化体系(CI、测试、构建脚本、skill)默认不携带任何真实模型供应商凭据——这是刻意设计。哪些行为可以在“没有外部供应商”的前提下被确定性断言,由crates/tui/assets/skills-catalog-matrix.json及其 catalog-matrix 测试共同约束(对应实现见 catalog_matrix.rs)。技能目录注册、别名解析、语言环境路由、提示词预算等都属于这套 provider-free 套件的管辖范围。

因此,docs/LIVE_SMOKE.md描述的 live smoke不是 CI 任务、不是测试用例、也不是 skill,仓库中没有任何自动化机制会运行下面的命令。它只在你想要回答上面那个“窄问题”时手动执行:真实路由 → 真实模型 → 在这台机器上是否产出良构收据。

一次 live smoke 能证明什么、不能证明什么

问题是否能在此回答
收据是否记录了我要求的 provider / model?✅ 能。但这本身证明是哪个网络端点处理了请求。
运行是否产出可检查的 route/usage 收据?✅ 能(当 harness 推进到该阶段时)。
一次响应能否证明我的账户 entitlement 状态?不能。provider 配置、认证/entitlement、harness 行为在得到佐证前都是候选原因。
模型是否在语义上选对了 skill?❌ 不测量。
技能注册表 / 目录 / 别名行为是否正确?❌ 不能——这是无供应商套件的职责。

这些运行应当被当作调查起点(investigation starting points),而不是已被证实的故障类别。原文档给出了两类典型观察及其解读纪律:

  • Provider 错误响应——HTTP 401/403、unknown-model、配额或区域类错误,可能反映:配置的 provider/端点、凭据认证或 entitlement、provider 可用性,或 harness 的路由/请求缺陷。响应本身无法区分这些原因。
  • 收据或进程异常——收据中provider/model写错、收据字段缺失、崩溃、或未使用隔离状态目录,都是值得去调查 harness 的证据;但仍需最小化复现或其他佐证才能归因。

从源码结构可以印证这一谨慎立场:在crates/tui/src/exec_agent.rs中,route_sourceapproval_posturesandbox_posture等字段均由 harness 一侧计算并写入元数据,它们代表的是“harness 声称的路由/姿态”,而不是对端网络实体的独立证明。

隔离规则:这些片段遵循的 5 条约束

live smoke 的每条命令都刻意把“宿主环境”与“被测试环境”隔离。原文档归纳为 5 条规则:

  1. env -i清空继承环境——宿主HOMECODEWHALE_HOME、以及一切*_API_KEY都不会被带入,只有env行上显式列出的变量存活。
  2. 只有CODEWHALE_HOME指向任务专属的一次性目录——CodeWhale 配置、会话、内置 skill 安装全部落入 scratch 状态;HOME刻意保持未设置,smoke 运行绝不复用宿主HOME
  3. 凭据变量名由你自己指定(CW_SMOKE_CRED_VAR——不根据 provider 做任何猜测。
  4. 隔离子进程以“回显关闭”方式读取密钥——通过stty -echo隐藏输入,并在EXITINTHUPTERM上恢复终端状态;密钥只在那个子进程内export不落盘、不进命令行参数、不进 shell 历史
  5. PATH被显式转发,且是唯一被带入的宿主变量。

脚本全程使用可移植shsttymktemp -d是仅有的两个非 POSIX 便捷工具,而两者在 macOS 与主流 Linux 上都存在。

步骤 1 — 创建一次性状态目录(两种运行共用)

CW_SMOKE_CODEWHALE_HOME="$(mktemp -d)" || exit 1 mkdir -p "$CW_SMOKE_CODEWHALE_HOME/tmp" echo "scratch Codewhale state: $CW_SMOKE_CODEWHALE_HOME"

mktemp -d生成一个随机目录名,避免与既有配置、历史会话或已安装的 skill 冲突——这正是“隔离状态目录”要求的具体落地:任何写入 Codewhale 状态的东西都会落在这里而不是宿主目录。

步骤 2 — 命名凭据变量

CW_SMOKE_CRED_VAR必须是provider 期望的环境变量名。CodeWhale 的 provider 凭据解析由crates/config/src/provider.rs承载:

  • Moonshot/Kimi 路由读取MOONSHOT_API_KEY(或KIMI_API_KEY);
  • DeepSeek 路由读取DEEPSEEK_API_KEY
CW_SMOKE_CRED_VAR="MOONSHOT_API_KEY" # 由你选择;不进行任何推断

注意:运行命令是在隔离的子进程内部提示输入该变量的值(回显隐藏),它不会创建任何凭据文件——这与 CodeWhale 日常的配置文件凭据来源是两条完全不同的通道。

步骤 3a — 运行 A:Kimi K3

kimi-k3是本构建已知的一个模型 id。需要理解的是,路由由配置的 provider 及其解析出的端点决定--provider moonshot选择已配置的 Moonshot 路由;若选择opencode_go,则选择那条单独配置的路由。账户不在这两者之间选择,harness 也不会依据响应在两者间切换。按你打算测试的路由设置CW_SMOKE_PROVIDER/CW_SMOKE_MODEL。如果返回 model-not-found,在 provider/端点配置、凭据访问与 harness 请求三方面被佐证之前,这只是一个未分类的结果

CW_SMOKE_PROVIDER="moonshot" CW_SMOKE_MODEL="kimi-k3" CW_SMOKE_EFFORT="medium" CW_SMOKE_PROMPT="Reply with exactly: SMOKE OK" env -i \ PATH="$PATH" \ TMPDIR="$CW_SMOKE_CODEWHALE_HOME/tmp" \ CODEWHALE_HOME="$CW_SMOKE_CODEWHALE_HOME" \ CW_SMOKE_CRED_VAR="$CW_SMOKE_CRED_VAR" \ sh -c ' CW_SMOKE_STTY_STATE="$(stty -g)" || exit 1 restore_terminal() { stty "$CW_SMOKE_STTY_STATE" 2>/dev/null || : } trap "restore_terminal" EXIT trap "restore_terminal; exit 129" HUP trap "restore_terminal; exit 130" INT trap "restore_terminal; exit 143" TERM printf "Paste value for %s (input hidden): " "$CW_SMOKE_CRED_VAR" >&2 stty -echo || exit 1 if ! IFS= read -r CW_SMOKE_CRED; then printf "\nCredential input failed.\n" >&2 exit 1 fi restore_terminal trap - EXIT HUP INT TERM unset CW_SMOKE_STTY_STATE printf "\n" >&2 export "$CW_SMOKE_CRED_VAR=$CW_SMOKE_CRED" unset CW_SMOKE_CRED exec codewhale exec \ --provider "$1" --model "$2" --reasoning-effort "$3" --json "$4" ' sh "$CW_SMOKE_PROVIDER" "$CW_SMOKE_MODEL" "$CW_SMOKE_EFFORT" "$CW_SMOKE_PROMPT"

这一段值得逐层拆解(对应规则 4 的实现细节):

  • 进入子进程后先把stty -g保存为CW_SMOKE_STTY_STATE
  • 定义restore_terminal()并注册到EXIT/HUP/INT/TERM,保证任何中断路径都会把终端恢复为可读状态;
  • stty -echo关闭回显 → 隐藏式读取一次密钥 → 立即restore_terminal并清空 trap;
  • 通过export "$CW_SMOKE_CRED_VAR=$CW_SMOKE_CRED"仅在本子进程内注入凭据,随后unset CW_SMOKE_CRED
  • 最后exec codewhale exec …用注入后的环境完成一次性调用,凭据不会出现在任何命令行参数里。

关于命令行参数本身,从crates/tui/src/lib.rsExecArgs的定义可以看到与上文一致的契约:

  • --provider:非密钥的 provider 标识符,凭据仍从环境/配置解析(如deepseekopenrouter,fleet 也借此把 worker 钉在 profile 指定的 provider 上);
  • --reasoning-effort:接受autoofflowmediumhighmax
  • --json:输出机器可读 JSON(与--output-format互斥);
  • --model:覆盖本次运行的模型。

步骤 3b — 运行 B:第二个 provider / 模型(DeepSeek)

设置CW_SMOKE_CRED_VAR="DEEPSEEK_API_KEY",然后:

CW_SMOKE_PROVIDER="deepseek" CW_SMOKE_MODEL="deepseek-v4-pro"

……再原样重跑步骤 3a 中相同的env -i …即可;它会提示输入一份全新的凭据值。这里的关键设计是:对两个 provider 运行同一条命令形状——若结果出现差异,那只是值得调查的观察项,而不是路由、entitlement 或 harness 正确性的证明。provider/端点配置、凭据、provider 健康状态、以及生成的请求,全部仍然是可能的解释。

步骤 4 — 可选:工具与推理收据(stream-json)

上面--json的一次性调用记录的是harness 声称的已解析路由,并不独立证明是哪个端点处理了请求。若还想看到tool-catalog 与 reasoning 收据,改用流式形式(仍在同一个env -i包裹内,仅替换exec行):

exec codewhale exec --auto --max-turns 3 \ --output-format stream-json \ --provider "$1" --model "$2" --reasoning-effort "$3" "$4"

这里的参数语义同样可以回到源码确认:

  • --output-format stream-json对应crates/tui/src/lib.rsExecOutputFormat枚举的stream-json值(默认是Text);
  • --max-turns 3的取值下限为 1,省略表示不限步数(u32范围 1..);--auto开启 agent-with-tools 模式,允许自动化的工具批准,但它不改变沙箱姿态、也不提权任何被拒绝的工具——如需沙箱提权要显式使用--sandbox danger-full-access--allow-sandbox-elevation
  • crates/tui/src/exec_agent.rs的流式收据路径中可以看到reasoning_tokensreasoning_replay_tokens、tool catalog 的哈希(tool surface 被提供时才存在)等字段的实际写入逻辑——这正是步骤 5 中“字段何时存在”的底层来源。

步骤 5 — 需要记录什么

--json一次性收据:

字段预期
modeone-shot
provider与你传入的--provider完全一致
model与你传入的--model完全一致
successtrue
output模型的文本;内容不是通过/失败判据

stream-json的元数据收据:

字段预期
providermodel与传入的 flag 一致
route_source记录为何选择了该路由
reasoning_tokens当收据报告 reasoning 时存在;缺失可能反映模型/provider 行为、配置或 harness 遗漏,需要佐证
tool_catalog_sha256当提供了 tool surface 时存在
approval_posturesandbox_posture与传入的 flag 一致
duration_msinput_tokensoutput_tokens完成运行后存在

报告时应只汇报收据字段。切勿粘贴:凭据、密钥文件、或原始 provider 错误体(后者可能回显请求头)。

步骤 6 — 清理

rm -rf "$CW_SMOKE_CODEWHALE_HOME" unset CW_SMOKE_CODEWHALE_HOME CW_SMOKE_CRED_VAR \ CW_SMOKE_PROVIDER CW_SMOKE_MODEL CW_SMOKE_EFFORT CW_SMOKE_PROMPT

删除一次性状态目录并清空全部CW_SMOKE_*变量,确保任何会话、配置或 skill 安装痕迹都不会残留在本机。

边界结论:一次绿色运行究竟意味着什么

一次全绿的 live smoke 是“配置好的 live 尝试今天在这台机器上跑完了”的证据。仅凭它,不能证明:端点身份、长期有效的账户 entitlement、或不存在 harness 缺陷——这些都需要分别佐证。它对以下内容也不置一词:技能选择、别名解析、语言环境路由、提示词预算——而它们都已被crates/tui/src/skills/catalog_matrix.rs及配套 catalog-matrix 测试以确定性、无供应商的方式覆盖。

换言之,live smoke 是排障工具箱里的第一块拼图而非结论本身:当收据字段异常时,去查 harness;当收据字段正常但业务结果不符时,把视野扩大到 provider 配置与凭据通道。把docs/LIVE_SMOKE.md中的收据表格当作你的“现场笔录模板”,配合仓库中crates/tui/src/exec_agent.rscrates/config/src/provider.rs的实现细节交叉验证,就能让每一次手工冒烟都产出可复现、可归档、可追责的检查记录。

【免费下载链接】CodewhaleOpen-source coding agent for your terminal, built in Rust and on a journey of continuous community improvement. Issues and PRs welcome.项目地址: https://gitcode.com/GitHub_Trending/de/Codewhale

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 14:03:08

COMSOL相场法模拟锂枝晶生长与电池优化

1. 项目概述:树枝晶生长模拟的工程价值树枝晶生长现象在金属凝固、电池失效等工业场景中普遍存在。以锂电池为例,充放电过程中锂枝晶的不可控生长会刺穿隔膜导致短路,这是制约高能量密度电池发展的关键瓶颈。传统实验观测手段存在成本高、周期…

作者头像 李华
网站建设 2026/9/10 13:57:11

JVM内存模型解析与实战调优指南

1. JVM内存模型深度解析作为Java开发者面试必考知识点,JVM内存模型的理解程度直接决定了你解决实际生产问题的能力。我在处理线上OOM问题时发现,90%的故障根源都能追溯到对内存模型的误解。不同于教科书上的理论图解,这里我会结合15次真实故障…

作者头像 李华