环境钩子让 Gemini Managed Agents 在执行工具前后跑你自己的校验脚本,是给沙箱加权限门槛的关键。
- 01先读摘要,判断是否与你的场景相关。
- 02再看来源,保留继续查证的路径。
- 03最后看步骤、风险和可复用动作。
Gemini API 的 Managed Agents 在 2026-07-28 更新里加入环境钩子(environment hooks):你可以让模型在执行写文件、运行代码等工具调用前后,先跑你自己的脚本做拦截、审核或格式化。这套清单把“在沙箱里给 AI 代理加权限门槛”变成可执行的配置流程,适合想把代理从实验推到生产、又不愿意直接开放文件写入的开发者。
适用场景
- 你在用 Gemini API 的 Managed Agents 跑多步任务,需要给文件写入或代码执行加审核。
- 你希望代理在沙箱里做自动格式化、检查产物或生成审计记录。
- 你需要限制单次任务的 token 消耗,避免自主循环跑飞。
- 你想把重复任务做成定时触发,并统一管理沙箱生命周期。
不适用场景
- 你的任务只是一次性聊天,不需要工具调用审核。
- 你还没有创建 Managed Agent,也没安装 @google/genai 或配置 API key。
- 你的需求是外部服务的实时审批,需要用事件系统或你自己宿主的工作流,而不是沙箱内钩子。
- 你对预算和失败重试没有明确预期,先别直接上线到生产。
准备材料
- 一个 Google Cloud 项目,并有 Gemini API 的访问权限和 API key。
- Node.js 环境或 Python 环境,用于调用 Interactions API。
- Gemini API 的 Managed Agents 文档和 agent-hooks 文档。
- 一个测试用的 sandbox 环境,以及一份你想要审核的工具清单。
- 一个能存放 hooks 脚本的本地目录,例如项目根目录的 .agents/。
步骤一:创建 Managed Agent 并选择模型
Managed Agents 默认运行 Gemini 3.6 Flash。你可以通过 agent_config.model 明确选择 gemini-3.6-flash、gemini-3.5-flash 或 gemini-3.5-flash-lite。先在测试项目里用一个最小交互跑通,再叠加钩子与预算,避免一上来就排查复杂调用。
- 安装 @google/genai SDK。
- 用 API key 初始化客户端。
- 创建一个使用 agent_config.model 的最小 Interaction,确保能返回结果。
- 记录你创建 Interaction 时使用的 environment ID。
步骤二:添加 .agents/hooks.json
环境钩子由一个 .agents/hooks.json 文件定义,放在你的环境(environment)里。运行时会在每次相关工具调用前(pre_tool_execution)或后(post_tool_execution)执行你指定的脚本。matcher 字段用正则匹配工具名,可以用 | 匹配多个,或用 * 匹配全部。
{
"gate": {
"pre_tool_execution": [
{
"matcher": "code_execution|write_file",
"commands": [
{ "type": "command", "command": "python3 /.agents/hooks-scripts/gate.py", "timeout": 10 }
]
}
]
}
}
步骤三:写 gate 脚本并定义拒绝规则
脚本需要能接收工具调用的上下文,并在需要拒绝时返回一个让运行时可识别的结果。官方文档说明,如果 pre_tool_execution 返回拒绝决定,工具调用会被跳过,拒绝原因会进入模型上下文。为保证脚本不无限阻塞,要设置合理 timeout。
- 在环境脚本里读取工具名称、参数或目标路径。
- 定义允许/拒绝规则,例如只允许写 /tmp 下或特定目录。
- 拒绝时返回包含原因的结构,避免只打印日志却不拦截。
- 给每个命令设置 timeout,防止脚本挂起导致任务停滞。
步骤四:配置 post 钩子做校验和格式化
post_tool_execution 在工具调用结束后运行,适合做产物校验、自动 lint 或生成审计清单。官方在 OffDeal 例子里用 post 钩子对 AI 生成的图像做验证,只有通过检查的文件才能进入成果集。
- 为需要校验的工具添加 post_tool_execution。
- 把校验结果写入一个明确路径或清单文件。
- 如果校验失败,让脚本记录原因,而不是静默通过。
- 检查钩子脚本是否有读写权限,避免因为权限不足造成假通过。
步骤五:设置 max_total_tokens 预算上限
自主循环会消耗较大 token 量。通过 agent_config 传 max_total_tokens 可以封顶输入、输出和思考的总量。达到上限后执行会安全暂停并返回 status: incomplete,环境状态保留,你可以用 previous_interaction_id 和新的预算继续。
{
"agent_config": {
"model": "gemini-3.6-flash",
"max_total_tokens": 200000
}
}
步骤六:用 scheduled triggers 做定时执行
如果你有每日报告、定时检查等重复任务,可以把 agent、environment、prompt 和 cron 绑定成 scheduled trigger。每次运行复用同一个沙箱,文件可以跨执行保留。先用手动触发确认结果稳定,再开放到定时。
- 先在手动模式跑 3 次以上,确认结果一致。
- 确认 budget 足够覆盖一次完整任务。
- 配置 cron 表达式并记录执行日志。
- 如果任务有副作用,先想好幂等,避免重复执行产生重复产物。
步骤七:用 Environments API 清理沙箱
Managed Agents 的沙箱默认有保留周期。通过 Environments API,你可以列出、查看和删除 sandbox 会话。流水线结束时主动清理,能减少未使用的沙箱残留和费用。
- 在任务结束的清理脚本里调用 Environments API。
- 按 environment ID 检查是否还需要保留。
- 删除不再需要的沙箱,并在日志里记录 ID。
- 对定时任务,在每次执行结束后决定是保留还是重建。
检查清单
- 已创建测试项目并跑通最小 Interaction。
- .agents/hooks.json 语法正确,matcher 覆盖目标工具。
- gate 脚本能返回可识别的拒绝结果,并设了 timeout。
- post 钩子会生成可读的校验/审计结果。
- max_total_tokens 已设置并测试过 incomplete 续跑。
- 定时触发已手动验证多次。
- 沙箱有明确的创建、保留和删除策略。
实际例子:给文件写入加目录白名单
假设你要让代理在沙箱里根据数据生成 Markdown 报告。先写一个 gate.py,读取预写文件的路径参数,凡是不在 /workspace/reports 下的 write_file 请求都返回 deny,并在原因里写清楚“只允许写入 reports 目录”。同时在 .agents/hooks.json 用 matcher=write_file 绑定它。接着设 max_total_tokens=100000 防止任务失控,手动触发一次生成报告,确认文件落在白名单目录;之后用 scheduled trigger 每天执行,并在 post 钩子检查文件非空和标题存在。
常见坑
- 把 hooks.json 放在本地项目根目录,却没有放到 agent 的环境里,导致钩子不生效。
- gate 脚本只打印日志,不返回可识别的拒绝结果,运行库无法拦截。
- 不设 timeout,脚本挂起会把整个任务卡住。
- 用 * 匹配所有工具但脚本没有处理未知参数,造成误拦。
- 忽略 incomplete 状态,以为任务完成,结果只是预算用完暂停。
排错路径
- 如果钩子没触发,确认 hooks.json 的路径、文件名和匹配器都正确。
- 如果拒绝没生效,检查脚本退出码和返回结构是否被运行时识别。
- 如果任务一直 incomplete,先看是否达到 max_total_tokens,再决定提高预算或拆分任务。
- 如果沙箱找不到,用 Environments API 列出环境 ID,确认有没有被删除或 TTL 到期。
可复制模板:Managed Agents 上线检查表
- 环境 ID:。
- 模型:gemini-3.6-flash / 其他。
- 需要拦截的工具:code_execution、write_file 等。
- gate 脚本路径:。
- post 校验脚本:。
- max_total_tokens:。
- 触发方式:手动 / cron。
- 沙箱清理策略:保留 N 天 / 每次删除。
- 更新日期:2026-08-21。
更新日期和维护建议
本文基于 Google 官方博客与 Gemini API 文档整理,更新日期为 2026-08-21。Managed Agents、hooks 事件、预算参数和沙箱 TTL 都可能随版本变化。每次升级 SDK 或 API 后,先在测试环境重跑一遍钩子与暂停续跑流程,再更新生产任务。