把大模型 “说” 出来的代码直接跑在本地,并让它像 CI 一样通过测试,再顺手把依赖装好、日志补全,这是 Block 开源的 Goose 给出的承诺。整套流程不靠远程沙箱,也不把源码传出去,而是用一个纯 Rust 的 Agent 运行时把 LLM 的输出切成可执行单元,然后调度本地工具链完成 “编辑 - 构建 - 测试” 闭环。下面把 Goose 在工程侧最关键的并发、成本、安全三块拆成可抄作业的参数清单,方便你直接把类似运行时塞进自己的底座。
1. 并发模型:Tokio 之上再做两层 “任务扇出”
Goose 把一次用户请求拆成三级异步任务:
- LLM 调用任务:每个模型后端一个独立
Client,内部用reqwest::Client长连接池,默认pool_max_idle_per_host = 20,http2_keep_alive_interval = 30 s; - 工具执行任务:收到 LLM 返回的
tool_calls后,立即tokio::spawn批量执行,上限由GOOSE_MAX_PARALLEL_TASKS控制,官方默认 50; - 子进程守护任务:真正跑
cargo test、npm install等命令时,再包一层tokio::process::Command,用Semaphore::new(10)限制同时运行的系统进程数,防止把笔记本风扇拉爆。
实测在 8C16G 的 MacBook Pro 上,把 200 并发任务打到 Goose,平均响应 350 ms、P99 1.2 s、错误率 2.8 %;如果把 GOOSE_TOKIO_THREADS 从默认 8 降到 4,吞吐下降 18 %,但 CPU 利用率从 90 % 降到 68 %,风扇噪音直接减半。线上环境建议先按 “CPU 核心数 ×1.5” 设工作线程,再用 tokio-console 看 steal 指标,>5 % 就继续加线程,直到 steal 归零。
2. 成本控制:实时 Token 计量 + 上下文摘要回写
Goose 在 crates/goose-cost 里给每个模型硬编码了 input/output 单价,调用前先用 tiktoken 算 token,再乘实时汇率输出美元估算;同时把 “当日已用” 和 “单任务上限” 写进 ~/.goose/cost.yaml,超预算直接抛 CostLimitExceeded 中断执行。
Block 内部给 4 k 工程师定的红线是:每人每日 10 USD、单任务 2 USD、预警阈值 5 USD。换算成 Claude-3.5-Sonnet 大约 650 k input + 130 k output token,足够把包含单测的 Rust crate 从头写到 90 % 覆盖率。若你的场景更 “聊天”,可以把上下文窗口利用率打到 80 % 后触发自动摘要:用同模型把历史消息压缩成 300 token 的 “记忆”,再续聊,实测能把总消耗降 42 %。
多模型比价也能省:同样 10 k input/2 k output 的代码生成任务,Claude-3.5-Sonnet 0.018 USD、GPT-4-turbo 0.03 USD、Gemini-1.5 0.007 USD。 Goose 允许在 goose.toml 里写模型路由规则:复杂推理走 Claude,通用任务走 Gemini,成本直接砍一半。
3. 安全与可验证:本地执行 + 一次性 Firecracker 回滚
Goose 默认把代码写进 $GOOSE_WORKSPACE(当前 repo),所有命令都在本地 shell 执行,不挂载远程沙箱,源码和机密不会出境。为了防 “LLM 把 rm -rf / 写进构建脚本”,Goose 在启动子进程前做三步过滤:
- 命令白名单:只有
cargo、npm、go、python、make、pytest、deno、node8 个二进制可执行,且路径必须落在$PATH解析结果里; - 参数黑名单:正则拦截
\b(rm|sudo|dd|mkfs|curl|wget)\b等危险关键字; - UID 检查:若当前用户是 root,强制
setuid到一个空白的goose用户,Home 目录只给 1 GB 磁盘配额。
即便如此,Block 内部仍要求 “任何自动生成的代码必须在一次性环境里跑完测试”。他们把 Goose 套在 Firecracker microVM 里,CI 流水线大概长这样:
# CI step
cargo build --release
goose run --task "把 examples/hello 升级到 axum 0.8,并跑通单元测试" \
--model claude-3.5-sonnet \
--workspace /tmp/goose-firecracker/workspace
VM 生命周期跟随 Goose 进程,测试通过即把产物 git diff 输出到宿主机,然后整个 VM 被 kill -9 销毁,磁盘快照清零。这样就算 LLM 写出恶意代码,也只能污染 5 ms 后就不存在的磁盘镜像。对隐私要求更高的金融、医疗场景,可以把 Firecracker 换成 gVisor 或 Kata,但思路一样:让不可信代码只在 “一次性容器” 里运行,产物通过 diff 回流,主机不做任何持久化。
4. 可观测三板斧:日志、Trace、成本看板
- 日志:Goose 用
tracing-subscriber输出 JSON,关键字段task_id、llm_model、tool_name、exit_code,直接丢进 Loki 就能查; - Trace:LLM 调用链用
opentelemetry-rust接入 OTLP,Span 里把 input/output token、首字节时间(TTFB)打标签,方便在 Jaeger 里按模型维度对比延迟; - 成本: Goose 会推
goose_cost_usd{model="claude-3.5-sonnet",user="alice"} 0.018到 Prometheus,一条 PromQL 就能算 “昨日 Top10 烧钱用户”。
5. 快速落地最小清单
| 维度 | 推荐值 | 备注 |
|---|---|---|
| Tokio 工作线程 | CPU 核心 ×1.5 | steal >5 % 继续加 |
| 最大并行任务 | 50 | 200 并发以上错误率 >3 % 时下调 |
| HTTP 连接池 | 20/Host | 内网 Jenkins/GitHub 自建可提到 50 |
| 每日成本上限 | 10 USD / 人 | 按 input 0.3 美分 /output 1.5 美分折算 |
| 单任务成本上限 | 2 USD | 触发摘要或降档模型 |
| 上下文窗口利用率 | 80 % | 触发历史消息压缩 |
| 子进程并发 | 10 | 本地笔记本默认,CI 可提到 30 |
| VM 磁盘配额 | 1 GB | Firecracker 一次性环境 |
把以上参数写进 Helm values,再把 Goose 跑在 Firecracker Job 里,你就拥有了一个 “LLM 驱动、可验证、可计量” 的代码生成运行时 —— 既能让模型放手去写,又能在预算红线内把风险降到一次性 VM 的级别。
资料来源
- Block 官方仓库与发布页:https://github.com/block/goose
- Goose 高并发实测数据:CSDN《Goose 高并发:处理大量并行请求的能力》
- Goose 成本计算与优化策略:CSDN《Goose 成本分析:计算和使用成本的工具》