ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Long-Horizon Harness 沙箱环境 CLI 引导技能详解:bootstrap-google-tools 的安装与认证全流程

Long-Horizon Harness 沙箱环境 CLI 引导技能详解:bootstrap-google-tools 的安装与认证全流程 Long-Horizon Harness 沙箱环境 CLI 引导技能详解bootstrap-google-tools 的安装与认证全流程【免费下载链接】adk-samplesA collection of sample agents built with Agent Development Kit (ADK)项目地址: https://gitcode.com/GitHub_Trending/ad/adk-samples导读bootstrap-google-tools是 Long-Horizon Harness位于 core/python/long-horizon-harness内置的一项沙箱环境引导技能built-in skill专门解决一个真实而棘手的问题沙箱镜像以极简方式出厂——Node、gws、gcloud、agents-cli、mcp-cli全部缺席且运行时镜像升级时只迁移/workspace目录。本文将以该技能文档为骨架结合仓库源码与测试用例完整讲解每个 CLI 的安装配方、凭据持久化模型、短时令牌认证路径以及高频故障排查表让读者掌握在 Horizon 沙箱中按需装、装得对、认证不丢的完整实战能力。技能定位一份菜单而非一条流水线从技能 frontmatter 可以清晰看到它的使命见 SKILL.mdname: bootstrap-google-tools description: Install/auth CLIs the sandbox lacks - gws (Drive, Gmail, Sheets, Calendar), gcloud, agents-cli, mcp-cli (MCP servers). Use on command not found or before GCP/Workspace/MCP work.关键设计意图有三点按需安装四个工具相互独立这不是一条 1-2-3 顺序执行的流水线而是一份菜单任务需要哪个就装哪个只负责装好 认证每个工具的日常用法由各自的专属技能负责google-workspace、mcp-cli自带技能、google-agents-cli-*系列本技能完成任务后即交棒触发时机明确出现command not found或在开始 GCP / Google Workspace / MCP 相关任务之前调用。仓库用测试锁定了该技能的两个契约见 tests/unit/test_builtin_bootstrap_skill.py它必须能通过 ADK 的load_skill_from_dir正常解析防止 YAML 语法错误或漏提交文件并且**预注入令牌优先于 loopback 登录这一指令在文档中必须排在gws auth login之前**确保 Agent 遵循先探测令牌、再走 OAuth 登录的正确顺序。技能目录还要求只允许存在references/、assets/、scripts/子目录与SKILL.md本身。持久化模型二进制放~/.local凭据放/workspace沙箱存在两条不同的持久性边界这决定了所有安装决策普通会话之间沙箱重新挂载$HOME下的一切都保留——装一次下个会话直接复用运行时镜像升级时沙箱被重新供给re-provision只有/workspace会被迁移而且该迁移是 zip 打包——会丢弃符号链接、剥离可执行位且是 best-effort。因此它根本无法携带已安装的 CLI 二进制只适合存放纯数据文件。由此得出分而治之的存放规则这是整个技能最核心的工程判断内容存放位置升级后CLI 二进制~/.localbin 目录~/.local/bin已在PATH上丢失——重新安装成本低且command -v检查可自动触发凭据 / 配置/workspace/lha/config/gws/、gcloud/、mcp_servers.json随迁移保留——登录状态不丢不要把二进制放到/workspace它们反正无法迁移反而会撑大迁移 zip、威胁到那些能迁移的凭据。~/.local/bin已经由运行时镜像写入PATH且bash是非登录 shell没有~/.profile所以正是镜像里的那份PATH让安装后的命令得以解析。仓库的 sandbox-lifecycle.md 佐证了这一模型普通 reattach 是版本无关的$HOME/~/.local里的 CLI 能存活而显式升级/sandbox-upgrade才会重新供给并仅迁移/workspace。动手前先检查command -v在同一会话内以及没有升级的跨会话场景工具可能已就绪。安装前务必先探测只补装缺失项bash(commandcommand -v gws) # 或 gcloud / agents-cli / mcp-cli / node这也是升级后自动修复的依据——command -v返回非零即触发重装。Node npmgws的前置依赖沙箱是 Debian x86_64带curl和tar但没有xz。因此必须下载.tar.gz构建包而不是.tar.xz后者会因xz缺失而解压失败。选择一个当前 LTS 版本bash(commandmkdir -p ~/.local/bin cd ~ Vv22.x.x \ curl -fsSLo node.tgz https://nodejs.org/dist/$V/node-$V-linux-x64.tar.gz \ tar -xzf node.tgz -C ~/.local rm node.tgz \ ln -sf ~/.local/node-$V-linux-x64/bin/node ~/.local/node-$V-linux-x64/bin/npm ~/.local/node-$V-linux-x64/bin/npx ~/.local/bin/)将v22.x.x替换为真实的最新 LTS。最后一步ln -sf … ~/.local/bin/把node/npm/npx软链进PATH然后验证bash(commandnode --version npm --version)两个易错点务必使用.tar.gz符号链接步骤不能跳过~/.local/bin在PATH上而带版本的解压根目录不在。gwsGoogle Workspace CLI安装用 npm 全局安装到~/.local前置条件是 Node 已在PATH通过--prefix让二进制落在~/.local/bin/gwsbash(commandnpm install -g --prefix ~/.local googleworkspace/cli gws --version)预期版本为0.22.x。gws自我标识为非 Google 官方支持产品——它是社区 CLI包装了 Workspace REST API自动处理分页、重试与 JSON 解析但不捆绑任何凭据OAuth 客户端或服务账号必须由你配置详见 google-workspace 技能。关键把凭据留在/workspacegws默认读写~/.config/gws——该目录在运行时升级时不会被迁移。每次执行gws命令都要设置两个环境变量把配置目录迁到/workspace并使用文件型 keyringheadless 环境没有 OS keyringexport GOOGLE_WORKSPACE_CLI_CONFIG_DIR/workspace/lha/config/gws export GOOGLE_WORKSPACE_CLI_KEYRING_BACKENDfileGOOGLE_WORKSPACE_CLI_CONFIG_DIR重定位配置目录内含client_secret.json、令牌与加密密钥到/workspace让 OAuth client、token、加密密钥在升级后存活GOOGLE_WORKSPACE_CLI_KEYRING_BACKENDfileheadless 下没有系统 keyring文件后端把密钥写进配置目录因此也随之落在/workspace上。认证第一步永远优先探测预注入令牌当用户在网络 UI 中使用了Connect Workspace时GOOGLE_WORKSPACE_CLI_TOKEN这个 secret 会被自动注入到每一条bash命令的环境中它是gws优先级最高的认证源。技能要求不要检查环境、不要询问用户直接对目标面做一次廉价读取探测bash(commandexport GOOGLE_WORKSPACE_CLI_CONFIG_DIR/workspace/lha/config/gws GOOGLE_WORKSPACE_CLI_KEYRING_BACKENDfile gws gmail messages list --params {\maxResults\: 1})探测结果的三种解读返回数据令牌有效直接开工——不需要 OAuth client、不需要gws auth login、不需要 loopback 桥接403/ scope 错误令牌有效但用户授予的面不全或仅只读。Connect Workspace 是按面drive/gmail/calendar/sheets/docs/chat/tasks/slides/keep/script/meet/forms× 只读|读写授权的默认只读。此时应请用户重新连接以包含所需面或读写权限而不是启动登录流程401/ 未登录令牌确实缺失或已过期约 1 小时寿命无刷新此时才回退到下面的 OAuth-client 选项。切勿信任gws auth status在使用环境令牌时它报告auth_method: none/credential_source: token_env_var但读取仍然成功——所以真实读取是唯一可靠的检查手段。若跳过探测直接gws auth login会把用户拖进一个本来不需要的浏览器重定向桥接流程。仓库的注入机制在 horizon/secrets/inject.py 中有对应实现secret_env()把当前用户的 secrets 解析为{name: value}并注入沙箱命令环境且永不抛异常secret 解析失败也不能中断命令执行。认证第二路径为gws配置 OAuth clientgws不自带任何 OAuth client以下四种方式任选其一放入client_secret.json到/workspace/lha/config/gws/必须是Desktop app类型的 OAuth client——沙箱内首选详见google-workspace技能设置环境变量GOOGLE_WORKSPACE_CLI_CLIENT_IDGOOGLE_WORKSPACE_CLI_CLIENT_SECRET服务账号GOOGLE_APPLICATION_CREDENTIALS/workspace/lha/config/gws/key.json——适合完全无人值守的自动化无需交互登录gws auth setup可自动开通 GCP 项目 OAuth client但是全屏 TUI无法 headless 驱动沙箱内优先方案 1。gws auth login仅支持 loopback-browser 流程但在沙箱中可以 headless 完成——需要手工桥接 OAuth 重定向后台启动它把授权 URL 转给用户再把用户粘贴回的localhost:port/?code...重定向用curl送回等待中的监听器localhost在 Layer A 外发防护的白名单上该curl不会被拦截。完整的认证配方Desktop-app 类型、Internal 受众、loopback 桥接以及 Drive/Docs/Sheets/Gmail/Calendar/Chat 的命令形态都在 google-workspace 技能 中。若任务完全无人值守、没有用户粘贴重定向请使用服务账号方案。Routine 场景提醒在 routine定时任务下Google/gcloud 令牌仅当你在 routine 的secrets:中声明了其 secret 名称GOOGLE_WORKSPACE_CLI_TOKEN/CLOUDSDK_AUTH_ACCESS_TOKEN才会出现——这正是 inject.py 中scoped_secret_env()的职责routine 只拿到其清单显式声明的 secret绝不暴露用户的完整 secret 面。强烈建议安装 Google 官方gws技能gws就绪后技能强烈建议安装 Google 官方按面拆分的gws技能位于googleworkspace/cli仓库比内置google-workspace技能更深入每个面一个bash(commandnpx --yes skills add googleworkspace/cligws-shared -y) bash(commandnpx --yes skills add googleworkspace/cligws-gmail -y) # 还有: gws-drive, gws-docs, gws-docs-write, gws-sheets, gws-calendar, # gws-events, gws-chat-sendSkills CLI 会把每个技能暂存到.agents/skills/skill/下Horizon 会自动发现——只需load_skill(actionreload)即可无需移动详见 find-skills 技能。其底层机制在 horizon/tools/skill_loader.pywalk_skill_dirs合并内置技能根horizon/builtin_skills/与用户技能根workspace/.agents/skills/同名时用户技能遮蔽内置技能build_skill_toolset移除ListSkillsTool使 ADK 每轮自动向系统提示注入available_skills目录模型无需为list_skills花费一次往返。npx --yes skills find gws可列出当前技能集及安装数。gcloudGCP 命令行安装装到~/.local精简安装不要添加额外组件并把入口软链到PATHbash(commandmkdir -p ~/.local/bin cd ~/.local \ curl -fsSLo gcloud.tgz https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-cli-linux-x86_64.tar.gz \ tar -xzf gcloud.tgz rm gcloud.tgz \ ./google-cloud-sdk/install.sh --quiet --usage-reportingfalse --path-updatefalse \ ln -sf ~/.local/google-cloud-sdk/bin/gcloud ~/.local/google-cloud-sdk/bin/gsutil ~/.local/google-cloud-sdk/bin/bq ~/.local/bin/)验证bash(commandgcloud --version)。沙箱中不保留任何持久化的 gcloud 凭据。GCP 访问走下面的短时令牌即 secret路径不落任何东西——没有 refresh token、没有 ADC 文件、没有密钥。可以设CLOUDSDK_CONFIG/workspace/lha/config/gcloud作为 scratch 配置目录但没有需要跨升级持久化的登录状态。安全基线GCP 凭据是高信任组合登录会沉淀下Agent 自己可用的凭据而沙箱又有开放的出站互联网。一旦 Agent 被注入恶意指令它可能读取用户的 GCP 数据、bq extract/gsutil cp到外部桶、铸造服务账号密钥、或在*.googleapis.com上授予外部 IAM。Layer Aexfil_guard仍会拦截凭据/secret 外传和对非白名单主机的上传并封锁 GCP metadata server但它没有 GCP 动作感知看不到gcloud调用在做什么。因此真正的控制手段是凭据最小化只走短时令牌路径见下沙箱内不留任何持久凭据refresh token / ADC 文件 / SA key一次注入无法变成超出约 1 小时令牌寿命的常驻访问铸造令牌时使用任务所需的最窄 scopecloud-platform用户 IAM 允许的一切是宽泛的高信任默认值绝非免费通行证在把令牌加入沙箱前先确认用户确实希望 Agent 以他们的身份在 GCP 上行动。认证唯一 GCP 路径短时访问令牌即 secret这是信任最低、摩擦最小的路径也是唯一使用的方式同样适用于 corp / 组织受限账号用户在自己的终端上已以正确账号通过 gcloud 认证因而满足组织的设备/CAA 策略本地铸造短时访问令牌gcloud auth print-access-token用户在/lha/secretsUI 中把它保存为名为CLOUDSDK_AUTH_ACCESS_TOKEN的 secret——绝不粘贴到聊天里它是活凭据secrets 会被自动注入为每条bash命令的环境变量gcloud 会从环境读取CLOUDSDK_AUTH_ACCESS_TOKEN——Agent 直接跑命令即可无需 login、无需 ADC、无需 OAuth clientbash(commandexport CLOUDSDK_CONFIG/workspace/lha/config/gcloud gcloud projects list)gsutil和bq读取同一个环境令牌。不要在curl/wget里指名这个令牌如-H Authorization: Bearer $CLOUDSDK_AUTH_ACCESS_TOKEN外发防护会硬拦截引用了 secret 环境变量的网络命令这是有意的设计——阻止 Agent 把令牌外带。请使用 gcloud 系列 CLI它们无需指名即可从环境读取必须携带令牌的裸 REST 调用需要/grant。为什么这是默认方案短时约 1 小时一次注入无法变成常驻访问到期后用户重新铸造并更新 secret沙箱内无持久物/workspace上没有可复用的 refresh token对组织友好同意流程已在用户组织批准的本地 gcloud 中完成——没有Account restricted、没有自定义 OAuth client、没有远程引导局限该窗口内它确实以用户身份行动短寿命限制了滥用但并未消除且携带用户登录时的 scopes。长时无人值守任务中令牌约 1 小时即过期必须重新铸造并更新 secret——设计上我们不在沙箱保留任何可回退的持久凭据。agents-cli调用远程 AgentA2A / ADK要把任务交给远程部署的另一个 AgentCloud Run、Vertex Agent Runtime或任意 A2A 端点直接 shell 出去调用agents-cli即可无需进程内接线。这是进程内subagent()的出站对应物远程 Agent 是拥有自身状态的独立服务你只是通过 HTTP 发送一个 prompt。安装一次性沙箱已带uv它装到~/.local/binbash(commandcommand -v agents-cli || uv tool install google-agents-cli) bash(commandagents-cli --version)安装从google-agents-cli的发布索引拉取——若沙箱无法访问该索引这与 Node/gcloud 下载是同样的出站依赖。调用bash(commandagents-cli run summarize this repo --url https://my-agent-xxxx.run.app --mode a2a)参数要点--mode a2a走 A2A 协议--mode adk走 ADK SSE/run_sse或 Agent Runtime 的:streamQuery。--mode与--url同时使用时是必填的--app-name name定向到该端点上的特定 Agent--session-id id延续会话-v输出完整 JSON 事件stdout 就是远程 Agent 的最终响应——那即是你的结果阻塞式。对于长时远程任务用process(actionspawn, command...)启动并以 fire-and-forget 方式通过process工具轮询。认证——通常自动完成agents-cli从沙箱身份自动探测 Google 凭据——Cloud Run 用ID tokenaudience 服务 URLVertex AI / Agent Runtime 用access token。要得到可用令牌沙箱/Cloud Run 服务账号需要对目标有正确的 IAMCloud Run 需要roles/run.invokerAgent Runtime 需要 Vertex 权限——401/403几乎总是 IAM 缺失而不是 CLI 的问题。用户委托认证以用户身份调用显式传入令牌覆盖自动探测bash(commandagents-cli run ... --url https://... --mode a2a -H Authorization: Bearer $USER_TOKEN)令牌应从 secrets / headless-auth 子系统获取绝不在聊天中内联原始 secret。--url是瘦客户端——它不加载本地技能远程 Agent 的技能归远程自己管。如果需要agents-cli更广的工具链scaffold、deploy、eval、observability、publish、workflow按需通过 find-skills 技能 安装相应技能。mcp-cli调用 MCP 服务器暴露的工具在沙箱中调用MCP 服务器GitHub、filesystem、数据库、第三方 API暴露的工具时使用。这是客户端侧——通过bash使用外部 MCP 服务器而非运行一个。认证仅支持静态令牌——通过${VAR}headers 注入服务器的 bearer见下没有 OAuth/consent 流程。GCP 请使用gcloud一节的令牌即 secret 路径而非 MCP。安装不要 pipe-to-bashinstall.sh会下载一个校验和验证的、自包含的预编译二进制mcp-cli-linux-x64约 100 MB到~/.local/bin/mcp-cli。它用 Bun 编译但安装与运行时都不需要 Bun/Node——完全独立。不要curl … | bash工具策略会拦截把远程内容管道进 shell。请先下载脚本再从文件执行bash(commandcommand -v mcp-cli || (curl -fsSLo /tmp/mcp_install.sh https://raw.githubusercontent.com/philschmid/mcp-cli/main/install.sh bash /tmp/mcp_install.sh)) bash(commandmcp-cli --version)可选先read(/tmp/mcp_install.sh)——它只是抓取最新发布二进制并校验 SHA256。装到~/.local/bin。配置服务器真正的 onboarding 工作mcp-cli是配置驱动的它读取mcp_servers.json。把它放在/workspace配置是数据文件——可迁移并用MCP_CONFIG_PATH它的最高优先级解析器指向它默认的~/.config/mcp/…不会被迁移export MCP_CONFIG_PATH/workspace/lha/config/mcp_servers.json写入该文件与 Claude-Desktop / Gemini / VS-Code 兼容{ mcpServers: { filesystem: { command: npx, args: [-y, modelcontextprotocol/server-filesystem, /workspace] }, remote-api: { url: https://mcp.example.com, headers: { Authorization: Bearer ${MCP_TOKEN} } } } }stdio服务器 →commandargs沙箱能 spawn 的服务器本身也要装好例如通过npx/uvxHTTP服务器 →urlheaders认证headers中的${VAR}在配置加载时从环境替换缺失的变量会报错除非设MCP_STRICT_ENVfalse。该令牌从secrets 子系统环境注入获取——绝不内联原始 secret。使用bash(commandmcp-cli) # 列出服务器 工具 bash(commandmcp-cli info filesystem read_file) # 工具 schema bash(commandmcp-cli call filesystem read_file {\path\: \./README.md\})用call调用、info检视——直接写mcp-cli server tool是有歧义的会报错。完整参考可经find-skills安装 mcp-cli 自带的用法技能。故障排查速查表技能文档提供了一份按症状组织的排障表是沙箱运维中最实用的部分症状原因 / 修复运行时升级后任何工具 command not found二进制在$HOME下、不被迁移——按本技能重装command -v检查会自动触发安装后node/gcloud: command not found跳过了ln -sf … ~/.local/bin/软链步骤补跑即可~/.local/bin在 PATH 上而带版本/SDK 的 bin 目录不在tar: ... cannot exec xz下载了.tar.xz改用.tar.gz构建包升级后gws又要求登录其凭据被写到了$HOME下未迁移每次调用都设置GOOGLE_WORKSPACE_CLI_CONFIG_DIR指向/workspace/lha/config/*gcloud 不保留持久登录——重新添加令牌 secretgws登录令牌未保存 / 无 keyring设置GOOGLE_WORKSPACE_CLI_KEYRING_BACKENDfile与 config-dir 导出一起gws auth status显示auth_method: none但读取正常当GOOGLE_WORKSPACE_CLI_TOKEN是来源时这符合预期——auth status不反映环境令牌。用真实读取确认不要启动登录流程gws auth login挂在监听器上headless 下的预期行为——桥接重定向见google-workspace技能或无人值守时改用服务账号403 access_denied Account restrictedOAuth client 上有 Context-Aware Access——别硬刚。改用令牌即 secret路径用户本地跑gcloud auth print-access-token并存为 secretCLOUDSDK_AUTH_ACCESS_TOKEN网络命令被拦截reads a credential path or secret env var不要在curl/wget中指名$CLOUDSDK_AUTH_ACCESS_TOKEN或任何*_TOKEN/*_KEY——外发防护会硬拦截。让gcloud/gsutil/bq从环境读取裸 REST 调用需要/grant无人值守任务没有 GCP 令牌CLOUDSDK_AUTH_ACCESS_TOKENsecret 缺失或过期提示需要一个新令牌并停止——不要循环agents-cli: command not founduv tool install google-agents-cli沙箱已带 uv远程agents-cli run --url401/403目标上缺少 IAMroles/run.invoker/ Vertex 权限不是 CLI 的 bug--mode is required when using --url给远程调用加上--mode a2a或--mode adkmcp-cli: command not found下载install.sh后bash该文件不要\| bash——策略拦截装到~/.local/binmcp-cliAMBIGUOUS_COMMAND用mcp-cli call/info server tool不要用mcp-cli server toolmcp-cli 配置加载时${VAR}缺失导出令牌来自 secrets 子系统或设MCP_STRICT_ENVfalse从技能到机制Horizon 的技能加载体系bootstrap-google-tools之所以能成为内置技能背后是 Horizon 的双根技能加载体系horizon/tools/skill_loader.py两个技能根内置技能随包发布在horizon/builtin_skills/name/SKILL.md用户技能位于workspace/.agents/skills/name/SKILL.mdnpx skills add的暂存位置也是生态标准。walk_skill_dirs合并两者同名时用户技能遮蔽内置技能容错加载单个 SKILL.md 损坏只产生警告并被跳过绝不污染整个技能目录每轮自动注入build_skill_toolset移除 ADK 的ListSkillsTool使available_skills目录在每轮被自动注入系统提示模型无需显式list_skills沙箱后端适配mirror_user_skills_to_host通过环境接口的异步list_directory/read_file把沙箱内/workspace/.agents/skills镜像到宿主机加载器可读的位置两个后端sandbox / local共用同一套技能目录逻辑。这份架构保证了Agent 遇到command not found时能按 find-skills 技能 的流程找到并安装新技能也能随时load_skill(actionreload)刷新已装技能的目录——与bootstrap-google-tools的装好即交棒设计无缝衔接。总结bootstrap-google-tools用一份文档把沙箱中最容易踩坑的四类问题一次性讲透装什么按需、不贪多、装在哪二进制~/.local、凭据/workspace、怎么认证令牌优先探测、OAuth client 兜底、GCP 令牌即 secret、服务账号无人值守以及坏了怎么办按症状索引的排障表。它的核心工程哲学可以浓缩为一句话让贵的OAuth 客户端与令牌跨升级存活让便宜的二进制升级后廉价重装。结合 secrets/inject.py 的 secret 环境注入、skill_loader.py 的双根技能发现以及 tests/unit/test_builtin_bootstrap_skill.py 锁定的令牌路径必须先于登录路径契约这套引导体系保证了 Agent 在长时、跨会话、跨镜像升级的任务中始终能以最小凭据面稳定访问 Google Workspace、GCP 与 MCP 生态。【免费下载链接】adk-samplesA collection of sample agents built with Agent Development Kit (ADK)项目地址: https://gitcode.com/GitHub_Trending/ad/adk-samples创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表