Skip to content

callModel 是 OpenRouter Agent SDK 的核心 API,提供统一接口调用任意 LLM。它基于 Responses API 的 items 模型,支持文本、流式、tool 调用等多种消费模式,内置自动 tool 执行循环,TypeScript 全类型推导。一个调用搞定从简单问答到复杂多轮 agent 工作流的全部场景。

为什么用 callModel?

  • Items 模型:基于 OpenRouter Responses API,输出是结构化 items(消息、tool 调用、推理)而非原始 chunk
  • 多种消费模式:同一次调用,可以取文本、流式输出、结构化数据
  • 自动 tool 执行:用 Zod schema 定义 tool,SDK 自动处理执行循环
  • 类型安全:tool 输入输出、事件全部有 TypeScript 类型推导
  • 格式兼容:可与 OpenAI chat 格式和 Anthropic Claude 格式互转

快速开始

typescript
import { OpenRouter } from '@openrouter/agent';

const openrouter = new OpenRouter({
  apiKey: process.env.OPENROUTER_API_KEY,
});

const result = openrouter.callModel({
  model: 'openai/gpt-5-nano',
  input: 'What is the capital of France?',
});

// 最简单的消费方式:取文本
const text = await result.getText();
console.log(text); // "The capital of France is Paris."

消费模式

callModel 返回一个 ModelResult 对象,提供多种获取响应的方式:

文本方法

typescript
// 只取文本内容
const text = await result.getText();

// 取完整响应(含用量数据)
const response = await result.getResponse();
console.log(response.usage); // { inputTokens, outputTokens, cachedTokens }

流式方法

typescript
// 流式接收文本 delta
for await (const delta of result.getTextStream()) {
  process.stdout.write(delta);
}

// 流式接收推理过程(推理模型专用)
for await (const delta of result.getReasoningStream()) {
  console.log('Reasoning:', delta);
}

// 流式接收完整 items(推荐方式)
for await (const item of result.getItemsStream()) {
  console.log('Item update:', item.type, item.id);
}

// 流式接收所有事件(含 tool 中间结果)
for await (const event of result.getFullResponsesStream()) {
  console.log('Event:', event.type);
}

Tool 方法

typescript
// 获取响应中的所有 tool 调用
const toolCalls = await result.getToolCalls();

// 流式接收 tool 调用
for await (const toolCall of result.getToolCallsStream()) {
  console.log(`Tool: ${toolCall.name}`, toolCall.arguments);
}

// 流式接收 tool delta 和中间结果
for await (const event of result.getToolStream()) {
  if (event.type === 'delta') {
    process.stdout.write(event.content);
  } else if (event.type === 'preliminary_result') {
    console.log('Progress:', event.result);
  }
}

输入格式

callModel 支持多种输入格式:

typescript
// 简单字符串
const result1 = openrouter.callModel({
  model: 'openai/gpt-5-nano',
  input: 'Hello!',
});

// 消息数组(OpenResponses 格式)
const result2 = openrouter.callModel({
  model: 'openai/gpt-5-nano',
  input: [
    { role: 'user', content: 'Hello!' },
  ],
});

// 带 system 指令
const result3 = openrouter.callModel({
  model: 'openai/gpt-5-nano',
  instructions: 'You are a helpful assistant.',
  input: 'Hello!',
});

下一步

常见问题

Q: callModel 返回的 ModelResult 和直接 await 结果有什么区别?

A: callModel 本身是同步的,返回 ModelResult 对象,不发起网络请求。只有调用 .getText().getResponse() 等方法时才触发实际请求。这样设计允许同一个 result 被多个消费者并发消费。

Q: 可以同时用多种消费方式吗(比如边流式边取完整响应)?

A: 可以。底层使用 ReusableReadableStream,支持并发消费者。Promise.all([result.getTextStream(), result.getResponse()]) 这种写法完全没问题。

Q: getItemsStream() 和 getTextStream() 有什么区别?

A: getTextStream() 只输出文本 delta,适合纯文本场景。getItemsStream() 输出结构化 items(含消息、tool 调用、推理等),每次迭代给出同一 item 的最新快照,适合需要处理多种输出类型的场景。