首页
/ Claude 托管智能体公路旅行规划器:从密钥配置到会话流式传输的完整部署与调试指南

Claude 托管智能体公路旅行规划器:从密钥配置到会话流式传输的完整部署与调试指南

2026-09-07 16:30:26作者:董宙帆

导读

managed_agents/roadtrip_planner 是构建在 Claude Managed Agents Session 之上的一个 Next.js 全栈示例,其 skill.md 提供了一份"自上而下、每步有验证"的完整部署清单:它引导你申请三类密钥、一键供给云端沙箱与两个 Agent、启动本地聊天界面,并演示会话事件流、保险库凭据注入位置、按会话模型覆盖以及多 Agent 协同评审四项核心 API 能力。读完本指南,你将能独立完成该项目的环境搭建、四步功能演示、常见故障定位与一键重置,并理解每个配置项背后的源码实现依据。

一、项目是什么:一个不需要数据库的 Agent 聊天后端

在进入逐级搭建之前,先理解 skill.md 所服务的对象。整个应用建立在这样一个思想上:Managed Agents 会话本身就是可续聊的聊天后端。从 README.md 可以看到,它没有使用任何聊天框架、也没有数据库:

  • 会话的事件日志(GET /v1/sessions/{id}/events)就是消息列表;
  • 实时的 token 就是该会话 SSE 流的尾部;
  • 流式路径上唯一的服务端代码,是一个把 API Key 留在服务端、不让浏览器接触的薄代理。

前端架构的核心数据流可概括为:

浏览器 ──▶ POST /api/chat ──▶ sessions.events.send(user.message)
   ▲
   │ 一条 EventSource              GET /v1/sessions/{id}/events/stream
   └── GET /api/stream ◀──────────   ?event_deltas[]=agent.message
       (薄 SSE 代理)                &event_deltas[]=agent.thinking

沙箱端,Agent 通过 curl 访问两个白名单主机(美国国家公园管理局 NPS 与 Windy 天气),密钥以占位符形式存在于沙箱环境变量中,由平台在出口处按规则替换为真实值;规划 Agent 起草完行程后,还会通过线程把草稿发送给"评审 Agent"(运行在 Opus 上)换取批评意见,整个过程都是普通会话事件,见 README.md

该目录还配套了一份面向代码维护者的 CLAUDE.md,其中总结了若干必须保持的不变量(流是"尾部而非回放"、预览是推测性的、单一折叠函数渲染历史与实时等),这些不变量会在本文相应小节中印证。

二、准备工作:三把密钥与 Node 环境

skill.md 的第一步是 Keys。搭建前需要三把不同的凭据,其用途与获取方式如下表:

密钥 获取位置 说明
ANTHROPIC_API_KEY Anthropic Console 的 API Keys 页面 也可跳过它,用 ant auth login 登录一次即可;组织必须具备 Managed Agents 访问权限
NATIONAL_PARK_SERVICE_API_KEY NPS 开发者注册页面 免费,注册后即时邮件下发
WINDY_API_KEY Windy Point Forecast API 文档页 免费档,使用 point-forecast 产品

环境要求:Node 20 或更高版本,@anthropic-ai/sdk 使用最新发布版(本仓库 package.json 锁定 ^0.109.0)。

密钥就位后,创建本地环境变量文件并填入三个值:

cp .env.example .env.local   # 然后填上三把 key

模板文件 .env.example 中同时预留了另外两个可选配置项(后续"供给脚本"会说明它们的作用):

ANTHROPIC_API_KEY=
NATIONAL_PARK_SERVICE_API_KEY=
WINDY_API_KEY=

# 可选
# ROADTRIP_PLANNER_MODEL=claude-sonnet-5
# ROADTRIP_PLANNER_REVIEWER_MODEL=claude-opus-4-8

从源码看,setup/env.ts 是这些环境变量的解析器:它只识别 KEY=valueKEY="value" 两种格式、已有 shell 值优先、保存时保留注释与未知行,并且写回时设置 0o600 权限——因为该文件里躺着三把第三方密钥。

三、先在你的机器上验证供应商密钥(在进入沙箱之前)

skill.md 特别强调:在把沙箱牵扯进来之前,先在自己机器上验证供应商密钥。这一步能把"密钥本身有问题"与"沙箱配置有问题"这两种故障分开。两条验证命令如下:

curl -sS "https://developer.nps.gov/api/v1/alerts?parkCode=acad&limit=1" -H "X-Api-Key: $NATIONAL_PARK_SERVICE_API_KEY" | head -c 300
curl -sS -X POST "https://api.windy.com/api/point-forecast/v2" \
  -H "Content-Type: application/json" \
  -d '{"lat":44.35,"lon":-68.21,"model":"gfs","parameters":["temp"],"levels":["surface"],"key":"'"$WINDY_API_KEY"'"}' | head -c 300

两条命令都应返回 JSON。这里有一个重要的判别准则:如果出现 403,那是密钥的问题,不是 cookbook 的问题。注意两条命令已经体现了两家供应商认证方式的根本差异——NPS 把密钥放在 HTTP 请求头(X-Api-Key),Windy 把密钥放进 POST 的 JSON 请求体内。这个差异正是后文"凭据注入位置"演示的起点。

四、一次性供给:npm installnpm run setup

4.1 供给命令

npm install
npm run setup

package.json 将供给脚本映射为 tsx setup/create.ts(见 package.json 的 scripts 字段)。skill.md 对该脚本的产出描述如下:它创建了——

  1. 环境(environment):一个网络被限制为只能访问 developer.nps.govapi.windy.com 两个主机的云端沙箱;
  2. 评审 Agent(reviewer):运行在 Opus 上、只做评审的 prompt;
  3. 规划 Agent(planner):开启 bash、关闭 web_search/web_fetch,并配置一个 multiagent 协调者名单(coordinator roster),名单中指名评审 Agent;
  4. 保险库(vault):存放两把厂商密钥;
  5. 两条 environment_variable 类型凭据:各自按厂商文档硬编码了 injection_location(NPS 走 header,Windy 走 body)。

供给完成后,脚本把六个 ROADTRIP_PLANNER_* id 写入 .env.local,这些 id 即随后每次运行与每次演示时引用的句柄。

4.2 供给脚本的源码级拆解

setup/create.ts 的执行顺序严格对应 skill.md 的描述,我们从实现上逐层印证:

前置校验。脚本首先确认 ANTHROPIC_API_KEY 存在,否则回退到 ant auth login 保存的凭据,二者都没有才报错退出;随后通过 requireEnv 强制要求两个厂商密钥存在。

幂等性判断。如果 .env.local 里已存在一个存活的 Agent,脚本直接跳过(除非传入 --force)。一个值得注意的细节是:如果存储的规划 Agent 早于评审名单出现(即 alive.multiagent 为空),脚本不会静默继续,而是打印提示、要求用 npm run setup -- --force 重新供给双 Agent 版本——因为"无名单的旧 Agent 永远不会发生评审交接"。--force 则会供给一份全新的副本。

1. 创建环境(外层防火墙)limited 网络是"外城墙":容器只能连接名单上的两个主机(没有软件包源、没有 MCP 服务器、没有其他任何主机):

const environment = await client.beta.environments.create({
  name: "roadtrip_planner",
  config: {
    type: "cloud",
    networking: { type: "limited", allowed_hosts: [NATIONAL_PARK_SERVICE_HOST, WINDY_HOST] },
  },
  metadata: { cookbook: "roadtrip_planner" },
});

2. 创建评审 Agent(先于规划 Agent,因为规划者的名单要引用它的 id)。评审者刻意做得"小":从不需要调用厂商 API、也看不到保险库,它只是从线程消息里读出行程草稿、回一份简短批评。把它跑在 Opus 上、而规划者默认跑在 Sonnet 上正是设计意图——在不触碰规划 Agent 的前提下,把"快速把关"路由给更强的模型:

const reviewer = await client.beta.agents.create({
  name: "Plan reviewer",
  model: REVIEWER_MODEL,
  system: REVIEWER_SYSTEM,
  tools: [{
    // 默认拒绝:评审者只评判草稿文本,即使草稿被投毒也没有工具可调
    type: "agent_toolset_20260401",
    default_config: { enabled: false },
    configs: [],
  }],
});

3. 创建规划 Agent(关闭联网搜索是刻意的)web_searchweb_fetch 被显式关闭:一旦打开,模型就能从公开网络直接作答、永远不碰保险库里的 API,整个演示就失效了。multiagent 名单使它成为协调者——它可以把评审 Agent 作为会话线程拉起并交换消息;名单 Agent 自身不能再拥有名单(深度上限为 1):

const agent = await client.beta.agents.create({
  name: "Road trip planner",
  model: MODEL,                    // 默认 claude-sonnet-5
  system: SYSTEM,
  multiagent: { type: "coordinator", agents: [reviewer.id] },
  tools: [{
    type: "agent_toolset_20260401",
    default_config: { enabled: true },
    configs: [
      { name: "web_search", enabled: false },
      { name: "web_fetch", enabled: false },
    ],
  }],
});

两个 Agent 的系统提示词定义在 setup/config.ts。规划者的 SYSTEM 规定了"每次提问最多 5 次 API 调用"的预算、逐日行程格式、以及对供应商拒绝调用的处理策略;REVIEWER_SYSTEM 则要求评审者 120 词以内、先给一句结论再加至多三条编号问题、只评判消息内的内容。评审者的提示词与其 deny-by-default 工具集互为补充("提示词说一遍,工具集强制一遍")。

4. 创建保险库。凭据存放在 vault 中,而不是环境或提示词里;会话在创建时通过 vault_ids 选择加入。

5. 创建两条凭据(同一机制、完全相反的注入位置)。沙箱中看到的是 $NATIONAL_PARK_SERVICE_API_KEY / $WINDY_API_KEY 这样的不透明占位符,只有当"请求主机在凭据 allowed_hosts 占位符位于 injection_location 允许的位置"时,真实密钥才会在出口被替换:

const nationalParkService = await client.beta.vaults.credentials.create(vault.id, {
  display_name: "National Park Service API key (header)",
  auth: {
    type: "environment_variable",
    secret_name: "NATIONAL_PARK_SERVICE_API_KEY",
    secret_value: nationalParkServiceKey,
    networking: { type: "limited", allowed_hosts: [NATIONAL_PARK_SERVICE_HOST] },
    injection_location: { header: true, body: false },   // NPS:仅 header
  },
});

const windy = await client.beta.vaults.credentials.create(vault.id, {
  display_name: "Windy API key (body)",
  auth: {
    type: "environment_variable",
    secret_name: "WINDY_API_KEY",
    secret_value: windyKey,
    networking: { type: "limited", allowed_hosts: [WINDY_HOST] },
    injection_location: { header: false, body: true },   // Windy:仅 body
  },
});

供给脚本最终写入的六个 id 汇总如下(也即 .env.local 末尾被追加的内容):

变量 对象
ROADTRIP_PLANNER_ENVIRONMENT_ID 沙箱环境
ROADTRIP_PLANNER_AGENT_ID 规划 Agent
ROADTRIP_PLANNER_REVIEWER_AGENT_ID 评审 Agent
ROADTRIP_PLANNER_VAULT_ID 保险库
ROADTRIP_PLANNER_NATIONAL_PARK_SERVICE_CREDENTIAL_ID NPS 密钥凭据(header)
ROADTRIP_PLANNER_WINDY_CREDENTIAL_ID Windy 密钥凭据(body)

可覆盖的模型选择。两个模型的默认值来自 setup/config.tsROADTRIP_PLANNER_MODEL 默认 claude-sonnet-5ROADTRIP_PLANNER_REVIEWER_MODEL 默认 claude-opus-4-8,均可在 .env.local 中覆盖后重新运行供给。

五、启动并运行:npm run dev 与四个演示步骤

5.1 启动命令

npm run dev

然后打开 http://localhost:3000skill.md 强调了一个细节:页面在加载时就会为每个浏览器创建一条会话(cookie 名为 roadtrip_planner_session_id),因此在你发出第一个问题之前沙箱就已经是"热"的。该 cookie 在整个应用中承载着唯一的身份概念——它是 httpOnly 的,会话 id 不暴露给前端脚本(见 src/lib/client.ts)。

5.2 打开页面背后的两条 API 调用链

页面加载即触发 src/app/api/session/route.tsPOST:优先续用 cookie 指向的存活会话并按其 events.list(升序、每页 100 条)回放整个事件日志;若会话已归档/终止则静默新建。新建时统一走 agent_with_overrides 选择器,同时把会话绑定到供给好的环境与保险库:

session ??= await client.beta.sessions.create({
  agent: {
    type: "agent_with_overrides",
    id: env("ROADTRIP_PLANNER_AGENT_ID"),
    ...(body.model ? { model: body.model } : {}),   // 选择模型时追加 override
  },
  environment_id: env("ROADTRIP_PLANNER_ENVIRONMENT_ID"),
  vault_ids: [env("ROADTRIP_PLANNER_VAULT_ID")],     // 保险库只在创建时挂载
  title: `Road trip - ${new Date().toISOString().slice(0, 10)}`,
});

同时,浏览器通过一条 EventSource 连上 src/app/api/stream/route.ts 的 SSE 代理。该代理是整条流式路径上唯一需要服务端存在的原因——把 API Key 留在服务端。它带着两个关键查询参数请求会话事件流:

tail = await client.beta.sessions.events.stream(sessionId, {
  event_deltas: ["agent.message", "agent.thinking"],
});

event_deltas 正是这个 cookbook 的主角之一:agent.message 预览让回复逐 token 抵达,agent.thinking 预览则只在扩展思考开始时触发一次(开始即亮起"thinking…",而缓冲事件要等思考结束才落盘)。流是"尾部而非回放":连接建立前发出的事件只存在于 events.list 中,因此 src/lib/use-managed-agent-session.ts 在每次连接/重连(source.onopen / source.onerror)都会先 resync() 重新拉取一次事件日志再信任流尾。

5.3 四个演示步骤("four things to do with it")

skill.md 要求按 README.md 中的"four things to do with it"小节顺序做完四个演示。以下是每个演示的要点:

Beat 1 —— 请它规划行程。 提问:"Plan a 5 day road trip split between Zion and Bryce Canyon for the first week of October." 规划者会先调用 /parks?q=... 解析公园(得到 parkCode 与经纬度),再基于 API 返回的事实做规划。状态行在模型开始推理的瞬间翻转为 "thinking..."(这就是 agent.thinking 预览);回复边写边渲染。右侧工具栏逐条展示 Agent 在沙箱里运行的每条 curl——它在每个问题内自限 5 次调用,每次都命中允许的主机、每次都用它读不到的密钥认证。换成 Acadia、Yellowstone、Joshua Tree 等任何公园均可。

Beat 2 —— 翻转一个字段,观察供应商拒绝占位符。 这是"保险库 + 注入位置"的故事,需要前面已经存在真实对话才最有说服力。使用 ant CLI 更新存活的凭据(它复用供给时保存的凭据,id 在 .env.local 中):

eval "$(grep '^ROADTRIP_PLANNER_' .env.local)"
ant beta:vaults:credentials update \
  --vault-id "$ROADTRIP_PLANNER_VAULT_ID" \
  --credential-id "$ROADTRIP_PLANNER_NATIONAL_PARK_SERVICE_CREDENTIAL_ID" \
  --auth '{type: environment_variable, injection_location: {header: false, body: true}}'

NPS 只接受把密钥放在请求头里,而现在该凭据的 header 注入被关闭了:没有任何机制替换占位符,下一次 NPS 调用会带着字面占位符发出并被拒绝。此时问一句 "is anything closed at the park right now",就能看到 4xx 落进工具栏:Agent 会展示状态码与响应体、按文档位置重试一次 header 注入,然后坦率地说 NPS 正在拒绝它的密钥,同时继续用天气 API 规划。恢复命令就是把两个布尔值翻回去:

eval "$(grep '^ROADTRIP_PLANNER_' .env.local)"
ant beta:vaults:credentials update \
  --vault-id "$ROADTRIP_PLANNER_VAULT_ID" \
  --credential-id "$ROADTRIP_PLANNER_NATIONAL_PARK_SERVICE_CREDENTIAL_ID" \
  --auth '{type: environment_variable, injection_location: {header: true, body: false}}'

"一个字段、无密钥轮换、无重新部署、可见后果"。同一翻转也适用于 Windy 凭据($ROADTRIP_PLANNER_WINDY_CREDENTIAL_ID,两个布尔值取反),因为 Windy 只文档化了 body 认证。注意 Caveat:injection_location 只有 headerbody 两个开关,没有查询串(query-string)选项?api_key=... 形式的密钥永远不会被替换。

Beat 3 —— 让同一个 Agent 跑在不同的模型上。 这是 agent_with_overrides 模型选择器的演示:在页头选择另一个模型,新行程就会在每次会话都使用的选择器上追加一个 model override:

anthropic.beta.sessions.create({
  agent: { type: "agent_with_overrides", id: agentId, model: "claude-opus-4-8" },
  // ...
});

override 只对本次会话替换存储 Agent 的模型。页头展示的模型来自会话已解析的 agent 快照(session.agent.model),所以"你读到的是 API 实际解析的结果,而不是客户端请求的内容"。存储的 Agent 从不改变:没有副本、没有新版本,"New trip"回到其配置模型。systemtoolsmcp_serversskills 可以用同样方式覆盖。关于覆盖范围的边界,src/app/api/session/route.ts 在捕获创建错误时还做了一层翻译:400 若包含 agent_reference 或 "Extra inputs are not permitted",意味着组织的 agent_with_overrides 闸门尚未开放,属于准入问题而非供给问题。

Beat 4 —— 看规划者把方案交给评审。 需要一次完整的逐日行程提问(Beat 1 的 Zion/Bryce 提示词即可),单一事实类问题不会触发。草稿写完、评审意见返回之前,状态行会翻转为 "waiting on Plan reviewer...":规划者把名单中的评审 Agent 拉成会话线程并把草稿发给它。评审者是 npm run setup 创建的第二份存储 Agent,其创建方式如下:

const reviewer = await anthropic.beta.agents.create({
  name: "Plan reviewer",
  model: "claude-opus-4-8",
  system: REVIEWER_SYSTEM, // 快速把关:一行结论 + 至多 3 个问题
  tools: [{ type: "agent_toolset_20260401", default_config: { enabled: false }, configs: [] }],
});

const planner = await anthropic.beta.agents.create({
  name: "Road trip planner",
  model: "claude-sonnet-5",
  multiagent: { type: "coordinator", agents: [reviewer.id] },
  // ...
});

没有人请求评审。名单授予了能力,而规划者自己的系统提示词决定何时使用:新的逐日行程会被评审,快速的实况问答不会。发送草稿不是工具调用、也不是应用请求,唯一的踪迹就是线程事件本身。一次会话两个模型:Sonnet 起草、Opus 把关;评审者的 deny-by-default 工具集既是安全边界(被投毒的草稿没有任何工具可触及),也是评审速度的保障。评审的往返会同时渲染在两处:聊天流里出现 "to Plan reviewer"(草稿发出)与 "from Plan reviewer"(批评返回)两个 chip;右侧工具栏则依次展示 session.thread_created、两个 agent.thread_message_*(含全文)以及线程闲置状态事件。整场评审的代价是"一个额外 Agent + 零管道"——没有队列、没有 webhook、没有第二个会话。

5.4 前端为什么没有状态管理库

src/lib/transcript.ts 可以看出,整个应用只有"一次折叠":foldTranscript 把事件数组折叠成可渲染的回合(turn),它同时作用于加载时的历史回放和流式追加后的实时数组,因此刷新后渲染出的内容与流式渲染完全一致——历史与实时"按构造"相同。流上其余一切事件都是状态信号:span.model_request_* 驱动工作态与 token 统计、agent.thread_message_sent 把活动行翻转为等待评审、session.error 区分"重试中"与"回合已死"。停止按钮 POST user.interrupt,随后的 session.status_idle 把界面翻回就绪。

六、故障排查速查表(skill.md 调试表全量整理)

skill.md 附带的调试表覆盖了从供给到运行的几乎所有已知故障,下面按原文档逐行完整保留:

症状 原因 修复
npm run setup/v1/environments 上 404 组织未开通 Managed Agents 申请访问权限,或切换组织
tsc 拒绝 event_deltasinjection_locationlib/sessions/accumulate 导入 已安装的 SDK 早于 2026-07-01 的 Managed Agents 更新 升级 @anthropic-ai/sdk
回复整段到达,无逐 token 渲染 组织流式闸门未开放(未放行时 event_deltas 被静默忽略),或旧版 SDK 的流解析器丢弃它不认识的 event_start / event_delta 事件 确认组织已加入该更新;升级 @anthropic-ai/sdk
选择模型报 400:"Agent must be a non-empty Agent ID or agent_reference"(或旧版 "Extra inputs are not permitted") 组织的 agent_with_overrides 闸门未开(关闭的闸门会把选择器当成未知的 agent 形态而拒绝) 在组织加入该更新前使用默认模型
选择模型报 400:agent_field_not_overridable 选择器携带了不可覆盖的键(闸门已开时仅 modelsystemtoolsmcp_serversskills 可被覆盖) 只在你改过 createTripSession 时发生:移除多余的键
启动画面提示 Missing ROADTRIP_PLANNER_AGENT_ID .env.local 未写入,或 dev server 先于供给启动 运行 npm run setup,重启 npm run dev
事件只按回合结束成批到达 有代理在缓冲 SSE 响应 先在 localhost 上直接用 next dev
回答没有引用任何工具调用 Agent 靠先验知识作答 提示词要求每条声明必须有 API 证据:若你削弱过它,重新 npm run setup -- --force
行程到手但没有评审交接(工具栏无线程事件) 存储的规划者早于评审名单(在多 Agent 变更前供给),或问题太小、命中提示词中 "跳过评审" 的分支 重新 npm run setup -- --force;请求完整的多日行程
npm run setup 创建规划者时因 multiagent 报 400 组织尚未加入附带协调者名单的 Managed Agents 更新 在组织加入前使用单 Agent 副本(删除 setup/create.ts 中的 multiagent 行)
开启 header 注入后每次 NPS 调用都 403 NPS 密钥本身有问题 在你机器上重跑第一步的 curl
session.errorcredential_host_unreachable_error 凭据允许的主机不在环境的网络白名单内 两份 allowed_hosts 列表都必须点名该厂商主机
teardown 后聊天重置成空行程 cookie 指向了已归档会话,于是新建了一条 符合预期:已归档会话不能再接收消息

两条容易忽略的 allowlist 约束

把调试表里两处"必须一致"的约束合起来看,会得到本 cookbook 最核心的一条配置纪律:环境与凭据各有一份 allowed_hosts,二者必须都点名厂商主机README.md 的 Caveats 一节做了精确区分:环境的 networking.allowed_hosts 控制沙箱"能否连到"某个主机;凭据的 networking.allowed_hosts 控制"它的密钥能否在那里被替换"。前者缺了主机则根本连不上,后者缺了主机则请求带着占位符发出。

七、重置:一键归档与重建

测试结束或想从头再来时,skill.md 提供了两条命令:

npm run teardown            # 归档会话、两个 Agent、保险库、凭据与环境
npm run setup -- --force    # 供给一份全新的副本

setup/teardown.ts 的实现看,teardown 是"归档"而非"删除":事件日志在 Console 中仍然可读,六个 ROADTRIP_PLANNER_* id 也会保留在 .env.local 中。执行顺序是:先列出规划者的全部会话并逐一归档,再归档两个 Agent(评审者从不持有自己的会话,它只以规划者会话内的线程运行)、两条凭据、保险库、最后是环境。注意当 cookie 指向归档会话后,再次打开页面会静默新建一条新会话——这正是调试表中最后一行"chat 重置成空行程"的预期行为。

八、源码文件导航

如果你要深入阅读这个示例的实现,README.md 的文件清单是最佳索引:

文件 职责
setup/create.ts 环境 + 规划者 + 评审者 + 保险库 + 两条凭据,幂等,打印并保存 id
setup/teardown.ts 归档 setup 创建的一切
setup/config.ts 主机名单、模型默认值、两个系统提示词
src/lib/client.ts 共享 SDK 客户端与会话 cookie 名
src/lib/use-managed-agent-session.ts 客户端运行时:一条 EventSource、SDK 累加器、send/stop
src/lib/transcript.ts 事件日志折叠为可渲染回合的唯一折叠函数
src/app/api/session/route.ts cookie 背后创建/续用会话,返回事件日志
src/app/api/stream/route.ts 会话流尾的 SSE 代理(API Key 留在服务端)
src/app/api/chat/route.ts 发送一条 user.message
src/app/api/interrupt/route.ts 发送 user.interrupt(停止按钮)
src/app/page.tsx 聊天、模型选择器、工具栏

结语

skill.md 自上而下走完一遍,你会获得一整套可复用的 Agent 应用范式:以会话事件日志作为唯一状态的无状态前端、event_deltas 驱动的逐 token 流式渲染、injection_location 控制的按请求位置密钥注入、agent_with_overrides 实现的按会话模型覆盖,以及用 multiagent 协调者名单完成的 Agent 间评审。每个能力都有对应的 npm run 演示步骤、可观察的界面信号与一行可反转的配置项,这套"供给 → 演示 → 破坏 → 修复 → 重置"的闭环,正是把它当作教学样例的价值所在。

登录后查看全文
热门项目推荐
相关项目推荐