定义智能体仅仅是设置步骤。运行时的问题是单次运行会做什么、下一轮如何继续,以及当工作流因等待审批或工具执行而暂停时的行为方式。
The agent loop
一次 SDK 运行即代表一个应用层面的轮次。运行器 (runner) 会不断循环,直到到达一个真正的停止点:
- 使用准备好的输入调用当前智能体的模型。
- 检查模型输出。
- 如果模型产生了工具调用,则执行它们并继续。
- 如果模型将控制权移交给了另一个专家,则切换智能体并继续。
- 如果模型产生了最终回答且无需更多工具执行,则返回结果。
该循环是 SDK 背后的核心概念。工具、移交、审批和流式传输都构建于其之上,而不是替代它。
选择一种对话策略
将状态带入下一轮有四种常见方式:
| 策略 | 状态存储位置 | 适用场景 | 在下一轮传递的内容 |
|---|---|---|---|
result.history | 您的应用程序 | 简短的对话循环与最大控制权 | The replay-ready history |
session | 您的存储加上 SDK | 持久的对话状态、可恢复的运行以及由您控制的存储 | The same session |
conversationId | OpenAI Conversations API | 跨工作器或服务的共享服务器托管状态 | 相同的对话 ID 且仅包含新的轮次 |
previousResponseId | OpenAI Responses API | 从一次响应到下一次响应的最轻量级服务器托管延续 | 上一次的响应 ID 且仅包含新的轮次 |
在大多数应用中,请为每个对话选择一种策略。除非您刻意协调这两个层面,否则将本地重放与服务器托管状态混合使用可能会导致上下文重复。
通过 sessions 持久化多轮状态
typescript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import { Agent, MemorySession, run } from "@openai/agents";
const agent = new Agent({
name: "Tour guide",
instructions: "Answer with compact travel facts.",
});
const session = new MemorySession();
const firstTurn = await run(
agent,
"What city is the Golden Gate Bridge in?",
{ session },
);
console.log(firstTurn.finalOutput);
const secondTurn = await run(agent, "What state is it in?", { session });
console.log(secondTurn.finalOutput);当您需要持久化内存、可恢复的审批流程或由您的应用程序控制的存储时,sessions 是最佳的默认选择。
使用服务器托管状态继续
typescript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import { Agent, run } from "@openai/agents";
import OpenAI from "openai";
const agent = new Agent({
name: "Assistant",
instructions: "Reply very concisely.",
});
const client = new OpenAI();
const { id: conversationId } = await client.conversations.create({});
const first = await run(agent, "What city is the Golden Gate Bridge in?", {
conversationId,
});
console.log(first.finalOutput);
const second = await run(agent, "What state is it in?", {
conversationId,
});
console.log(second.finalOutput);使用 conversationId 当多个系统需要共享一个命名的对话时。使用 previousResponseId
增量式流式传输运行
流式传输使用相同的智能体循环和相同的状态策略。唯一的区别在于,您会在运行仍在进行时消费事件。
随着文本到达来流式传输运行
typescript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import { Agent, run } from "@openai/agents";
const agent = new Agent({
name: "Planet guide",
instructions: "Answer with short facts.",
});
const stream = await run(agent, "Give me three short facts about Saturn.", {
stream: true,
});
for await (const event of stream) {
if (
event.type === "raw_model_stream_event" &&
event.data.type === "response.output_text.delta"
) {
process.stdout.write(event.data.delta);
}
}
await stream.completed;
console.log("\nFinal:", stream.finalOutput);三个实用规则很重要:
- 在将运行视为稳定之前,请等待流式传输完成。
- 如果运行因等待审批而暂停,请解决
interruptionsand resume fromstate而不是开始一个新的用户轮次。 - 如果您在轮次中途取消了流式传输,请从以下位置恢复未完成的轮次:
state如果您希望同一轮次稍后继续。
妥善处理暂停和失败
两大类非理想路径的结果很重要:
- 运行时或验证失败 例如最大轮次限制、护栏异常或工具错误。
- 预期的暂停 例如人工审批请求,此时运行被有意中断,稍后应从相同状态恢复。
将审批视为已暂停的运行,而不是新的轮次。这种区分可以保持轮次计数、历史记录和服务器托管的延续 ID 的一致性。
后续步骤
一旦明确了运行时循环,就可以转到与您需要设计的下一个工作流边界相匹配的指南。