先建立坐标系:一条鲸鱼的「去 DeepSeek 化」
工坊写 Crush 时说过,2025 下半年起 terminal coding agent 进入「周更军备竞赛」。Codewhale 是这场竞赛里最值得看的一个样本,因为它走了一条别人没走的路:主动斩断自己的原生模型出身。README「Project history」写得很直白:「Codewhale began as deepseek-tui and still preserves that configuration and session compatibility. It is now provider-neutral and independently maintained; it is not affiliated with any model provider.」——一个 DeepSeek 系 TUI,改名叫鲸鱼,然后宣布「我跟任何模型厂商都没关系」。
这不是营销话术,是能实测验证的工程决策:
- doctor 里还留着旧世界的化石:凭据目录同时检查
~/.codewhale/secrets/secrets.json和~/.deepseek/secrets/secrets.json(legacy path)——老 deepseek-tui 用户的配置无缝继承; - config.toml 顶层
api_key/base_url仍按 DeepSeek 默认读取(官方注释:「backward compatibility」),但新增的[providers.*]表让 38 个 provider 可以同时存 key、用/model随时切; - 默认 provider 还是 deepseek——实测无 key 裸跑,报错第一行就是「DeepSeek API key not found」+ 官方申请链接。它不否认出身,只是不再被绑定。
对比一下这个生态里的另外两条路:MiMo-Code(小米)是「fork OpenCode 然后锁进自家模型闭环」,deepseek-reasonix 是「把 DeepSeek 的缓存经济学吃到极致」——Codewhale 是第三个方向:「模型自由」本身当卖点,默认值留给老东家。三种路线谁活得久,2026 下半年见分晓。眼下看数据:不到 8 个月 40.9K Star、周更、MIT、codewhale update 自更新、GitHub release 直接发 8 平台二进制(win/mac/linux × x64/arm64 + Android),工程成熟度明显不是玩具。
核心机制一:工具面只有 7 个——「反 Ruflo」的动态发现路线
工坊写 Ruflo 时算过一笔账:333 个 MCP 工具 ≈ 每轮 61,550 schema tokens,光工具定义就把上下文烧掉一大截。Codewhale 走了完全相反的路线。我用 mock 服务扒它 exec --auto 真实发出的请求,tools 数组里只有 7 个:
| 工具名 | 作用(从 schema 描述实测扒取) |
|---|---|
read | 读文件(offset/limit 分页),实测执行后返回内容 + content_hash="sha256:..." |
write | 写文件(content/path) |
edit | 一次性多处不相交替换(edits 数组,全部基于原文件匹配) |
bash | 执行 shell 命令(带 justification 字段——要求模型说明为什么跑) |
todo_write | 写完整待办清单(替换式,不是追加)——配合持久 /goal |
agent | 启动子 agent(action: start + prompt,dependentSchemas 描述完整状态机) |
tool_search | 工具发现:按 query 搜索可用工具(match 支持 bm25 等)——需要更多工具时现搜现用 |
核心设计是 tool_search:不把几百个工具的定义一次性塞进上下文,而是让模型按需「搜」出工具再调用。7 个常驻工具 schema 的总开销比 Ruflo 那种全家桶低一个数量级,代价是模型多一轮搜索推理。系统提示词我完整导出了:10,729 字符,开头是一段不像机器写的哲学(「You already have an A: begin from possibility and bring your whole attention.」「Invent no urgency or deadline.」「Failure is information. Check before concluding; never invent.」),尾部是 verbosity/translation 控制和 Registry 发现规则——提醒模型「熟悉的 shell 命令也不是跳过 Registry 发现的理由」。这种「少工具 + 动态发现 + 长人格提示词」的组合,是 2026 年上下文成本焦虑下的典型解法,跟 headroom(压缩一切)是同一焦虑的两张脸。
核心机制二:把「授权」写成契约——9 层流水线 + 类型化权限
这是 Codewhale 技术深度最硬的部分,也是它跟 Crush / opencode 拉开差距的地方。docs/AUTHORIZATION_ORDER.md 把「模型请求一个工具调用后会发生什么」写成了一张 9 层流水线表,每层只能加码不能减码:
- L1 配置与姿态:用户设置 + 命令行覆盖 + 项目 overlay 在回合前解析。项目 overlay 只能收紧(approval: auto→on-request→never;sandbox: danger-full-access→workspace-write→read-only;shell 只能从 true 变 false),不能放松,也不能加凭据/hooks;
- L2 模式与工具准入:Plan 模式限制、工具 deny/allow 名单、调用者限制。同一个工具同时出现在两个名单里 = 拒绝;
- L3 前置 hooks:
tool_call_before按 deny > ask > allow 折叠,严格匹配但没出结论的 hook 直接 fail closed; - L4 注册工具基线:工具自身的 ApprovalRequirement 定常规审批需求,hook 的 ask 后置生效,不能被基线抹掉;
- L5 类型化
permissions.toml:规则优先级是「层级(User > Agent > BuiltinDefault)> 动作(deny > ask > allow)> 匹配精度」,硬 deny 前缀(比如rm -rf)跨规则集合并集、永远优先、任何 allow 都盖不掉; - L6 自动审查 + 内置安全底线:block 规则先跑,allow 规则和确定性 fallback 后跑,只能加提示/阻断、不能消掉前面的 hold;
- L7 仓库法(repo law):受保护路径不变量,Full Access 下 repo-law 的提示直接变硬 block(因为 Full Access 没有弹窗通道);
- L8 人类审批:剩下的提示才到人。拒绝即停;批准只授权「这一发」,不豁免后面的门;
- L9 工具权限与执行沙箱:worker authority envelope + 原生工具路径检查 + OS/外部沙箱。沙箱拒绝就是拒绝,除非用户单独走 elevation 路径。
这套契约不是 PPT——文档末尾列了对应的回归测试名(authorization_order_contract_matches_documented_precedence、hook_fold_deny_wins_over_ask_and_allow、full_access_permission_allow_cannot_bypass_background_catastrophic_floor……),仓库里 execpolicy crate 就是它的实现。另一个细节很戳人:「未知的模型价格保持未知,而不会被误报为免费」——这是 README 安全章节里的一句话,专门堵「价格表没配就显示 $0」的假省钱幻觉。跟 vibe-kanban 倒闭、ruflo 默认关加密对比着看,能感受到这个项目对「信任边界」的执念到了什么程度。
核心机制三:fleet + workflow——把多 agent 跑批做成可恢复的耐久运行
Codewhale 的多 agent 不叫「sub-agent 扇出」,叫 fleet(船队),定位是「local-first 的耐久多 worker 层」。架构上很讲究:fleet 只负责「谁参与」,不执行也不授权——成员选定后,由委托协调器拉起一个 headless codewhale exec 跑,Runtime 做耐久跟踪。命令行长这样:
codewhale fleet init codewhale fleet run tasks.json --max-workers 4 codewhale fleet status / inspect <worker-id> / logs / artifacts / interrupt / restart codewhale fleet resume <run-id> # 重启恢复:重放 ledger、对心跳停止的 worker 重试或升级告警 codewhale fleet stop --all
成员身份是公开契约:稳定 member id + 语义角色(explore / implement / test / advisor,旧的 worker/scout/builder/verifier/oracle 拼写仍接受)+ 精确的 provider/model 或继承路由。自然语言选人是确定性的:点名 member id、唯一名字、唯一角色、精确模型 id(比如 deepseek-v4-flash)都行。状态全部落盘:.codewhale/fleet.jsonl ledger + .codewhale/fleet/ 日志目录,resume 是幂等的——笔记本休眠、manager 退出后重跑不重复起新活。旁边还挂着 workflow(入库的 workflow 文件)+ lane runtime(跑 workflow 实例),0.9.12 又加了 per-session 控制 socket(JSON-RPC:message / interrupt / relaunch / status)。这套「先记账再干活、账本可重放」的工程习惯,是冲着「agent 跑批必须能断电续传」去的。
核心机制四:0.9.12 的三个信号(9 月 4 日刚发)
- computer-use 进二进制但默认禁用:
computer-use插件——38 个工具,覆盖 macOS/Windows/Linux/HarmonyOS,accessibility-first 观察 + pixel fallback、截图/缩放/录屏、通过 ssh/hdc 注册远程电脑——直接内嵌在发布包里,首跑时写到$CODEWHALE_HOME/builtin-plugins。关键在态度:「It lists as builtin · not-reviewed and stays disabled until you review and enable it: shipping it is not consenting to it.」——内置 ≠ 授权,这句值得每个做 agent 的公司抄进 README。旧的 stdlib-Python computer-use server 被替换掉了; - Cloud dispatch(远程跑批):把 coding agent 任务 offload 到隔离云沙箱,machine token 认证 + 结构化任务跟踪。命令注释里写着「Never spends or pushes without --confirm」——花钱/推送前必须确认,跟 L7 repo-law 的「Full Access 没有弹窗」哲学互为表里;
- 匿名统计从这版起默认开启:changelog 自己交代得很清楚——0.9.11 是先询问(opt-in),0.9.12 改成默认统计(版本/平台/会话/功能/错误计数,PostHog 聚合,无内容无 IP),首次启动披露一次。实测首跑确实打印了那段「Usage reporting is on by default」,关闭开关是持久的:
codewhale config set telemetry false(或CODEWHALE_TELEMETRY=0)。工具是好工具,但这手「先问一版、下版默认开」的套路,值得你升级前知情。
上手:我在沙箱实测跑通的命令(含 mock 全链路)
Ubuntu 无头沙箱。官方推荐 curl -fsSL https://codewhale.net/install.sh | sh(装到 ~/.local/bin/codewhale),我直接下 GitHub release 的 codew-linux-x64(v0.9.12,69,543,680 字节 ≈ 66 MiB)。全链路:版本 → doctor → 无 key → 坏 key → 裸 exec → exec --auto + SSE mock 闭环,都走了一遍。
# 1) 安装(直接下载 release 二进制;npm/cargo/docker/nix/scoop/Termux 也行) curl -sL https://github.com/Hmbown/Codewhale/releases/download/v0.9.12/codew-linux-x64 -o codew chmod +x codew ./codew --version # codewhale 0.9.12 (dcd4c200f72f) # 2) 诊断(纯离线可跑) ./codew doctor # config.toml not found at ~/.codewhale/config.toml (using defaults/env) # legacy_path: /home/ubuntu/.deepseek/secrets/secrets.json (absent) ← deepseek-tui 化石 # 3) 无 key 裸跑:报错清晰,还带 4 个补救方案 ./codew exec "hi" # error: DeepSeek API key not found. # 1. Get a key: https://platform.deepseek.com/api_keys # 2. codewhale auth set --provider deepseek # export DEEPSEEK_API_KEY=*** / api_key = "..." in ~/.codewhale/config.toml # codewhale auth external-consent --provider deepseek --mode read-only # 4) 坏 key:不静默,但会回显 key 尾号 DEEPSEEK_API_KEY=sk-invalid-123 ./codew exec "say hi" # error: Authentication failed: Authentication Fails, Your api key: ****-123 is invalid # 5) 裸 exec = 一次性模型回复(不是 agent!) # 本地 mock 记录:单发非流式 POST /v1/chat/completions,只有 1 条 user 消息, # 无 system、无 tools、max_tokens=65536——mock 回文本它就原样打印 exit 0; # 回 tool_call 它直接静默吞掉(无输出,exit 0) # 6) exec --auto = 工具型 agent 模式(SSE 流式) ./codew exec --auto "read main.rs and summarize it in one line" # tool: read_file (path: main.rs) # tool read_file completed: content_hash="sha256:f32984..." ← 本地真执行 # MOCK-DONE: 读到了 main.rs(mock 流式闭环完成) # 7) 模型目录(离线只有 3 个 DeepSeek id,--update 才拉全) ./codew models # * deepseek-v4-flash / deepseek-v4-pro / deepseek-v4-flash-vision-exp
mock 抓包的关键事实:请求统一打到 {base_url 的 origin}/v1/chat/completions(配置里写 /beta 也会被归一化),Authorization 正常带 Bearer sk-...,UA 是 Mozilla/5.0 (compatible; codewhale/0.9.12; +https://github.com/Hmbown/CodeWhale)。系统提示词 10,729 字符、7 个工具、tool_choice: auto、max_tokens 65536。全程 2 个请求闭环:req1 模型要 read_file → Codewhale 本地真执行(返回内容带 sha256 content_hash)→ req2 带 tool 结果 → 模型给最终文本。工具调用格式是标准 OpenAI function calling,tool_call_id 回传正确。
实测与踩坑:6 个坑,第 1 个最阴
- 坑 1(最阴):裸
exec根本不是 agent。README 大标题示例是codewhale exec "fix the failing tests..."——但exec --help自己招了:「Plaincodewhale execis a one-shot model response. Use--autofor non-interactive filesystem/shell tool use.」实测:裸 exec 的请求里没有 system、没有 tools;mock 回一个tool_call,它既不执行也不报错,静默吞掉、无输出、exit 0。照 README 示例写脚本的人会得到一份「模型声称做完了但其实啥也没干」的结果。自动化场景务必--auto。 - 坑 2:--auto 只认 SSE 流。第一版 mock 按普通 JSON 返回 200,Codewhale 直接连报 4 次
error: Chat Completions stream closed before [DONE] or finish_reason,最后exec turn failedexit 1——期间 12 个请求全打进了我的 mock(带累积历史的多次重试)。自建网关/代理接 Codewhale,必须实现text/event-stream+data: [DONE]收尾,缺一个就整轮失败。 - 坑 3:0.9.12 起匿名统计默认开启。changelog 白纸黑字:0.9.11 先问、0.9.12 直接统计(PostHog 聚合版本/平台/会话/功能/错误计数,声明无内容无 IP)。首跑会打印披露一次。介意就
codewhale config set telemetry false(持久)或CODEWHALE_TELEMETRY=0。 - 坑 4:默认值全是「为 DeepSeek 深度推理调校」的。默认 provider deepseek、默认
reasoning_effort = "max"、默认模型 deepseek-v4-pro——无 key 用户第一步就撞「DeepSeek API key not found」;想用别家得先auth set --provider xxx再/model切换。国内用户还要记得有 deepseek-cn / volcengine / siliconflow / zai 这些本土入口可选(doctor 里甚至能设百度/秘塔/火山做搜索源)。 - 坑 5:配置双文件 + 未知 key 静默忽略。
config.toml和settings.toml分家,TUI 显示类设置(show_thinking、pin_last_prompt、cost_currency…)放进 config.toml 会被直接忽略——config example 注释原话:「Confighas no such fields and unknown keys are ignored」。写错文件/写错 key 都不报错,排查全靠codewhale config list。 - 坑 6:模型目录离线只有 3 个 id。沙箱里
codewhale models只列出 bundled 的 3 个 DeepSeek id(flash/pro/vision-exp),--update才去拉 provider catalog。离线/内网环境想切模型,得自己配[providers.*]的 models 表,别指望开箱即有 38 家目录。
对比:2025-26 Terminal Coding Agent 家族里的站位
| 维度 | Codewhale | Crush | Aider | OpenCode |
|---|---|---|---|---|
| 出生 | 2026-01(前身 deepseek-tui) | 2025-05(charmbracelet) | 2023-05(祖师爷) | 2025-04(社区/被广泛 fork) |
| 语言 / 许可 | Rust / ✅ MIT | Go / ⚠️ FSL-1.1-MIT(两年内禁竞争性商用) | Python / ✅ Apache-2.0 | TypeScript / ✅ MIT |
| Star / 状态 | 40,913 / ✅ 周更(9/4 刚发 0.9.12) | 27,677 / ✅ 活跃 | 48,605 / ⚠️ 休眠 3 个月 | 205,072 / ✅ 活跃 |
| 模型面 | 38 个内置 provider + Ollama/vLLM/SGLang,默认 DeepSeek,flash/pro 自动路由 | 40 家 provider / 1,547 模型(社区目录日更) | litellm 全家桶 | 多后端 + 插件 |
| 工具设计 | 7 常驻工具 + tool_search 动态发现(反全家桶) | 26 工具(8 个 LSP) | SEARCH/REPLACE 编辑块 + repo map(首创) | LSP + 插件生态 |
| 安全/授权 | ✅ 9 层授权契约 + permissions.toml 类型化规则 + 3 档沙箱 | ✅ approval 模式 + crushrc 即代码 | ⚠️ 靠 git 兜底 | ⚠️ 权限系统 |
| 多 agent / 耐久 | ✅ fleet(ledger 可 resume)+ workflow/lane + 控制 socket | — | — | ⚠️ 插件 |
| 独特卖点 | computer-use 内置默认禁用 / cloud dispatch / 价格未知不报免费 | Bubble Tea TUI 美学 | 范式输出者(repo map/自动 commit) | 生态最大、被小米等 fork |
一句话定位:aider 是「范式祖师爷」、OpenCode 是「生态最大公约数」、Crush 是「设计驱动的新贵」——Codewhale 则是「安全工程最较真的模型自由派」。它跟 Crush 是最直接的竞品(都是 2025 下半年冒头、都周更、都主打「模型随便接」),但气质完全不同:Crush 的配置是「可执行 Bash」(crushrc,信任即代码),Codewhale 的配置是「9 层授权流水线 + 类型化规则 + 只能收紧的项目 overlay」(信任要分层审计)。前者浪漫,后者适合当生产基础设施。
值不值得装:三个场景对号入座
- 想要「一个二进制、模型随便切、授权可审计」的日常 terminal agent:值得装。MIT 无商用陷阱(对比 Crush 的 FSL)、单文件无 node 依赖、周更 + 自更新、坏 key 报错不静默、系统提示词和工具面都克制。唯一前提是你接受默认 DeepSeek 需要配 key、且升级前留意 telemetry 默认值。
- 想研究「agent 安全授权到底该怎么设计」:必看。
docs/AUTHORIZATION_ORDER.md的 9 层流水线 + execpolicy crate + 带名字的回归测试,是目前开源 coding agent 里把「授权顺序」写成交契并测试的最完整样本——比读十篇「如何防止 agent 乱跑命令」的博客有用。它那个「shipping is not consenting」的 computer-use 默认禁用策略,也值得抄进你自己的 agent 产品。 - 要跑「多 worker 批量任务 + 必须能断电续传」的流水线:fleet 的 ledger + 幂等 resume + 角色化成员选择,加上 workflow/lane 和 cloud dispatch,是 2026 年这批 agent 里少见的「为长任务而生」的设计。想研究 agent 上下文管理的反面(工具 schema 瘦身)也可以看它的 tool_search 路线。
最后说句公道话:Codewhale 不是没有隐忧——周更节奏意味着 changelog 永远比教程新,exec/exec --auto 这种「同名不同命」的命令设计对新手不友好,默认 DeepSeek + 默认 max 推理 + 默认开统计的组合拳也说明它的「默认值」是站在老用户(deepseek-tui 迁移者)而非新用户立场上的。但论工程密度、授权严谨度和「模型自由」的彻底程度,40.9K Star 里没有水分。MIT,仓库 github.com/Hmbown/Codewhale,官方安装 curl -fsSL https://codewhale.net/install.sh | sh——一条从 DeepSeek 游向整片海的鲸鱼,2026 年最值得盯的 Rust coding agent 之一。