openai-assistants

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

OpenAI 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
references/migration-to-responses.md
for complete migration guide.

OpenAI宣布将停用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.md

Table of Contents

目录

Quick Start

快速开始

Installation

安装

bash
npm install openai@6.7.0
bash
npm install openai@6.7.0

Environment 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:
  • model
    (required): Model ID (gpt-4o, gpt-5, gpt-4-turbo)
  • instructions
    : System prompt (max 256k characters in v2, was 32k in v1)
  • name
    : Assistant name (max 256 characters)
  • description
    : Description (max 512 characters)
  • tools
    : Array of tools (max 128 tools)
  • tool_resources
    : Resources for tools (vector stores, files)
  • temperature
    : 0-2 (default 1)
  • top_p
    : 0-1 (default 1)
  • response_format
    : "auto", "json_object", or JSON schema
  • metadata
    : Key-value pairs (max 16 pairs)
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",
  },
});
参数说明:
  • model
    (必填):模型ID(gpt-4o、gpt-5、gpt-4-turbo等)
  • instructions
    :系统提示词(v2版本最多256k字符,v1版本为32k字符)
  • name
    :助手名称(最多256字符)
  • description
    :助手描述(最多512字符)
  • tools
    :工具数组(最多128个工具)
  • tool_resources
    :工具所需资源(向量存储、文件)
  • temperature
    :0-2(默认值为1)
  • top_p
    :0-1(默认值为1)
  • response_format
    :"auto"、"json_object"或JSON schema
  • metadata
    :键值对(最多16对)

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:
  • role
    : "user" only (assistant messages created by runs)
  • content
    : Text or array of content blocks
  • attachments
    : Files with associated tools
  • metadata
    : Key-value pairs
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(),
  },
});
参数说明:
  • role
    :仅支持"user"(助手消息由运行自动生成)
  • 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:
  • assistant_id
    (required): Assistant to use
  • instructions
    : Override assistant instructions
  • additional_messages
    : Add messages before running
  • tools
    : Override assistant tools
  • metadata
    : Key-value pairs
  • temperature
    : Override temperature
  • top_p
    : Override top_p
  • max_prompt_tokens
    : Limit input tokens
  • max_completion_tokens
    : Limit output tokens
typescript
const run = await openai.beta.threads.runs.create("thread_abc123", {
  assistant_id: "asst_abc123",
  instructions: "请称呼用户为Jane Doe。",
  additional_messages: [
    {
      role: "user",
      content: "你能帮我处理这个问题吗?",
    },
  ],
});
参数说明:
  • assistant_id
    (必填):要使用的助手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

运行状态

StateDescription
queued
Run is waiting to start
in_progress
Run is executing
requires_action
Function calling needs your input
cancelling
Cancellation in progress
cancelled
Run was cancelled
failed
Run failed (check
last_error
)
completed
Run finished successfully
expired
Run expired (max 10 minutes)
状态描述
queued
运行等待启动
in_progress
运行正在执行
requires_action
需要用户输入以完成函数调用
cancelling
正在取消运行
cancelled
运行已取消
failed
运行失败(查看
last_error
completed
运行成功完成
expired
运行已过期(最长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
status
becomes
cancelled
.
typescript
const run = await openai.beta.threads.runs.cancel("thread_abc123", "run_abc123");
⚠️ 重要提示:取消操作是异步的,请确认
status
变为
cancelled

List 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

流式事件类型

EventDescription
thread.run.created
Run was created
thread.run.in_progress
Run started
thread.run.step.created
Step created (tool call, message creation)
thread.run.step.delta
Step progress update
thread.message.created
Message created
thread.message.delta
Message content streaming
thread.message.completed
Message finished
thread.run.completed
Run finished
thread.run.failed
Run failed
thread.run.requires_action
Function calling needed
事件描述
thread.run.created
运行已创建
thread.run.in_progress
运行已启动
thread.run.step.created
步骤已创建(工具调用、消息生成)
thread.run.step.delta
步骤进度更新
thread.message.created
消息已创建
thread.message.delta
消息内容流式返回
thread.message.completed
消息生成完成
thread.run.completed
运行完成
thread.run.failed
运行失败
thread.run.requires_action
需要进行函数调用

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 outputs
Output 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
    completed
    before using
  • 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
status: "completed"
before using with file search.
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_abc123
Supported 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 content
typescript
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
references/top-errors.md
for complete error catalog.

1. 线程已有活跃运行
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.md

Production 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.md

openai-responses(Responses API):
  • 新项目推荐使用
  • 更好的推理能力保留
  • 现代化MCP集成
  • 持续开发中
openai-assistants
  • ⚠️ 2026年上半年弃用
  • 适用于遗留应用
  • 提供迁移路径
迁移: 请参考
references/migration-to-responses.md

Migration from v1 to v2

从v1迁移至v2

v1 deprecated: December 18, 2024
Key Changes:
  1. Retrieval → File Search:
    retrieval
    tool replaced with
    file_search
  2. Vector Stores: Files now organized in vector stores (10,000 file limit)
  3. Instructions Limit: Increased from 32k to 256k characters
  4. File Attachments: Now message-level instead of assistant-level
See
references/migration-from-v1.md
for complete guide.

v1 弃用时间:2024年12月18日
主要变化:
  1. 检索 → 文件搜索
    retrieval
    工具替换为
    file_search
  2. 向量存储:文件现在组织在向量存储中(最多10,000个文件)
  3. 指令限制:从32k字符提升至256k字符
  4. 文件附件:现在属于消息级别而非助手级别
完整迁移指南请参考
references/migration-from-v1.md

Next Steps

下一步

Templates:
  • templates/basic-assistant.ts
    - Simple math tutor
  • templates/code-interpreter-assistant.ts
    - Data analysis
  • templates/file-search-assistant.ts
    - RAG with vector stores
  • templates/function-calling-assistant.ts
    - Custom tools
  • templates/streaming-assistant.ts
    - Real-time streaming
References:
  • references/top-errors.md
    - 12 common errors and solutions
  • references/thread-lifecycle.md
    - Thread management patterns
  • references/vector-stores.md
    - Vector store deep dive
Related Skills:
  • openai-responses
    - Modern replacement (recommended)
  • openai-api
    - Chat Completions (stateless)

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
    - 数据分析
  • templates/file-search-assistant.ts
    - 基于向量存储的RAG
  • templates/function-calling-assistant.ts
    - 自定义工具
  • templates/streaming-assistant.ts
    - 实时流式处理
参考文档:
  • references/top-errors.md
    - 12种常见错误及解决方案
  • references/thread-lifecycle.md
    - 线程管理模式
  • references/vector-stores.md
    - 向量存储深度解析
相关指南:
  • openai-responses
    - 现代化替代方案(推荐)
  • openai-api
    - 聊天补全(无状态)

最后更新:2025-10-25 包版本:openai@6.7.0 状态:生产可用(2026年上半年弃用)