跳到正文
OpenRouter Blog·· 2026-04-24精选AI 评分70

OpenRouter 发布两个基于 Agent SDK 的 Agent 脚手架 Skill

Build Your Own Harness with the Agent SDK

AI 导读

OpenRouter 发布 create-agent-tui 和 create-headless-agent 两个 Skill,前者生成带终端界面的 Agent,后者生成面向 CLI、API 服务和流水线的无界面 Agent,均基于新推出的 Agent SDK,可搭配 OpenRouter 上任意模型。

推荐理由

OpenRouter 把两个可直接安装的 Skill 和生成项目结构讲清楚,读者能据此搭出自己的 Agent 循环。

正文 · AI 翻译

我们构建了两个技能,用于构建你自己的 agent harness。第一个是create-agent-tui,它搭建了一个完整的终端 UI,外观可自定义——横幅、工具显示样式和输入字段,你可以匹配 Codex 的风格或 Claude Code 的风格。第二个是create-headless-agent,它为 CLI 工具、API 服务器、队列工作器和流水线搭建了一个无头 agent——没有终端 UI,只有结构化的输入/输出。

将 Claude Code、Codex、Cursor 或任何兼容技能的 agent 指向任一技能,描述你想要的内容,它就会生成一个完整、可运行的 TypeScript 项目。两者都运行在最近发布的 Agent SDK 上,并可与 OpenRouter 上的任何模型配合使用。

既然市面上已有许多优秀的商业 harness,为什么还要自己动手?

  • 你想要对界面外观、工具或循环进行细粒度控制
  • 你想要一个可以随产品一起发布的最小化 harness
  • 你想要了解 agent 的工作原理,以便更好地使用和调试它们

Agent TUI input style

现在就开始构建你自己的吧

  1. 如果你还没有,获取一个 OpenRouter API 密钥
  2. Install the skill you want in your coding agent:
    • Agent TUI:gh skill install OpenRouterTeam/skills create-agent-tui
    • 无头 agent:gh skill install OpenRouterTeam/skills create-headless-agent
  3. 告诉你的 agent 为你构建一个编码助手,以及什么会让你的助手与众不同
  4. Run the generated project:
    • Agent TUI:bun install && bun run start
    • 无头 agent:bun install && bun run src/cli.ts -m '~anthropic/claude-opus-latest' -p "What's in this repo?"

该技能在调用时会呈现一个交互式清单。你选择所需内容:服务器工具(网络搜索、日期时间、图像生成)、本地工具(文件读/写/编辑、grep、glob、shell 等)、harness 模块(会话持久化、上下文压缩、工具审批门控)和斜杠命令(/model 用于即时切换模型,/new 用于开启新对话,/export 用于保存为 Markdown)。完成选择后,它会生成完整项目并使用 tsc 验证类型。

终端 UI 的每个部分开箱即可自定义。三种工具显示样式(emoji 标记、分组操作标签或极简单行),三种输入样式(适应终端主题的全宽块、带边框的行或纯 readline),三种加载动画(渐变微光、旋转指示器或尾随点),以及自定义 ASCII 横幅。你也可以直接描述你想要的内容,技能会生成自定义样式。

生成的项目归你所有,可随意修改。添加特定领域的工具,接入不同的入口点(该技能包含 HTTP API 服务器的模板),为长对话附加上下文压缩,或将其精简到最低限度。

两个技能都依赖 Agent SDK 来实现可信的内部循环

两个技能都会生成两层代码。内层是 Agent SDK:一次 callModel 调用即可处理整个 agent 循环(模型调用、工具执行、多轮循环、停止条件、流式传输、成本跟踪)。外层是技能围绕它生成的一切:配置、工具定义、会话管理、入口点,以及——在 TUI 技能的情况下——终端界面。

以下是生成的 src/agent.ts,已精简至核心部分:

import { OpenRouter } from '@openrouter/agent';
import type { Item } from '@openrouter/agent';
import { stepCountIs, maxCost } from '@openrouter/agent';
import { tools } from './tools/index.js';

const client = new OpenRouter({ apiKey: config.apiKey });

const result = client.callModel({
  model: config.model,
  instructions: config.systemPrompt,
  input: userMessage,
  tools,
  stopWhen: [stepCountIs(config.maxSteps), maxCost(config.maxCost)],
});

那一次 callModel 调用就是整个 agent 循环。SDK 调用模型,检查输出中的工具请求,根据你的 Zod schema 验证参数,执行工具,将结果反馈回去,并重复此过程,直到触发停止条件。

该技能在此基础上通过遍历 result.getItemsStream() 来实现流式传输。每个条目都有类型,并携带完整的当前状态:message 条目携带目前为止的完整助手文本,function_call 条目携带工具调用,function_call_output 条目携带结果,reasoning 条目携带模型思考。生成的 src/renderer.ts 将这些转换为带有 token 计数和工具调用摘要的整洁终端显示。

工具位于 src/tools/ 中,每个工具一个文件。每个工具使用 SDK 的 tool() 函数,配合用于输入的 Zod schema 和一个带类型的 execute 函数。服务器工具(网页搜索、日期时间)更简单:serverTool({ type: 'openrouter:web_search' }),OpenRouter 在服务器端执行它们,客户端零代码。

配置通过三层流转:硬编码默认值、可选的 agent.config.json 文件和环境变量。你可以在配置文件中设置首选模型和成本限制,并通过 AGENT_MODEL=openai/gpt-5 npm start 按会话覆盖它们。

会话持久化将每条消息写入 JSONL 文件。下次运行时,harness 可以重新加载对话历史,并将其作为 Item[] 数组传回 callModel,从你上次中断的地方继续。

这些模式来自顶级 harness

该技能借鉴了三种生产级 agent 架构:

  • pi-mono 的编码 agent:三层分离(配置、agent 循环、工具)、JSONL 会话、可插拔的工具操作
  • Claude Code:带有只读和破坏性标志的工具元数据、由静态和动态上下文组成的系统提示词
  • Codex CLI:分层配置(默认值、配置文件、环境变量)、带会话缓存的审批流程

这些模式已融入生成的代码中,但 Agent SDK 才是让整个东西保持紧凑的关键。如果没有 callModel 处理 agent 循环、工具验证、流式传输和成本跟踪,你就得自己编写数百行的循环管理代码。该技能完全专注于应用特定的部分,因为 SDK 处理了其他所有事情。

无头技能遵循相同的架构,但完全去掉了 TUI 层。生成的 CLI 不是 REPL,而是通过 --prompt、位置参数或管道 stdin 接受提示词,并输出纯文本、NDJSON 事件流,或仅输出退出码。

有两个特性在生产使用中尤为突出。429/5xx 安全重试:生成的 runAgentWithRetry 包装器以指数退避重试瞬时 API 错误——但仅在尚未执行任何工具调用时。一旦像 file_write 或 shell 这样的变更型工具运行过,从初始提示词重放 agent 会导致副作用重复执行,因此重试会立即抛出异常。使用 --output-schema 的结构化输出:传入一个 JSON Schema 文件,CLI 会用 Ajv 根据它验证 agent 的最终响应,验证失败时以代码 2 退出。解析器对 markdown 代码围栏具有容错性,因此即使模型将 JSON 包裹在代码块中也能正常工作。

完整的 callModel API 参考,请查看 SDK 文档。详细演练请参阅 Build Your Own Agent TUI 和 Build Your Own Headless Agent 指南。要在 Agent SDK 之上构建自己的技能,请从 skills 仓库开始。

来源:OpenRouter Blog · openrouter.ai