goose — 架构与原理
30 秒导读: goose 是一个跑在你机器上的通用 AI agent(不只是写代码——研究、写作、自动化、数据分析都行),有桌面 App、CLI 和 API 三种壳,内核用 Rust 写。它把「让模型反复调工具直到任务完成」这件事做成一个可流式输出的循环,所有工具都通过 MCP(Model Context Protocol)这一开放标准接入,并且在每个工具真正执行之前,串了一条安全/权限检查链。
1. 这是什么(零基础也能懂)
一句话定义: goose 是一个开源的「AI agent 运行时」——你给它一个目标,它自己反复地「想一步、调一个工具、看结果、再想下一步」,直到把事做完。
解决什么问题 / 给谁用。 假设你在终端里说「帮我把这个项目的测试都修绿」。光有一个聊天模型不够:模型只会说话,不会真的读文件、跑命令、改代码。goose 补上的就是这套「手脚 + 大脑调度」:
- 它把你的话发给某个大模型(Anthropic / OpenAI / Google / Ollama / …);
- 模型回一句「我要运行
cargo test」(这叫一次工具调用); - goose 真的去执行,把输出再发回给模型;
- 如此往复,直到模型说「做完了」。
它能做什么(功能):
- 多家模型提供商:15+ 家,既可用 API key,也能复用你已有的 Claude/ChatGPT/Gemini 订阅。
- 70+ 扩展:通过 MCP 接入文件系统、shell、浏览器、记忆、自定义 server 等。
- 三种交互壳:桌面 App、CLI(
goose)、HTTP 服务(goosed)。 - 安全护栏:权限审批、prompt-injection 检测、数据外泄(egress)检测、生命周期 hooks。
- 长任务支撑:上下文自动压缩、子 agent、会话持久化、recipe(可复用任务模板)。
用起来什么样。 最小的 CLI 体感:
# 安装后,在项目目录里:
goose session
# 然后用自然语言下指令:
> 看一下 src/ 里有哪些 TODO,挑最关键的一个修掉
# goose 会:列目录 → 读文件 → 提议改动 → (按权限模式)征求同意 → 写文件 → 报告
一句话直觉 / 类比。 把 goose 想成一个项目经理 + 一双手:大模型是会出主意的「大脑」,但只会说话;goose 负责把大脑说的每句「去做 X」翻译成真实动作、拿回结果、再递回给大脑,并在动手前过一遍「这步安全吗、要不要先问主人」的安检。
2. 顶层全景(它大概怎么转)
仓库结 构(只列主线相关)
goose 是一个 Rust workspace,核心逻辑集中在 crates/goose:
| crate | 干什么 |
|---|---|
goose | 核心:agent 循环、工具分发、扩展管理、安全检查、上下文管理 |
goose-providers | 各家模型的接入(Anthropic / OpenAI / OpenAI-compatible),统一成 Provider trait |
goose-mcp | goose 自带的内置 MCP 扩展(computercontroller、memory、tutorial 等) |
goose-cli | 命令行入口 goose |
goose-server | HTTP 后端,二进制名 goosed,桌面 App 连它 |
ui/desktop | Electron 桌面应用(TypeScript) |
核心类型 Agent 定义在 crates/goose/src/agents/agent.rs:237(struct Agent)。
主部件与职责
| 部件 | 干什么 | 在哪 |
|---|---|---|
Agent | 持有 provider、扩展管理器、各种 manager,提供 reply() 入口 | agents/agent.rs:237 |
Provider (trait) | 把「一组消息 + 工具定义」发给模型,流式返回 | goose-providers/src/base.rs:381 |
ExtensionManager | 管理所有 MCP 扩展 、聚合工具、按前缀路由 dispatch_tool_call | agents/extension_manager.rs:186 |
ToolInspectionManager | 工具执行前的检查器流水线(安全/egress/权限/重复) | tool_inspection.rs:57 |
PromptManager | 组装系统提示(扩展信息 + hints + 模式) | agents/prompt_manager.rs:22 |
SessionManager | 会话与消息持久化 | session/ |
context_mgmt | 上下文超限时的压缩 / 工具对摘要 | context_mgmt/mod.rs |
主线走一遍(高层,不进代码)
用户的一条消息进来后,大致经过:
用户消息
│
▼
Agent::reply ──── 先跑斜杠命令? 先处理 elicitation 回复? 先看要不要自动压缩?
│
▼
reply_internal ────────────────────────────────────┐
│ (一个 async 流,内部是一个 loop = 一「回合」一圈) │
▼ │
① 问模型 (stream_response_from_provider) │
│ 模型流式吐:文本 / thinking / 工具调用 │
▼ │
② 分类工具 (categorize_tool_requests) │
│ 分成「前端工具」「其它工具」 │
▼ │
③ 安检 + 权限 (ToolInspectionManager.inspect_tools) │
│ 每个工具:Allow / Deny / 需审批 │
▼ │
④ 执行 (dispatch_tool_call → ExtensionManager) │
│ 按工具名前缀路由到对应 MCP 扩展 │
▼ │
⑤ 把工具结果作为 user 消息写回 conversation │
│ │
└── 这一圈如果调了工具 → 回到 ①(再问模型) ──────────┘
如果没调工具 → 收尾(goal/grind 提醒、retry、stop hook)→ 退出
关键直觉:「调了工具就继续循环,没调工具就准备结束」。这就是所有 agent 的心跳。goose 在这条主线上挂满了护栏和长任务机制,这正是它和「裸调 API」的区别。
3. 阅读地图(建议顺序)
想真正读懂 goose,按下面顺序看分章:
- 01-agent-loop.md —— 先看心跳。
reply_internal那个loop是整个项目的主算法,搞懂它你就懂了 80%。 - 02-tools-and-mcp.md —— 工具从哪来、怎么命名、调用时怎么找到对的扩展。MCP 是 goose 的「插槽标准」。
- 03-safety-chain.md —— goose 相对其它框架最用心的地方:工具执行前的检查器链 + 四种权限模式 + prompt-injection / egress 检测 + 生命周期 hooks。
- 04-context-management.md —— 长任务怎么不撑爆上下文:阈值触发的整体压缩、后台的工具对摘要、消息「可见性」双轨制。
- 05-clever-and-boundaries.md —— 巧妙之处(流式 + 工具的并发收集、tool_call_id 去重、思考内容回放抑制等)、边界局限、与兄弟项目对比、代码地图总表。
如果你是 agent,只想低成本判断相关性:goose = 「Rust 版的 MCP-原生通用 agent 内核 + 重安全护栏」。要找「主循环」看第 1 章;找「工具/MCP 接线」看第 2 章;找「权限/安全」看第 3 章。