openai-assistants
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseOpenAI Assistants API v2
OpenAI Assistants API v2
Status: Production Ready (Deprecated H1 2026)
Package: openai@6.7.0
Last Updated: 2025-10-25
v1 Deprecated: December 18, 2024
v2 Sunset: H1 2026 (migrate to Responses API)
状态:生产可用(2026年上半年弃用)
包版本:openai@6.7.0
最后更新:2025-10-25
v1 弃用时间:2024年12月18日
v2 停用时间:2026年上半年(迁移至Responses API)
⚠️ Important: Deprecation Notice
⚠️ 重要提醒:弃用通知
OpenAI announced that the Assistants API will be deprecated in favor of the Responses API.
Timeline:
- ✅ Dec 18, 2024: Assistants API v1 deprecated
- ⏳ H1 2026: Planned sunset of Assistants API v2
- ✅ Now: Responses API available (recommended for new projects)
Should you still use this skill?
- ✅ Yes, if: You have existing Assistants API code (12-18 month migration window)
- ✅ Yes, if: You need to maintain legacy applications
- ✅ Yes, if: Planning migration from Assistants → Responses
- ❌ No, if: Starting a new project (use openai-responses skill instead)
Migration Path:
See for complete migration guide.
references/migration-to-responses.mdOpenAI宣布将停用Assistants API,转而使用Responses API。
时间线:
- ✅ 2024年12月18日:Assistants API v1 弃用
- ⏳ 2026年上半年:计划停用Assistants API v2
- ✅ 当前:Responses API 已可用(新项目推荐使用)
是否仍应使用该指南?
- ✅ 是,如果:你已有基于Assistants API的代码(有12-18个月的迁移窗口期)
- ✅ 是,如果:你需要维护遗留应用
- ✅ 是,如果:正在规划从Assistants API迁移至Responses API
- ❌ 否,如果:启动新项目(请改用openai-responses相关指南)
迁移路径:
完整迁移指南请参考 。
references/migration-to-responses.mdTable of Contents
目录
Quick Start
快速开始
Installation
安装
bash
npm install openai@6.7.0bash
npm install openai@6.7.0Environment Setup
环境配置
bash
export OPENAI_API_KEY="sk-..."bash
export OPENAI_API_KEY="sk-..."Basic Assistant (Node.js SDK)
基础助手示例(Node.js SDK)
typescript
import OpenAI from 'openai';
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});
// 1. Create an assistant
const assistant = await openai.beta.assistants.create({
name: "Math Tutor",
instructions: "You are a personal math tutor. Write and run code to answer math questions.",
tools: [{ type: "code_interpreter" }],
model: "gpt-4o",
});
// 2. Create a thread
const thread = await openai.beta.threads.create();
// 3. Add a message to the thread
await openai.beta.threads.messages.create(thread.id, {
role: "user",
content: "I need to solve the equation `3x + 11 = 14`. Can you help me?",
});
// 4. Create a run
const run = await openai.beta.threads.runs.create(thread.id, {
assistant_id: assistant.id,
});
// 5. Poll for completion
let runStatus = await openai.beta.threads.runs.retrieve(thread.id, run.id);
while (runStatus.status !== 'completed') {
await new Promise(resolve => setTimeout(resolve, 1000));
runStatus = await openai.beta.threads.runs.retrieve(thread.id, run.id);
}
// 6. Retrieve messages
const messages = await openai.beta.threads.messages.list(thread.id);
console.log(messages.data[0].content[0].text.value);typescript
import OpenAI from 'openai';
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});
// 1. 创建助手
const assistant = await openai.beta.assistants.create({
name: "数学导师",
instructions: "你是一名私人数学导师。编写并运行代码来解答数学问题。",
tools: [{ type: "code_interpreter" }],
model: "gpt-4o",
});
// 2. 创建线程
const thread = await openai.beta.threads.create();
// 3. 向线程添加消息
await openai.beta.threads.messages.create(thread.id, {
role: "user",
content: "我需要解方程`3x + 11 = 14`。你能帮我吗?",
});
// 4. 创建运行
const run = await openai.beta.threads.runs.create(thread.id, {
assistant_id: assistant.id,
});
// 5. 轮询等待完成
let runStatus = await openai.beta.threads.runs.retrieve(thread.id, run.id);
while (runStatus.status !== 'completed') {
await new Promise(resolve => setTimeout(resolve, 1000));
runStatus = await openai.beta.threads.runs.retrieve(thread.id, run.id);
}
// 6. 获取消息
const messages = await openai.beta.threads.messages.list(thread.id);
console.log(messages.data[0].content[0].text.value);Basic Assistant (Fetch - Cloudflare Workers)
基础助手示例(Fetch - Cloudflare Workers)
typescript
// 1. Create assistant
const assistant = await fetch('https://api.openai.com/v1/assistants', {
method: 'POST',
headers: {
'Authorization': `Bearer ${env.OPENAI_API_KEY}`,
'Content-Type': 'application/json',
'OpenAI-Beta': 'assistants=v2',
},
body: JSON.stringify({
name: "Math Tutor",
instructions: "You are a helpful math tutor.",
model: "gpt-4o",
}),
});
const assistantData = await assistant.json();
// 2. Create thread
const thread = await fetch('https://api.openai.com/v1/threads', {
method: 'POST',
headers: {
'Authorization': `Bearer ${env.OPENAI_API_KEY}`,
'Content-Type': 'application/json',
'OpenAI-Beta': 'assistants=v2',
},
});
const threadData = await thread.json();
// 3. Add message and create run
const run = await fetch(`https://api.openai.com/v1/threads/${threadData.id}/runs`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${env.OPENAI_API_KEY}`,
'Content-Type': 'application/json',
'OpenAI-Beta': 'assistants=v2',
},
body: JSON.stringify({
assistant_id: assistantData.id,
additional_messages: [{
role: "user",
content: "What is 3x + 11 = 14?",
}],
}),
});
// Poll for completion...typescript
// 1. 创建助手
const assistant = await fetch('https://api.openai.com/v1/assistants', {
method: 'POST',
headers: {
'Authorization': `Bearer ${env.OPENAI_API_KEY}`,
'Content-Type': 'application/json',
'OpenAI-Beta': 'assistants=v2',
},
body: JSON.stringify({
name: "数学导师",
instructions: "你是一名乐于助人的数学导师。",
model: "gpt-4o",
}),
});
const assistantData = await assistant.json();
// 2. 创建线程
const thread = await fetch('https://api.openai.com/v1/threads', {
method: 'POST',
headers: {
'Authorization': `Bearer ${env.OPENAI_API_KEY}`,
'Content-Type': 'application/json',
'OpenAI-Beta': 'assistants=v2',
},
});
const threadData = await thread.json();
// 3. 添加消息并创建运行
const run = await fetch(`https://api.openai.com/v1/threads/${threadData.id}/runs`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${env.OPENAI_API_KEY}`,
'Content-Type': 'application/json',
'OpenAI-Beta': 'assistants=v2',
},
body: JSON.stringify({
assistant_id: assistantData.id,
additional_messages: [{
role: "user",
content: "3x + 11 = 14的解是什么?",
}],
}),
});
// 轮询等待完成...Core Concepts
核心概念
The Assistants API uses four main objects:
Assistants API 使用四个核心对象:
1. Assistants
1. 助手(Assistants)
Configured AI entities with:
- Instructions (system prompt, max 256k characters)
- Model (gpt-4o, gpt-5, etc.)
- Tools (Code Interpreter, File Search, Functions)
- File attachments
- Metadata
已配置的AI实体,包含:
- 指令(系统提示词,最多256k字符)
- 模型(gpt-4o、gpt-5等)
- 工具(代码解释器、文件搜索、函数)
- 文件附件
- 元数据
2. Threads
2. 线程(Threads)
Conversation containers that:
- Store message history
- Persist across runs
- Can have metadata
- Support up to 100,000 messages
对话容器,具备:
- 存储消息历史
- 跨运行会话持久化
- 可添加元数据
- 支持最多100,000条消息
3. Messages
3. 消息(Messages)
Individual messages in a thread:
- User messages (input)
- Assistant messages (output)
- Can include file attachments
- Support text and image content
线程中的单个消息:
- 用户消息(输入)
- 助手消息(输出)
- 可包含文件附件
- 支持文本和图片内容
4. Runs
4. 运行(Runs)
Execution of an assistant on a thread:
- Asynchronous processing
- Multiple states (queued, in_progress, completed, failed, etc.)
- Can stream results
- Handle tool calls automatically
助手在线程上的执行实例:
- 异步处理
- 多种状态(排队中、执行中、已完成、失败等)
- 可流式返回结果
- 自动处理工具调用
Assistants
助手(Assistants)
Create an Assistant
创建助手
typescript
const assistant = await openai.beta.assistants.create({
name: "Data Analyst",
instructions: "You are a data analyst. Use code interpreter to analyze data and create visualizations.",
model: "gpt-4o",
tools: [
{ type: "code_interpreter" },
{ type: "file_search" },
],
tool_resources: {
file_search: {
vector_store_ids: ["vs_abc123"],
},
},
metadata: {
department: "analytics",
version: "1.0",
},
});Parameters:
- (required): Model ID (gpt-4o, gpt-5, gpt-4-turbo)
model - : System prompt (max 256k characters in v2, was 32k in v1)
instructions - : Assistant name (max 256 characters)
name - : Description (max 512 characters)
description - : Array of tools (max 128 tools)
tools - : Resources for tools (vector stores, files)
tool_resources - : 0-2 (default 1)
temperature - : 0-1 (default 1)
top_p - : "auto", "json_object", or JSON schema
response_format - : Key-value pairs (max 16 pairs)
metadata
typescript
const assistant = await openai.beta.assistants.create({
name: "数据分析师",
instructions: "你是一名数据分析师。使用代码解释器分析数据并创建可视化图表。",
model: "gpt-4o",
tools: [
{ type: "code_interpreter" },
{ type: "file_search" },
],
tool_resources: {
file_search: {
vector_store_ids: ["vs_abc123"],
},
},
metadata: {
department: "analytics",
version: "1.0",
},
});参数说明:
- (必填):模型ID(gpt-4o、gpt-5、gpt-4-turbo等)
model - :系统提示词(v2版本最多256k字符,v1版本为32k字符)
instructions - :助手名称(最多256字符)
name - :助手描述(最多512字符)
description - :工具数组(最多128个工具)
tools - :工具所需资源(向量存储、文件)
tool_resources - :0-2(默认值为1)
temperature - :0-1(默认值为1)
top_p - :"auto"、"json_object"或JSON schema
response_format - :键值对(最多16对)
metadata
Retrieve an Assistant
获取助手信息
typescript
const assistant = await openai.beta.assistants.retrieve("asst_abc123");typescript
const assistant = await openai.beta.assistants.retrieve("asst_abc123");Update an Assistant
更新助手
typescript
const updatedAssistant = await openai.beta.assistants.update("asst_abc123", {
instructions: "Updated instructions",
tools: [{ type: "code_interpreter" }, { type: "file_search" }],
});typescript
const updatedAssistant = await openai.beta.assistants.update("asst_abc123", {
instructions: "更新后的指令",
tools: [{ type: "code_interpreter" }, { type: "file_search" }],
});Delete an Assistant
删除助手
typescript
await openai.beta.assistants.del("asst_abc123");typescript
await openai.beta.assistants.del("asst_abc123");List Assistants
列出所有助手
typescript
const assistants = await openai.beta.assistants.list({
limit: 20,
order: "desc",
});typescript
const assistants = await openai.beta.assistants.list({
limit: 20,
order: "desc",
});Threads
线程(Threads)
Threads store conversation history and persist across runs.
线程用于存储对话历史,并在多次运行之间保持持久化。
Create a Thread
创建线程
typescript
// Empty thread
const thread = await openai.beta.threads.create();
// Thread with initial messages
const thread = await openai.beta.threads.create({
messages: [
{
role: "user",
content: "Hello! I need help with Python.",
metadata: { source: "web" },
},
],
metadata: {
user_id: "user_123",
session_id: "session_456",
},
});typescript
// 空线程
const thread = await openai.beta.threads.create();
// 包含初始消息的线程
const thread = await openai.beta.threads.create({
messages: [
{
role: "user",
content: "你好!我需要Python相关的帮助。",
metadata: { source: "web" },
},
],
metadata: {
user_id: "user_123",
session_id: "session_456",
},
});Retrieve a Thread
获取线程信息
typescript
const thread = await openai.beta.threads.retrieve("thread_abc123");typescript
const thread = await openai.beta.threads.retrieve("thread_abc123");Update Thread Metadata
更新线程元数据
typescript
const thread = await openai.beta.threads.update("thread_abc123", {
metadata: {
user_id: "user_123",
last_active: new Date().toISOString(),
},
});typescript
const thread = await openai.beta.threads.update("thread_abc123", {
metadata: {
user_id: "user_123",
last_active: new Date().toISOString(),
},
});Delete a Thread
删除线程
typescript
await openai.beta.threads.del("thread_abc123");⚠️ Warning: Deleting a thread also deletes all messages and runs. Cannot be undone.
typescript
await openai.beta.threads.del("thread_abc123");⚠️ 警告:删除线程会同时删除所有相关消息和运行,且该操作不可撤销。
Messages
消息(Messages)
Add a Message to a Thread
向线程添加消息
typescript
const message = await openai.beta.threads.messages.create("thread_abc123", {
role: "user",
content: "Can you analyze this data?",
attachments: [
{
file_id: "file_abc123",
tools: [{ type: "code_interpreter" }],
},
],
metadata: {
timestamp: new Date().toISOString(),
},
});Parameters:
- : "user" only (assistant messages created by runs)
role - : Text or array of content blocks
content - : Files with associated tools
attachments - : Key-value pairs
metadata
typescript
const message = await openai.beta.threads.messages.create("thread_abc123", {
role: "user",
content: "你能分析这份数据吗?",
attachments: [
{
file_id: "file_abc123",
tools: [{ type: "code_interpreter" }],
},
],
metadata: {
timestamp: new Date().toISOString(),
},
});参数说明:
- :仅支持"user"(助手消息由运行自动生成)
role - :文本或内容块数组
content - :关联工具的文件
attachments - :键值对
metadata
Retrieve a Message
获取消息信息
typescript
const message = await openai.beta.threads.messages.retrieve(
"thread_abc123",
"msg_abc123"
);typescript
const message = await openai.beta.threads.messages.retrieve(
"thread_abc123",
"msg_abc123"
);List Messages
列出所有消息
typescript
const messages = await openai.beta.threads.messages.list("thread_abc123", {
limit: 20,
order: "desc", // "asc" or "desc"
});
// Iterate through messages
for (const message of messages.data) {
console.log(`${message.role}: ${message.content[0].text.value}`);
}typescript
const messages = await openai.beta.threads.messages.list("thread_abc123", {
limit: 20,
order: "desc", // "asc" 或 "desc"
});
// 遍历消息
for (const message of messages.data) {
console.log(`${message.role}: ${message.content[0].text.value}`);
}Update Message Metadata
更新消息元数据
typescript
const message = await openai.beta.threads.messages.update(
"thread_abc123",
"msg_abc123",
{
metadata: {
edited: "true",
edit_timestamp: new Date().toISOString(),
},
}
);typescript
const message = await openai.beta.threads.messages.update(
"thread_abc123",
"msg_abc123",
{
metadata: {
edited: "true",
edit_timestamp: new Date().toISOString(),
},
}
);Delete a Message
删除消息
typescript
await openai.beta.threads.messages.del("thread_abc123", "msg_abc123");typescript
await openai.beta.threads.messages.del("thread_abc123", "msg_abc123");Runs
运行(Runs)
Runs execute an assistant on a thread.
运行代表助手在线程上的一次执行过程。
Create a Run
创建运行
typescript
const run = await openai.beta.threads.runs.create("thread_abc123", {
assistant_id: "asst_abc123",
instructions: "Please address the user as Jane Doe.",
additional_messages: [
{
role: "user",
content: "Can you help me with this?",
},
],
});Parameters:
- (required): Assistant to use
assistant_id - : Override assistant instructions
instructions - : Add messages before running
additional_messages - : Override assistant tools
tools - : Key-value pairs
metadata - : Override temperature
temperature - : Override top_p
top_p - : Limit input tokens
max_prompt_tokens - : Limit output tokens
max_completion_tokens
typescript
const run = await openai.beta.threads.runs.create("thread_abc123", {
assistant_id: "asst_abc123",
instructions: "请称呼用户为Jane Doe。",
additional_messages: [
{
role: "user",
content: "你能帮我处理这个问题吗?",
},
],
});参数说明:
- (必填):要使用的助手ID
assistant_id - :覆盖助手原有指令
instructions - :运行前添加的消息
additional_messages - :覆盖助手原有工具
tools - :键值对
metadata - :覆盖温度参数
temperature - :覆盖top_p参数
top_p - :限制输入令牌数
max_prompt_tokens - :限制输出令牌数
max_completion_tokens
Retrieve a Run
获取运行信息
typescript
const run = await openai.beta.threads.runs.retrieve(
"thread_abc123",
"run_abc123"
);
console.log(run.status); // queued, in_progress, requires_action, completed, failed, etc.typescript
const run = await openai.beta.threads.runs.retrieve(
"thread_abc123",
"run_abc123"
);
console.log(run.status); // queued、in_progress、requires_action、completed、failed等Run States
运行状态
| State | Description |
|---|---|
| Run is waiting to start |
| Run is executing |
| Function calling needs your input |
| Cancellation in progress |
| Run was cancelled |
| Run failed (check |
| Run finished successfully |
| Run expired (max 10 minutes) |
| 状态 | 描述 |
|---|---|
| 运行等待启动 |
| 运行正在执行 |
| 需要用户输入以完成函数调用 |
| 正在取消运行 |
| 运行已取消 |
| 运行失败(查看 |
| 运行成功完成 |
| 运行已过期(最长10分钟) |
Polling Pattern
轮询模式
typescript
async function pollRunCompletion(threadId: string, runId: string) {
let run = await openai.beta.threads.runs.retrieve(threadId, runId);
while (['queued', 'in_progress', 'cancelling'].includes(run.status)) {
await new Promise(resolve => setTimeout(resolve, 1000)); // Wait 1 second
run = await openai.beta.threads.runs.retrieve(threadId, runId);
}
if (run.status === 'failed') {
throw new Error(`Run failed: ${run.last_error?.message}`);
}
if (run.status === 'requires_action') {
// Handle function calling (see Function Calling section)
return run;
}
return run; // completed
}
const run = await openai.beta.threads.runs.create(threadId, { assistant_id: assistantId });
const completedRun = await pollRunCompletion(threadId, run.id);typescript
async function pollRunCompletion(threadId: string, runId: string) {
let run = await openai.beta.threads.runs.retrieve(threadId, runId);
while (['queued', 'in_progress', 'cancelling'].includes(run.status)) {
await new Promise(resolve => setTimeout(resolve, 1000)); // 等待1秒
run = await openai.beta.threads.runs.retrieve(threadId, runId);
}
if (run.status === 'failed') {
throw new Error(`运行失败:${run.last_error?.message}`);
}
if (run.status === 'requires_action') {
// 处理函数调用(查看函数调用章节)
return run;
}
return run; // 已完成
}
const run = await openai.beta.threads.runs.create(threadId, { assistant_id: assistantId });
const completedRun = await pollRunCompletion(threadId, run.id);Cancel a Run
取消运行
typescript
const run = await openai.beta.threads.runs.cancel("thread_abc123", "run_abc123");⚠️ Important: Cancellation is asynchronous. Check becomes .
statuscancelledtypescript
const run = await openai.beta.threads.runs.cancel("thread_abc123", "run_abc123");⚠️ 重要提示:取消操作是异步的,请确认变为。
statuscancelledList Runs
列出所有运行
typescript
const runs = await openai.beta.threads.runs.list("thread_abc123", {
limit: 10,
order: "desc",
});typescript
const runs = await openai.beta.threads.runs.list("thread_abc123", {
limit: 10,
order: "desc",
});Streaming Runs
流式运行
Stream run events in real-time using Server-Sent Events (SSE).
使用Server-Sent Events(SSE)实时流式获取运行事件。
Basic Streaming
基础流式示例
typescript
const stream = await openai.beta.threads.runs.stream("thread_abc123", {
assistant_id: "asst_abc123",
});
for await (const event of stream) {
if (event.event === 'thread.message.delta') {
const delta = event.data.delta.content?.[0]?.text?.value;
if (delta) {
process.stdout.write(delta);
}
}
}typescript
const stream = await openai.beta.threads.runs.stream("thread_abc123", {
assistant_id: "asst_abc123",
});
for await (const event of stream) {
if (event.event === 'thread.message.delta') {
const delta = event.data.delta.content?.[0]?.text?.value;
if (delta) {
process.stdout.write(delta);
}
}
}Stream Event Types
流式事件类型
| Event | Description |
|---|---|
| Run was created |
| Run started |
| Step created (tool call, message creation) |
| Step progress update |
| Message created |
| Message content streaming |
| Message finished |
| Run finished |
| Run failed |
| Function calling needed |
| 事件 | 描述 |
|---|---|
| 运行已创建 |
| 运行已启动 |
| 步骤已创建(工具调用、消息生成) |
| 步骤进度更新 |
| 消息已创建 |
| 消息内容流式返回 |
| 消息生成完成 |
| 运行完成 |
| 运行失败 |
| 需要进行函数调用 |
Complete Streaming Example
完整流式示例
typescript
async function streamAssistantResponse(threadId: string, assistantId: string) {
const stream = await openai.beta.threads.runs.stream(threadId, {
assistant_id: assistantId,
});
for await (const event of stream) {
switch (event.event) {
case 'thread.run.created':
console.log('\\nRun started...');
break;
case 'thread.message.delta':
const delta = event.data.delta.content?.[0];
if (delta?.type === 'text' && delta.text?.value) {
process.stdout.write(delta.text.value);
}
break;
case 'thread.run.step.delta':
const toolCall = event.data.delta.step_details;
if (toolCall?.type === 'tool_calls') {
const codeInterpreter = toolCall.tool_calls?.[0]?.code_interpreter;
if (codeInterpreter?.input) {
console.log('\\nExecuting code:', codeInterpreter.input);
}
}
break;
case 'thread.run.completed':
console.log('\\n\\nRun completed!');
break;
case 'thread.run.failed':
console.error('\\nRun failed:', event.data.last_error);
break;
case 'thread.run.requires_action':
// Handle function calling
console.log('\\nFunction calling required');
break;
}
}
}typescript
async function streamAssistantResponse(threadId: string, assistantId: string) {
const stream = await openai.beta.threads.runs.stream(threadId, {
assistant_id: assistantId,
});
for await (const event of stream) {
switch (event.event) {
case 'thread.run.created':
console.log('\n运行已启动...');
break;
case 'thread.message.delta':
const delta = event.data.delta.content?.[0];
if (delta?.type === 'text' && delta.text?.value) {
process.stdout.write(delta.text.value);
}
break;
case 'thread.run.step.delta':
const toolCall = event.data.delta.step_details;
if (toolCall?.type === 'tool_calls') {
const codeInterpreter = toolCall.tool_calls?.[0]?.code_interpreter;
if (codeInterpreter?.input) {
console.log('\n正在执行代码:', codeInterpreter.input);
}
}
break;
case 'thread.run.completed':
console.log('\n\n运行完成!');
break;
case 'thread.run.failed':
console.error('\n运行失败:', event.data.last_error);
break;
case 'thread.run.requires_action':
// 处理函数调用
console.log('\n需要进行函数调用');
break;
}
}
}Tools
工具
Assistants API supports three types of tools:
Assistants API 支持三种类型的工具:
Code Interpreter
代码解释器(Code Interpreter)
Executes Python code in a sandboxed environment.
Capabilities:
- Run Python code
- Generate charts/graphs
- Process files (CSV, JSON, text, images, etc.)
- Return file outputs (images, data files)
- Install packages (limited set available)
Example:
typescript
const assistant = await openai.beta.assistants.create({
name: "Data Analyst",
instructions: "You are a data analyst. Use Python to analyze data and create visualizations.",
model: "gpt-4o",
tools: [{ type: "code_interpreter" }],
});
// Upload a file
const file = await openai.files.create({
file: fs.createReadStream("sales_data.csv"),
purpose: "assistants",
});
// Create thread with file
const thread = await openai.beta.threads.create({
messages: [{
role: "user",
content: "Analyze this sales data and create a visualization.",
attachments: [{
file_id: file.id,
tools: [{ type: "code_interpreter" }],
}],
}],
});
// Run
const run = await openai.beta.threads.runs.create(thread.id, {
assistant_id: assistant.id,
});
// Poll for completion and retrieve outputsOutput Files:
Code Interpreter can generate files (images, CSVs, etc.). Access them via:
typescript
const messages = await openai.beta.threads.messages.list(thread.id);
const message = messages.data[0];
for (const content of message.content) {
if (content.type === 'image_file') {
const fileId = content.image_file.file_id;
const fileContent = await openai.files.content(fileId);
// Save or process file
}
}在沙箱环境中执行Python代码。
功能:
- 运行Python代码
- 生成图表/图形
- 处理文件(CSV、JSON、文本、图片等)
- 返回文件输出(图片、数据文件)
- 安装包(支持有限的包集合)
示例:
typescript
const assistant = await openai.beta.assistants.create({
name: "数据分析师",
instructions: "你是一名数据分析师。使用Python分析数据并创建可视化图表。",
model: "gpt-4o",
tools: [{ type: "code_interpreter" }],
});
// 上传文件
const file = await openai.files.create({
file: fs.createReadStream("sales_data.csv"),
purpose: "assistants",
});
// 创建包含文件的线程
const thread = await openai.beta.threads.create({
messages: [{
role: "user",
content: "分析这份销售数据并创建可视化图表。",
attachments: [{
file_id: file.id,
tools: [{ type: "code_interpreter" }],
}],
}],
});
// 创建运行
const run = await openai.beta.threads.runs.create(thread.id, {
assistant_id: assistant.id,
});
// 轮询等待完成并获取输出输出文件:
代码解释器可以生成文件(图片、CSV等)。通过以下方式访问:
typescript
const messages = await openai.beta.threads.messages.list(thread.id);
const message = messages.data[0];
for (const content of message.content) {
if (content.type === 'image_file') {
const fileId = content.image_file.file_id;
const fileContent = await openai.files.content(fileId);
// 保存或处理文件
}
}File Search
文件搜索(File Search)
Semantic search over uploaded documents using vector stores.
Key Features:
- Up to 10,000 files per assistant (500x more than v1)
- Automatic chunking and embedding
- Vector + keyword search
- Parallel queries with multi-threading
- Advanced reranking
Pricing:
- $0.10/GB/day for vector storage
- First 1GB free
Example:
typescript
// 1. Create vector store
const vectorStore = await openai.beta.vectorStores.create({
name: "Product Documentation",
metadata: { category: "docs" },
});
// 2. Upload files to vector store
const file = await openai.files.create({
file: fs.createReadStream("product_guide.pdf"),
purpose: "assistants",
});
await openai.beta.vectorStores.files.create(vectorStore.id, {
file_id: file.id,
});
// 3. Create assistant with file search
const assistant = await openai.beta.assistants.create({
name: "Product Support",
instructions: "Use file search to answer questions about our products.",
model: "gpt-4o",
tools: [{ type: "file_search" }],
tool_resources: {
file_search: {
vector_store_ids: [vectorStore.id],
},
},
});
// 4. Create thread and run
const thread = await openai.beta.threads.create({
messages: [{
role: "user",
content: "How do I install the product?",
}],
});
const run = await openai.beta.threads.runs.create(thread.id, {
assistant_id: assistant.id,
});Best Practices:
- Wait for vector store status to be before using
completed - Use metadata for filtering (coming soon)
- Chunk large documents appropriately
- Monitor storage costs
使用向量存储对上传的文档进行语义搜索。
核心特性:
- 每个助手最多支持10,000个文件(比v1版本多500倍)
- 自动分块和嵌入
- 向量+关键词混合搜索
- 多线程并行查询
- 高级重排序
定价:
- 向量存储:$0.10/GB/天
- 前1GB免费
示例:
typescript
// 1. 创建向量存储
const vectorStore = await openai.beta.vectorStores.create({
name: "产品文档",
metadata: { category: "docs" },
});
// 2. 向向量存储上传文件
const file = await openai.files.create({
file: fs.createReadStream("product_guide.pdf"),
purpose: "assistants",
});
await openai.beta.vectorStores.files.create(vectorStore.id, {
file_id: file.id,
});
// 3. 创建具备文件搜索功能的助手
const assistant = await openai.beta.assistants.create({
name: "产品支持助手",
instructions: "使用文件搜索回答用户关于产品的问题。",
model: "gpt-4o",
tools: [{ type: "file_search" }],
tool_resources: {
file_search: {
vector_store_ids: [vectorStore.id],
},
},
});
// 4. 创建线程并运行
const thread = await openai.beta.threads.create({
messages: [{
role: "user",
content: "我该如何安装这个产品?",
}],
});
const run = await openai.beta.threads.runs.create(thread.id, {
assistant_id: assistant.id,
});最佳实践:
- 等待向量存储状态变为后再使用
completed - 使用元数据进行过滤(即将推出)
- 合理拆分大型文档
- 监控存储成本
Function Calling
函数调用(Function Calling)
Define custom functions for the assistant to call.
Example:
typescript
const assistant = await openai.beta.assistants.create({
name: "Weather Assistant",
instructions: "You help users get weather information.",
model: "gpt-4o",
tools: [{
type: "function",
function: {
name: "get_weather",
description: "Get the current weather for a location",
parameters: {
type: "object",
properties: {
location: {
type: "string",
description: "City name, e.g., 'San Francisco'",
},
unit: {
type: "string",
enum: ["celsius", "fahrenheit"],
description: "Temperature unit",
},
},
required: ["location"],
},
},
}],
});
// Create thread and run
const thread = await openai.beta.threads.create({
messages: [{
role: "user",
content: "What's the weather in San Francisco?",
}],
});
let run = await openai.beta.threads.runs.create(thread.id, {
assistant_id: assistant.id,
});
// Poll until requires_action
while (run.status === 'in_progress' || run.status === 'queued') {
await new Promise(resolve => setTimeout(resolve, 1000));
run = await openai.beta.threads.runs.retrieve(thread.id, run.id);
}
if (run.status === 'requires_action') {
const toolCalls = run.required_action.submit_tool_outputs.tool_calls;
const toolOutputs = [];
for (const toolCall of toolCalls) {
if (toolCall.function.name === 'get_weather') {
const args = JSON.parse(toolCall.function.arguments);
// Call your actual weather API
const weather = await getWeatherAPI(args.location, args.unit);
toolOutputs.push({
tool_call_id: toolCall.id,
output: JSON.stringify(weather),
});
}
}
// Submit tool outputs
run = await openai.beta.threads.runs.submitToolOutputs(thread.id, run.id, {
tool_outputs: toolOutputs,
});
// Continue polling...
}定义自定义函数供助手调用。
示例:
typescript
const assistant = await openai.beta.assistants.create({
name: "天气助手",
instructions: "你帮助用户获取天气信息。",
model: "gpt-4o",
tools: [{
type: "function",
function: {
name: "get_weather",
description: "获取指定地点的当前天气",
parameters: {
type: "object",
properties: {
location: {
type: "string",
description: "城市名称,例如'San Francisco'",
},
unit: {
type: "string",
enum: ["celsius", "fahrenheit"],
description: "温度单位",
},
},
required: ["location"],
},
},
}],
});
// 创建线程并运行
const thread = await openai.beta.threads.create({
messages: [{
role: "user",
content: "旧金山的天气怎么样?",
}],
});
let run = await openai.beta.threads.runs.create(thread.id, {
assistant_id: assistant.id,
});
// 轮询直到状态变为requires_action
while (run.status === 'in_progress' || run.status === 'queued') {
await new Promise(resolve => setTimeout(resolve, 1000));
run = await openai.beta.threads.runs.retrieve(thread.id, run.id);
}
if (run.status === 'requires_action') {
const toolCalls = run.required_action.submit_tool_outputs.tool_calls;
const toolOutputs = [];
for (const toolCall of toolCalls) {
if (toolCall.function.name === 'get_weather') {
const args = JSON.parse(toolCall.function.arguments);
// 调用实际的天气API
const weather = await getWeatherAPI(args.location, args.unit);
toolOutputs.push({
tool_call_id: toolCall.id,
output: JSON.stringify(weather),
});
}
}
// 提交工具输出
run = await openai.beta.threads.runs.submitToolOutputs(thread.id, run.id, {
tool_outputs: toolOutputs,
});
// 继续轮询...
}Vector Stores
向量存储(Vector Stores)
Vector stores enable efficient semantic search over large document collections.
向量存储支持对大型文档集合进行高效的语义搜索。
Create a Vector Store
创建向量存储
typescript
const vectorStore = await openai.beta.vectorStores.create({
name: "Legal Documents",
metadata: {
department: "legal",
category: "contracts",
},
expires_after: {
anchor: "last_active_at",
days: 7, // Auto-delete 7 days after last use
},
});typescript
const vectorStore = await openai.beta.vectorStores.create({
name: "法律文档",
metadata: {
department: "legal",
category: "contracts",
},
expires_after: {
anchor: "last_active_at",
days: 7, // 最后一次使用后7天自动删除
},
});Add Files to Vector Store
向向量存储添加文件
Single File:
typescript
const file = await openai.files.create({
file: fs.createReadStream("contract.pdf"),
purpose: "assistants",
});
await openai.beta.vectorStores.files.create(vectorStore.id, {
file_id: file.id,
});Batch Upload:
typescript
const fileBatch = await openai.beta.vectorStores.fileBatches.create(vectorStore.id, {
file_ids: ["file_abc123", "file_def456", "file_ghi789"],
});
// Poll for batch completion
let batch = await openai.beta.vectorStores.fileBatches.retrieve(vectorStore.id, fileBatch.id);
while (batch.status === 'in_progress') {
await new Promise(resolve => setTimeout(resolve, 1000));
batch = await openai.beta.vectorStores.fileBatches.retrieve(vectorStore.id, fileBatch.id);
}单个文件:
typescript
const file = await openai.files.create({
file: fs.createReadStream("contract.pdf"),
purpose: "assistants",
});
await openai.beta.vectorStores.files.create(vectorStore.id, {
file_id: file.id,
});批量上传:
typescript
const fileBatch = await openai.beta.vectorStores.fileBatches.create(vectorStore.id, {
file_ids: ["file_abc123", "file_def456", "file_ghi789"],
});
// 轮询等待批量上传完成
let batch = await openai.beta.vectorStores.fileBatches.retrieve(vectorStore.id, fileBatch.id);
while (batch.status === 'in_progress') {
await new Promise(resolve => setTimeout(resolve, 1000));
batch = await openai.beta.vectorStores.fileBatches.retrieve(vectorStore.id, fileBatch.id);
}Check Vector Store Status
检查向量存储状态
typescript
const vectorStore = await openai.beta.vectorStores.retrieve("vs_abc123");
console.log(vectorStore.status); // "in_progress", "completed", "failed"
console.log(vectorStore.file_counts); // { in_progress: 0, completed: 50, failed: 0 }⚠️ Important: Wait for before using with file search.
status: "completed"typescript
const vectorStore = await openai.beta.vectorStores.retrieve("vs_abc123");
console.log(vectorStore.status); // "in_progress"、"completed"、"failed"
console.log(vectorStore.file_counts); // { in_progress: 0, completed: 50, failed: 0 }⚠️ 重要提示:等待状态变为后再用于文件搜索。
status: "completed"List Vector Stores
列出所有向量存储
typescript
const stores = await openai.beta.vectorStores.list({
limit: 20,
order: "desc",
});typescript
const stores = await openai.beta.vectorStores.list({
limit: 20,
order: "desc",
});Update Vector Store
更新向量存储
typescript
const vectorStore = await openai.beta.vectorStores.update("vs_abc123", {
name: "Updated Name",
metadata: { updated: "true" },
});typescript
const vectorStore = await openai.beta.vectorStores.update("vs_abc123", {
name: "更新后的名称",
metadata: { updated: "true" },
});Delete Vector Store
删除向量存储
typescript
await openai.beta.vectorStores.del("vs_abc123");typescript
await openai.beta.vectorStores.del("vs_abc123");File Uploads
文件上传
Upload files for use with Code Interpreter or File Search.
上传文件供代码解释器或文件搜索使用。
Upload a File
上传文件
typescript
import fs from 'fs';
const file = await openai.files.create({
file: fs.createReadStream("document.pdf"),
purpose: "assistants",
});
console.log(file.id); // file_abc123Supported Formats:
- Code Interpreter: .c, .cpp, .csv, .docx, .html, .java, .json, .md, .pdf, .php, .pptx, .py, .rb, .tex, .txt, .css, .jpeg, .jpg, .js, .gif, .png, .tar, .ts, .xlsx, .xml, .zip
- File Search: .c, .cpp, .docx, .html, .java, .json, .md, .pdf, .php, .pptx, .py, .rb, .tex, .txt, .css, .js, .ts, .go
Size Limits:
- Code Interpreter: 512 MB per file
- File Search: 512 MB per file
- Vector Store: Up to 10,000 files
typescript
import fs from 'fs';
const file = await openai.files.create({
file: fs.createReadStream("document.pdf"),
purpose: "assistants",
});
console.log(file.id); // file_abc123支持的格式:
- 代码解释器:.c、.cpp、.csv、.docx、.html、.java、.json、.md、.pdf、.php、.pptx、.py、.rb、.tex、.txt、.css、.jpeg、.jpg、.js、.gif、.png、.tar、.ts、.xlsx、.xml、.zip
- 文件搜索:.c、.cpp、.docx、.html、.java、.json、.md、.pdf、.php、.pptx、.py、.rb、.tex、.txt、.css、.js、.ts、.go
大小限制:
- 代码解释器:每个文件最大512 MB
- 文件搜索:每个文件最大512 MB
- 向量存储:最多10,000个文件
Retrieve File Info
获取文件信息
typescript
const file = await openai.files.retrieve("file_abc123");typescript
const file = await openai.files.retrieve("file_abc123");Download File Content
下载文件内容
typescript
const content = await openai.files.content("file_abc123");
// Returns binary contenttypescript
const content = await openai.files.content("file_abc123");
// 返回二进制内容Delete a File
删除文件
typescript
await openai.files.del("file_abc123");typescript
await openai.files.del("file_abc123");List Files
列出所有文件
typescript
const files = await openai.files.list({
purpose: "assistants",
});typescript
const files = await openai.files.list({
purpose: "assistants",
});Thread Lifecycle Management
线程生命周期管理
Proper thread lifecycle management prevents common errors.
合理的线程生命周期管理可避免常见错误。
Pattern 1: One Thread Per User
模式1:每个用户对应一个线程
typescript
async function getOrCreateUserThread(userId: string): Promise<string> {
// Check if thread exists in your database
let threadId = await db.getThreadIdForUser(userId);
if (!threadId) {
// Create new thread
const thread = await openai.beta.threads.create({
metadata: { user_id: userId },
});
threadId = thread.id;
await db.saveThreadIdForUser(userId, threadId);
}
return threadId;
}typescript
async function getOrCreateUserThread(userId: string): Promise<string> {
// 检查数据库中是否存在线程
let threadId = await db.getThreadIdForUser(userId);
if (!threadId) {
// 创建新线程
const thread = await openai.beta.threads.create({
metadata: { user_id: userId },
});
threadId = thread.id;
await db.saveThreadIdForUser(userId, threadId);
}
return threadId;
}Pattern 2: Active Run Check
模式2:检查活跃运行
typescript
async function ensureNoActiveRun(threadId: string) {
const runs = await openai.beta.threads.runs.list(threadId, {
limit: 1,
order: "desc",
});
const latestRun = runs.data[0];
if (latestRun && ['queued', 'in_progress', 'cancelling'].includes(latestRun.status)) {
throw new Error('Thread already has an active run. Wait or cancel first.');
}
}
// Before creating new run
await ensureNoActiveRun(threadId);
const run = await openai.beta.threads.runs.create(threadId, { assistant_id });typescript
async function ensureNoActiveRun(threadId: string) {
const runs = await openai.beta.threads.runs.list(threadId, {
limit: 1,
order: "desc",
});
const latestRun = runs.data[0];
if (latestRun && ['queued', 'in_progress', 'cancelling'].includes(latestRun.status)) {
throw new Error('线程已有活跃运行。请等待或先取消该运行。');
}
}
// 创建新运行前调用
await ensureNoActiveRun(threadId);
const run = await openai.beta.threads.runs.create(threadId, { assistant_id });Pattern 3: Thread Cleanup
模式3:线程清理
typescript
async function cleanupOldThreads(maxAgeHours = 24) {
const threads = await openai.beta.threads.list({ limit: 100 });
for (const thread of threads.data) {
const createdAt = new Date(thread.created_at * 1000);
const ageHours = (Date.now() - createdAt.getTime()) / (1000 * 60 * 60);
if (ageHours > maxAgeHours) {
await openai.beta.threads.del(thread.id);
}
}
}typescript
async function cleanupOldThreads(maxAgeHours = 24) {
const threads = await openai.beta.threads.list({ limit: 100 });
for (const thread of threads.data) {
const createdAt = new Date(thread.created_at * 1000);
const ageHours = (Date.now() - createdAt.getTime()) / (1000 * 60 * 60);
if (ageHours > maxAgeHours) {
await openai.beta.threads.del(thread.id);
}
}
}Error Handling
错误处理
Common Errors and Solutions
常见错误及解决方案
1. Thread Already Has Active Run
Error: 400 Can't add messages to thread_xxx while a run run_xxx is active.Solution:
typescript
// Wait for run to complete or cancel it
const run = await openai.beta.threads.runs.retrieve(threadId, runId);
if (['queued', 'in_progress'].includes(run.status)) {
await openai.beta.threads.runs.cancel(threadId, runId);
// Wait for cancellation
while (run.status !== 'cancelled') {
await new Promise(resolve => setTimeout(resolve, 500));
run = await openai.beta.threads.runs.retrieve(threadId, runId);
}
}2. Run Polling Timeout
Long-running tasks may exceed reasonable polling windows.
Solution:
typescript
async function pollWithTimeout(threadId: string, runId: string, maxSeconds = 300) {
const startTime = Date.now();
while (true) {
const run = await openai.beta.threads.runs.retrieve(threadId, runId);
if (!['queued', 'in_progress'].includes(run.status)) {
return run;
}
const elapsed = (Date.now() - startTime) / 1000;
if (elapsed > maxSeconds) {
await openai.beta.threads.runs.cancel(threadId, runId);
throw new Error('Run exceeded timeout');
}
await new Promise(resolve => setTimeout(resolve, 1000));
}
}3. Vector Store Not Ready
Using vector store before indexing completes.
Solution:
typescript
async function waitForVectorStore(vectorStoreId: string) {
let store = await openai.beta.vectorStores.retrieve(vectorStoreId);
while (store.status === 'in_progress') {
await new Promise(resolve => setTimeout(resolve, 2000));
store = await openai.beta.vectorStores.retrieve(vectorStoreId);
}
if (store.status === 'failed') {
throw new Error('Vector store indexing failed');
}
return store;
}4. File Upload Format Issues
Unsupported file formats cause errors.
Solution:
typescript
const SUPPORTED_FORMATS = {
code_interpreter: ['.csv', '.json', '.pdf', '.txt', '.py', '.js', '.xlsx'],
file_search: ['.pdf', '.docx', '.txt', '.md', '.html'],
};
function validateFile(filename: string, tool: string) {
const ext = filename.substring(filename.lastIndexOf('.')).toLowerCase();
if (!SUPPORTED_FORMATS[tool].includes(ext)) {
throw new Error(`Unsupported file format for ${tool}: ${ext}`);
}
}See for complete error catalog.
references/top-errors.md1. 线程已有活跃运行
Error: 400 Can't add messages to thread_xxx while a run run_xxx is active.解决方案:
typescript
// 等待运行完成或取消运行
const run = await openai.beta.threads.runs.retrieve(threadId, runId);
if (['queued', 'in_progress'].includes(run.status)) {
await openai.beta.threads.runs.cancel(threadId, runId);
// 等待取消完成
while (run.status !== 'cancelled') {
await new Promise(resolve => setTimeout(resolve, 500));
run = await openai.beta.threads.runs.retrieve(threadId, runId);
}
}2. 运行轮询超时
长时间运行的任务可能超出合理的轮询窗口。
解决方案:
typescript
async function pollWithTimeout(threadId: string, runId: string, maxSeconds = 300) {
const startTime = Date.now();
while (true) {
const run = await openai.beta.threads.runs.retrieve(threadId, runId);
if (!['queued', 'in_progress'].includes(run.status)) {
return run;
}
const elapsed = (Date.now() - startTime) / 1000;
if (elapsed > maxSeconds) {
await openai.beta.threads.runs.cancel(threadId, runId);
throw new Error('运行超出超时时间');
}
await new Promise(resolve => setTimeout(resolve, 1000));
}
}3. 向量存储未就绪
在索引完成前使用向量存储会导致错误。
解决方案:
typescript
async function waitForVectorStore(vectorStoreId: string) {
let store = await openai.beta.vectorStores.retrieve(vectorStoreId);
while (store.status === 'in_progress') {
await new Promise(resolve => setTimeout(resolve, 2000));
store = await openai.beta.vectorStores.retrieve(vectorStoreId);
}
if (store.status === 'failed') {
throw new Error('向量存储索引失败');
}
return store;
}4. 文件上传格式问题
不支持的文件格式会导致错误。
解决方案:
typescript
const SUPPORTED_FORMATS = {
code_interpreter: ['.csv', '.json', '.pdf', '.txt', '.py', '.js', '.xlsx'],
file_search: ['.pdf', '.docx', '.txt', '.md', '.html'],
};
function validateFile(filename: string, tool: string) {
const ext = filename.substring(filename.lastIndexOf('.')).toLowerCase();
if (!SUPPORTED_FORMATS[tool].includes(ext)) {
throw new Error(`${tool}不支持该文件格式:${ext}`);
}
}完整错误目录请参考。
references/top-errors.mdProduction Best Practices
生产环境最佳实践
1. Use Assistant IDs (Don't Recreate)
1. 使用助手ID(不要重复创建)
❌ Bad:
typescript
// Creates new assistant on every request!
const assistant = await openai.beta.assistants.create({ ... });✅ Good:
typescript
// Create once, store ID, reuse
const ASSISTANT_ID = process.env.ASSISTANT_ID || await createAssistant();
async function createAssistant() {
const assistant = await openai.beta.assistants.create({ ... });
console.log('Save this ID:', assistant.id);
return assistant.id;
}❌ 错误做法:
typescript
// 每次请求都创建新助手!
const assistant = await openai.beta.assistants.create({ ... });✅ 正确做法:
typescript
// 创建一次,保存ID,重复使用
const ASSISTANT_ID = process.env.ASSISTANT_ID || await createAssistant();
async function createAssistant() {
const assistant = await openai.beta.assistants.create({ ... });
console.log('保存该ID:', assistant.id);
return assistant.id;
}2. Implement Proper Error Handling
2. 实现完善的错误处理
typescript
async function createRunWithRetry(threadId: string, assistantId: string, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await openai.beta.threads.runs.create(threadId, {
assistant_id: assistantId,
});
} catch (error) {
if (error.status === 429) {
// Rate limit - wait and retry
await new Promise(resolve => setTimeout(resolve, 2000 * (i + 1)));
continue;
}
if (error.message?.includes('active run')) {
// Wait for active run to complete
await new Promise(resolve => setTimeout(resolve, 5000));
continue;
}
throw error; // Other errors
}
}
throw new Error('Max retries exceeded');
}typescript
async function createRunWithRetry(threadId: string, assistantId: string, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await openai.beta.threads.runs.create(threadId, {
assistant_id: assistantId,
});
} catch (error) {
if (error.status === 429) {
// 速率限制 - 等待后重试
await new Promise(resolve => setTimeout(resolve, 2000 * (i + 1)));
continue;
}
if (error.message?.includes('active run')) {
// 等待活跃运行完成
await new Promise(resolve => setTimeout(resolve, 5000));
continue;
}
throw error; // 其他错误
}
}
throw new Error('超出最大重试次数');
}3. Monitor Costs
3. 监控成本
typescript
// Track usage
const run = await openai.beta.threads.runs.retrieve(threadId, runId);
console.log('Tokens used:', run.usage);
// { prompt_tokens: 150, completion_tokens: 200, total_tokens: 350 }
// Set limits
const run = await openai.beta.threads.runs.create(threadId, {
assistant_id: assistantId,
max_prompt_tokens: 1000,
max_completion_tokens: 500,
});typescript
// 跟踪使用量
const run = await openai.beta.threads.runs.retrieve(threadId, runId);
console.log('使用的令牌数:', run.usage);
// { prompt_tokens: 150, completion_tokens: 200, total_tokens: 350 }
// 设置限制
const run = await openai.beta.threads.runs.create(threadId, {
assistant_id: assistantId,
max_prompt_tokens: 1000,
max_completion_tokens: 500,
});4. Clean Up Resources
4. 清理资源
typescript
// Delete old threads
async function cleanupUserThread(userId: string) {
const threadId = await db.getThreadIdForUser(userId);
if (threadId) {
await openai.beta.threads.del(threadId);
await db.deleteThreadIdForUser(userId);
}
}
// Delete unused vector stores
async function cleanupVectorStores(keepDays = 30) {
const stores = await openai.beta.vectorStores.list({ limit: 100 });
for (const store of stores.data) {
const ageSeconds = Date.now() / 1000 - store.created_at;
const ageDays = ageSeconds / (60 * 60 * 24);
if (ageDays > keepDays) {
await openai.beta.vectorStores.del(store.id);
}
}
}typescript
// 删除旧线程
async function cleanupUserThread(userId: string) {
const threadId = await db.getThreadIdForUser(userId);
if (threadId) {
await openai.beta.threads.del(threadId);
await db.deleteThreadIdForUser(userId);
}
}
// 删除未使用的向量存储
async function cleanupVectorStores(keepDays = 30) {
const stores = await openai.beta.vectorStores.list({ limit: 100 });
for (const store of stores.data) {
const ageSeconds = Date.now() / 1000 - store.created_at;
const ageDays = ageSeconds / (60 * 60 * 24);
if (ageDays > keepDays) {
await openai.beta.vectorStores.del(store.id);
}
}
}5. Use Streaming for Better UX
5. 使用流式处理提升用户体验
typescript
// Show progress in real-time
async function streamToUser(threadId: string, assistantId: string) {
const stream = await openai.beta.threads.runs.stream(threadId, {
assistant_id: assistantId,
});
for await (const event of stream) {
if (event.event === 'thread.message.delta') {
const delta = event.data.delta.content?.[0]?.text?.value;
if (delta) {
// Send to user immediately
sendToClient(delta);
}
}
}
}typescript
// 实时展示进度
async function streamToUser(threadId: string, assistantId: string) {
const stream = await openai.beta.threads.runs.stream(threadId, {
assistant_id: assistantId,
});
for await (const event of stream) {
if (event.event === 'thread.message.delta') {
const delta = event.data.delta.content?.[0]?.text?.value;
if (delta) {
// 立即发送给用户
sendToClient(delta);
}
}
}
}Relationship to Other Skills
与其他指南的关系
vs. openai-api Skill
vs. openai-api 指南
openai-api (Chat Completions):
- Stateless requests
- Manual history management
- Direct responses
- Use for: Simple text generation, function calling
openai-assistants:
- Stateful conversations (threads)
- Automatic history management
- Built-in tools (Code Interpreter, File Search)
- Use for: Chatbots, data analysis, RAG
openai-api(聊天补全):
- 无状态请求
- 手动管理历史记录
- 直接返回响应
- 适用场景:简单文本生成、函数调用
openai-assistants:
- 有状态对话(线程)
- 自动管理历史记录
- 内置工具(代码解释器、文件搜索)
- 适用场景:聊天机器人、数据分析、RAG
vs. openai-responses Skill
vs. openai-responses 指南
openai-responses (Responses API):
- ✅ Recommended for new projects
- Better reasoning preservation
- Modern MCP integration
- Active development
openai-assistants:
- ⚠️ Deprecated in H1 2026
- Use for legacy apps
- Migration path available
Migration: See
references/migration-to-responses.mdopenai-responses(Responses API):
- ✅ 新项目推荐使用
- 更好的推理能力保留
- 现代化MCP集成
- 持续开发中
openai-assistants:
- ⚠️ 2026年上半年弃用
- 适用于遗留应用
- 提供迁移路径
迁移: 请参考
references/migration-to-responses.mdMigration from v1 to v2
从v1迁移至v2
v1 deprecated: December 18, 2024
Key Changes:
- Retrieval → File Search: tool replaced with
retrievalfile_search - Vector Stores: Files now organized in vector stores (10,000 file limit)
- Instructions Limit: Increased from 32k to 256k characters
- File Attachments: Now message-level instead of assistant-level
See for complete guide.
references/migration-from-v1.mdv1 弃用时间:2024年12月18日
主要变化:
- 检索 → 文件搜索:工具替换为
retrievalfile_search - 向量存储:文件现在组织在向量存储中(最多10,000个文件)
- 指令限制:从32k字符提升至256k字符
- 文件附件:现在属于消息级别而非助手级别
完整迁移指南请参考。
references/migration-from-v1.mdNext Steps
下一步
Templates:
- - Simple math tutor
templates/basic-assistant.ts - - Data analysis
templates/code-interpreter-assistant.ts - - RAG with vector stores
templates/file-search-assistant.ts - - Custom tools
templates/function-calling-assistant.ts - - Real-time streaming
templates/streaming-assistant.ts
References:
- - 12 common errors and solutions
references/top-errors.md - - Thread management patterns
references/thread-lifecycle.md - - Vector store deep dive
references/vector-stores.md
Related Skills:
- - Modern replacement (recommended)
openai-responses - - Chat Completions (stateless)
openai-api
Last Updated: 2025-10-25
Package Version: openai@6.7.0
Status: Production Ready (Deprecated H1 2026)
模板:
- - 简单数学导师
templates/basic-assistant.ts - - 数据分析
templates/code-interpreter-assistant.ts - - 基于向量存储的RAG
templates/file-search-assistant.ts - - 自定义工具
templates/function-calling-assistant.ts - - 实时流式处理
templates/streaming-assistant.ts
参考文档:
- - 12种常见错误及解决方案
references/top-errors.md - - 线程管理模式
references/thread-lifecycle.md - - 向量存储深度解析
references/vector-stores.md
相关指南:
- - 现代化替代方案(推荐)
openai-responses - - 聊天补全(无状态)
openai-api
最后更新:2025-10-25
包版本:openai@6.7.0
状态:生产可用(2026年上半年弃用)