ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Gas Town Factory Worker API 设计解析:为 AI Agent 运行时定义稳定的进程边界

2026/9/13 14:08:58 拓冰建站 浏览量
Gas Town Factory Worker API 设计解析:为 AI Agent 运行时定义稳定的进程边界 Gas Town Factory Worker API 设计解析为 AI Agent 运行时定义稳定的进程边界【免费下载链接】gastownGas Town - multi-agent workspace manager项目地址: https://gitcode.com/GitHub_Trending/ga/gastown本文是 Gas Town多智能体工作区管理器中一份设计文档的深度解读聚焦于 factory-worker-api.md 所定义的 Gas Town 与 AI Agent 运行时之间的 API 边界。该设计旨在将目前依赖 tmux 按键注入、终端输出正则匹配、JSONL 文件抓取等脆弱机制的集成方式收敛为一套基于 HTTP 语义的结构化本地 API。读完本文你将理解这 7 个 API 端点的职责划分、消息格式、替换对象以及为什么 Push, not scrape 与 Fail-closed 是这套设计的基石。问题背景28 个脆弱的集成触点Gas Town 需要与 Claude Code 等 AI Agent 运行时深度协作投递提示词、探测空闲、统计成本、轮换账号、检查存活、拦截危险命令。当前实现完全围绕各厂商的运行细节展开文档开篇就点出了现状的碎片化本质Prompt 投递tmuxsend-keys 512 字节分块配合 ESC600ms readline 等待、Enter 重试、SIGWINCH 唤醒等一系列时序协议空闲检测正则匹配 Claude Code 的❯提示符前缀需做 NBSP 归一化以及⏵⏵状态栏解析遥测抓取~/.claude/projects/slug/session.jsonl文件系统日志成本追踪从 JSONL 转录中解析 token 用量配合硬编码的价格表账号轮换macOS 专属的 keychain token 交换存活检测通过pane_current_commandpgrep遍历 tmux 进程树Guard 脚本利用 PreToolUse hook 的退出码 2 来阻止危险命令权限绕过为每个 Agent 厂商维护约 10 种不同的--dangerously-*启动参数。从源码中可以逐一印证这些触点。例如 nudge.go 中NudgeModeImmediate明确写着 Send directly via tmux send-keys (current behavior)而 tmux.go 用sessionNudgeLocks信号量串行化同一会话的 nudge、以 30 秒超时防止卡死——这些都是时序协议的真实工程化产物。遥测方面claudecode.go 的ClaudeCodeAdapter.Watch会在~/.claude/projects/hash/session-uuid.jsonl中轮询并 tail 最新 JSONL 文件成本则由 costs.go 的extractCostFromWorkDir从转录中抽取。权限模型方面hooks/config.go 展示了通过gt tap guard pr-workflow、gt tap guard dangerous-command这类 PreToolUse hook 拦截命令的方式而 agents.go 为 claude、codex、cursor 等厂商预设了各自的--dangerously-skip-permissions、--dangerously-bypass-approvals-and-sandbox、--dangerously-allow-all等启动参数。文档统计这些触点超过 28 个全部依赖 Claude Code、tmux、macOS Keychain 或文件系统约定等随时可能变更且不会通知的实现细节。这正是 Factory Worker API 要解决的根因。设计原则五个不可妥协的前提针对上述混乱文档给出五条设计原则它们贯穿后续所有 API 定义Push而不是 ScrapeAgent 主动上报自身状态GT 不再从终端输出中猜测结构化而不是字符串匹配JSON 消息而非对 pane 内容做正则Agent 无关无论 worker 是 Claude、Gemini、Codex 还是自定义运行时只有一套 API天然关联单一run_id贯穿从进程诞生到消亡的每一个事件默认失败关闭状态未知 不派活、不杀会话。第 4 条值得展开目前遥测散落在约 6 个互不关联的日志文件中agentlog包 tail JSONL、stop hook 的gt costs record、RecordPaneRead等无法把一次完整执行串起来。run_id就是为消除这种日志孤岛而生的关联键。API 表面七个端点API 共分七个端点每个端点都明确列出了它替换的现有机制方便对照迁移。1. Lifecycle运行时上报生命周期GT 不再推断GT 从不过问这个 Agent 现在在干什么而是等待运行时主动上报状态转换POST /lifecycle { event: started | ready | busy | idle | stopping | stopped, run_id: uuid, session_id: gt-crew-max, timestamp: 2026-03-01T15:00:00Z, metadata: {} // event-specific (e.g., exit_code for stopped) }它替换的现有机制包括提示符前缀匹配、状态栏解析、pane_current_command、IsAgentAlive()、GetSessionActivity()、heartbeat 文件、WaitForIdle()轮询、WaitForRuntimeReady()轮询。在仓库中这些机制大量存在heartbeat 由 heartbeat.go 和 polecat/heartbeat.go 的TouchSessionHeartbeat/TouchSessionHeartbeatWithState维护会话健康则由CheckSessionHealth通过 tmux 三档检查实现见 rig.go 与 dog/health.go。各事件的语义如下表Event替换对象触发时机startedsession 创建检测Agent 进程启动readyWaitForRuntimeReady()轮询Agent 准备好接收首个 promptidle提示符前缀 状态栏检测一轮回合结束等待输入busyesc to interrupt 检测正在处理 promptstoppingdone-intent 文件检测Agent 主动发起关闭stopped进程树检查Agent 进程已退出2. Prompt Submission结构化消息取代终端注入GT 向运行时投递结构化消息彻底告别终端注入POST /prompt { run_id: uuid, content: Review PR #2068..., priority: normal | urgent | system, source: nudge | mail | sling | prime, metadata: { from: gastown/crew/tom, bead_id: gt-abc12 } } Response: { accepted: true, queued: false, // true if agent was busy and queued it position: 0 // queue position if queued }它替换的对象正是问题清单中最复杂的一块NudgeSession()的 8 步 tmux send-keys 协议、512 字节分块、ESCreadline 时序、防抖定时器、nudge 队列 JSON 文件、UserPromptSubmithook drain、大 prompt 临时文件绕行方案。当前gt nudge命令的现状可见于 nudge.goimmediate模式直接通过 tmux send-keys 发送会打断进行中的工作注释还特别强调不要在别处使用裸 tmux send-keys——这本身就说明了该方案的脆弱。优先级语义明确划分了三个层级system在回合边界注入替换system-reminder块urgent立即中断当前工作替换即时 nudgenormal空闲时投递替换 wait-idle 队列兜底。响应的accepted/queued/position字段让 GT 无需自建队列文件——排队行为由运行时负责并返回队位。3. Context Injection (Priming)结构化的上下文注入在会话启动与压缩compaction时以结构化分节的方式投递上下文POST /context { run_id: uuid, sections: [ {type: role, content: You are a polecat worker...}, {type: work, content: AUTONOMOUS WORK MODE: gt-abc12...}, {type: mail, content: 2 unread messages...}, {type: checkpoint, content: Previous session state...}, {type: directive, content: Execute your hooked work.} ], mode: full | compact | resume }它替换的对象包括gt prime流水线10 节输出、SessionStarthook、PreCompacthook、beacon 注入、面向无 hook Agent 的启动 nudge 兜底以及向 stdout 渲染角色模板的机制。mode字段full/compact/resume对应首次启动、上下文压缩后、断点恢复三种场景把原来分散在 hook 链各阶段的拼接逻辑统一到运行时一侧。4. Tool Authorization把守卫从 shell 脚本变成数据运行时在执行工具前向 GT 请求授权由 GT 决策POST /authorize { run_id: uuid, tool: Bash, input: {command: git push --force}, context: { role: polecat, rig: gastown, bead_id: gt-abc12 } } Response: { allowed: false, reason: force push blocked by dangerous-command guard }它替换的对象包括PreToolUse hook 退出码 2 拦截、PR-workflow guard、dangerous-command guard、patrol-formula guard以及各 Agent 的--dangerously-*启动参数后者本质是用全局权限开关代替细粒度拦截。权限模型有三条核心约束按角色设定权限集polecat 全权、witness 只读、crew 可配置Guard 规则是数据而非 shell 脚本即authorize请求中的toolinput是结构化字段规则匹配可以精确到git push --force这类特定命令模式而不必解析任意 shell 语法失败关闭GT 不可达时默认拦截工具调用。5. Telemetry Cost Reporting在源头计算成本运行时推送结构化事件取代文件系统抓取POST /telemetry { run_id: uuid, events: [ { type: turn_complete, timestamp: 2026-03-01T15:01:00Z, usage: { input_tokens: 12000, output_tokens: 3500, cache_read_tokens: 8000, cache_creation_tokens: 0, model: claude-opus-4-6, cost_usd: 0.2325 }, tools_called: [ {name: Bash, success: true, duration_ms: 1200}, {name: Read, success: true, duration_ms: 50} ] } ] }它替换的对象包括JSONL 转录抓取、extractCostFromWorkDir()、硬编码价格表、agentlog包Claude Code JSONL tailing、RecordPaneRead、stop hook 的gt costs record以及 6 个互不关联的日志文件。设计上有四个明确要点按回合统计 token 用量而非按 content block避免重复计数成本在源头计算运行时掌握模型与真实定价GT 不再维护价格表工具调用结果携带成功/失败状态与耗时可用于诊断与性能分析所有事件携带run_id保证可关联性。6. Identity CredentialsGT 发身份运行时做认证身份由 GT 分配认证动作发生在运行时POST /identity { run_id: uuid, role: polecat, rig: gastown, agent_name: alpha, session_id: gt-gastown-alpha, credentials: { type: api_key | oauth | token, value: sk-ant-..., expires_at: 2026-03-02T00:00:00Z }, env: { GT_ROLE: gastown/polecats/alpha, BD_ACTOR: gastown/polecats/alpha, GT_ROOT: /Users/stevey/gt } }它替换的对象包括AgentEnv()通过 tmuxSetEnvironmentPrependEnv注入 30 环境变量、macOS keychain token 交换、CLAUDE_CONFIG_DIR隔离、账号切换符号链接、GT_QUOTA_ACCOUNT环境变量、credential passthrough 白名单。仓库中环境注入的现状可从 crew_at.go 与 handoff.go 看到SetEnvironment只对新 pane 生效所以还需要config.PrependEnv生成 OS 感知的 export 前缀追加到启动命令中——这些平台相关的工作将来都会被/identity取代。凭证轮换机制的要点GT 轮换时主动推送新凭证运行时无需重启即可应用不再依赖 keychain任何操作系统可用运行时上报凭证过期时间GT 在到期前主动轮换。7. Health Liveness双向健康检查健康检查是双向的——GT 查运行时运行时也报告自身GET /health Response: { status: healthy | degraded | unhealthy, run_id: uuid, uptime_seconds: 3600, current_state: idle | busy | stopping, last_activity: 2026-03-01T15:00:00Z, context_usage: 0.73, // fraction of context window used error: null }它替换的对象包括CheckSessionHealth()三档 tmux 检查、IsAgentAlive()进程树遍历、GetSessionActivity()tmux 活动时间戳、heartbeat 文件、TouchSessionHeartbeat()、zombie 检测启发式、spawn storm 检测。其中context_usage是一个全新的信号运行时最清楚自己的上下文窗口还有多少余量。GT 可以利用它赶在 Agent 性能退化之前触发 compaction 或 handoff——这为 polecat-lifecycle.md、scheduler.md 等设计中的主动压缩策略提供了数据基础。传输层本地优先两种通道API 仅限本机通信文档给出两个选项Unix domain socket首选$GT_ROOT/.runtime/worker.sock不暴露网络端口基于文件权限做访问控制GT 作为服务端Agent 运行时作为客户端Agent 启动时连接保持持久连接。Embedded HTTP兜底localhost 随机端口端口写入众所周知的文件为无法使用 Unix socket 的运行时准备的降级方案端口文件位于$GT_ROOT/.runtime/worker-session.port。从仓库现状看本地代理通信并非新领域internal/acp/已有基于子进程的 ACPAgent Client Protocol代理实现见 proxy.gocmd/gt-proxy-server与cmd/gt-proxy-client也验证了本地 socket 类通道的可行性——这为 Factory Worker API 的传输层落地提供了既有工程参考。迁移策略Sidecar 渐进式替换Factory Worker API 不需要立即抛弃 Claude Code。文档给出的迁移路径是以 sidecar 形式逐步落地与 Claude Code 同处一个 tmux session 运行在 API 与 Claude Code 现有机制hooks、JSONL、send-keys之间做翻译随着 sidecar 成熟逐步替换 tmux 中介的交互方式。这样做的价值在于先用 sidecar 验证 API 设计本身是否合理再决定是否构建完全 GT 原生的运行时避免了先重写再发现设计缺陷的高昂代价。这也呼应了文档对自身定位的清醒认识——它是一份边界设计而非具体厂商的适配规范。非目标与待决问题文档明确划定了设计边界避免过度设计非目标一多机编排。这是同一台机器上 GT 与 worker 之间的本地 API不解决分布式调度非目标二Agent 智能。API 是管道plumbing而非策略policyAgent 拿到 prompt 后做什么与 API 无关非目标三兼容所有 Agent 厂商。翻译工作交给 sidecarAPI 是为 GT 原生运行时设计的。同时文档诚实地列出了四个尚未定论的设计问题作为后续迭代的输入Prompt 投递应该是同步阻塞直到被接受还是 fire-and-forget 状态回调工具授权应该是逐调用有延迟成本还是按会话预先协商能力集compaction/handoff 如何工作——GT 直接命令运行时现在压缩还是由运行时上报上下文压力、GT 做决策运行时是否应暴露对话历史还是遥测流已足够满足 GT 需求小结Factory Worker API 的本质是把 Gas Town 与 AI Agent 之间对着终端屏幕猜状态的关系重构为通过结构化消息明确交换状态的协议关系。七类端点各司其职Lifecycle 管状态、Prompt 管指令、Context 管上下文、Authorize 管权限、Telemetry 管成本、Identity 管身份、Health 管存活再由run_id串起全局关联。它不追求替换具体厂商的 Agent而是先定义一条稳定的边界再以 sidecar 方式渐进收敛现有的 28 个脆弱触点。对于任何在多 Agent 工作区中维护集成层的开发者来说这套push 不 scrape、结构化不 regex、失败关闭的接口设计思路都值得作为本地进程集成架构的参考样板。【免费下载链接】gastownGas Town - multi-agent workspace manager项目地址: https://gitcode.com/GitHub_Trending/ga/gastown创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考