OpenAI Assistants 迁移指南

2026-11-09 16:21 更新

Assistants API 已于2026年8月26日正式停止服务,目前不可用。新集成请使用Responses API。

感谢曾使用Assistants API的开发者,以及大家开发的应用和提供的反馈。本文说明如何将集成迁移到Responses API。

Responses的使用方式更简单:发送输入条目(Item),接收输出条目。它还提供更好的性能,以及网页搜索、MCP、计算机使用等功能。也可以通过会话对象管理上下文,代替每次传回previous_response_id。

迁移时注意:下文保留官方指南中的prompt对象迁移路径,但可复用prompt对象也已进入弃用流程。长期集成采用该路径前,应查看弃用时间表及从prompt对象迁移。旧Assistants调用只用于说明历史结构,不能作为当前可运行请求。

有哪些变化

以前 现在 原因
Assistants Prompts 保存模型、工具和指令等配置,更便于版本管理和更新。
Threads Conversations 保存条目流,不再局限于消息。
Runs Responses 发送输入条目或使用会话对象,接收输出条目;工具调用循环由应用显式管理。
Run steps Items 通用对象可以表示消息、工具调用、工具输出等。

从assistants迁移到prompts

Assistant是持久化API对象,将模型选择、指令和工具声明组合起来,完全通过API创建和管理。此指南中的替代方案prompt只能在控制台创建,并可随产品开发进行版本管理。

这样做的好处

  • 可移植性与版本管理:可以对提示规格建立快照、审核、比较差异和回滚;为prompt建立版本后,代码可以引用最新版本。
  • 职责分离:应用代码负责历史裁剪、工具循环和重试;prompt负责系统指导、工具可用性、结构化输出Schema和默认温度等高层行为与约束。
  • Realtime兼容性:连接Realtime API时可复用相同配置,使聊天、流式响应和低延迟交互会话共用一份行为定义。
  • 工具与输出一致性:prompt封装工具Schema及结构化输出要求,使用它启动的Responses或Realtime会话继承一致约定。

实际迁移步骤

  1. 找出每个Assistant的“指令+工具”组合。
  2. 在控制台中将其重新创建为具名prompt。
  3. 将prompt ID或导出的规格纳入版本控制,使应用引用稳定标识。
  4. 上线期间通过切换prompt ID进行A/B测试,无须用程序创建或删除Assistant对象。

可以将prompt理解为可接入Responses或Realtime API的带版本行为配置。

从threads迁移到conversations

Thread是在服务端保存的消息集合,只能存储消息。Conversation保存条目,条目可以是消息、工具调用、工具输出或其他数据。

请求示例

Python

Thread对象

来源示例 1(python):

代码内提示词/文本译释:

  • what are the 5 Ds of dodgeball?:躲避球的五个D是什么?

## [中文] 历史Assistants示例:创建Thread并写入用户消息和metadata;该API已停止服务,仅用于对照迁移前结构。
thread = openai.beta.threads.create(
    messages=[{"role": "user", "content": "what are the 5 Ds of dodgeball?"}],
    metadata={"user_id": "peter_le_fleur"},
)

Conversation对象

来源示例 2(python):

代码内提示词/文本译释:

  • what are the 5 Ds of dodgeball?:躲避球的五个D是什么?

## [中文] 创建Conversation,以items保存用户消息,并保留应用metadata;与Thread创建方式对照。
conversation = openai.conversations.create(
    items=[{"role": "user", "content": "what are the 5 Ds of dodgeball?"}],
    metadata={"user_id": "peter_le_fleur"},
)

Go

Thread对象(Go)

来源示例 3(go):

代码内提示词/文本译释:

  • what are the 5 Ds of dodgeball?:躲避球的五个D是什么?

// [中文] 历史Assistants示例:创建Thread并写入用户消息和metadata;该API已停止服务,仅用于对照迁移前结构。
thread, err := client.Beta.Threads.New(context.Background(), openai.BetaThreadNewParams{
    Messages: []openai.BetaThreadNewParamsMessage{{
        Role: "user",
        Content: openai.BetaThreadNewParamsMessageContentUnion{
            OfString: openai.String("what are the 5 Ds of dodgeball?"),
        },
    }},
    Metadata: shared.Metadata{"user_id": "peter_le_fleur"},
})
if err != nil {
    panic(err)
}

Conversation对象(Go)

来源示例 4(go):

代码内提示词/文本译释:

  • what are the 5 Ds of dodgeball?:躲避球的五个D是什么?

// [中文] 创建Conversation,以items保存用户消息,并保留应用metadata;与Thread创建方式对照。
conversation, err := client.Conversations.New(context.Background(), conversations.ConversationNewParams{
    Items: []responses.ResponseInputItemUnionParam{
        responses.ResponseInputItemParamOfMessage("what are the 5 Ds of dodgeball?", responses.EasyInputMessageRoleUser),
    },
    Metadata: shared.Metadata{"user_id": "peter_le_fleur"},
})
if err != nil {
    panic(err)
}

JavaScript

Thread对象(JavaScript)

来源示例 5(javascript):

代码内提示词/文本译释:

  • what are the 5 Ds of dodgeball?:躲避球的五个D是什么?

// [中文] 历史Assistants示例:创建Thread并写入用户消息和metadata;该API已停止服务,仅用于对照迁移前结构。
import OpenAI from "openai";

const client = new OpenAI();
const thread = await client.beta.threads.create({
  messages: [{ role: "user", content: "what are the 5 Ds of dodgeball?" }],
  metadata: { user_id: "peter_le_fleur" },
});
console.log(thread.id);

Conversation对象(JavaScript)

来源示例 6(javascript):

代码内提示词/文本译释:

  • What are the five Ds of dodgeball?:躲避球的五个D是什么?

// [中文] 创建Conversation,以items保存用户消息,并保留应用metadata;与Thread创建方式对照。
import OpenAI from "openai";

const client = new OpenAI();

const conversation = await client.conversations.create({
  items: [{ role: "user", content: "What are the five Ds of dodgeball?" }],
  metadata: { user_id: "peter_le_fleur" },
});

console.log(conversation.id);

响应示例

Thread对象

来源示例 7(json):

中文译释:历史Thread对象:id为线程标识,metadata保存应用元数据,tool_resources为工具资源;不是当前可调用请求。

{
  "id": "thread_CrXtCzcyEQbkAcXuNmVSKFs1",
  "object": "thread",
  "created_at": 1752855924,
  "metadata": {
    "user_id": "peter_le_fleur"
  },
  "tool_resources": {}
}

Conversation对象

来源示例 8(json):

中文译释:Conversation对象包含会话ID、创建时间和metadata;字段名与原始ID保持不变。

{
    "id": "conv_68542dc602388199a30af27d040cefd4087a04b576bfeb24",
    "object": "conversation",
    "created_at": 1752855924,
    "metadata": {
        "user_id": "peter_le_fleur"
    }
}

从runs迁移到responses

Run是在Thread上执行的异步过程。Response更直接:提供一组输入条目执行,获得输出条目列表。

Responses可以独立使用,也可以搭配prompt和conversation对象保存配置与上下文。

请求示例

Python

Run对象

来源示例 9(python):

## [中文] 历史Assistants示例:在Thread上创建Run并轮询状态;停止服务后的接口不可用于当前集成。
## Replace the illustrative IDs and URLs below with your own resource values.
import time

from openai import OpenAI

openai = OpenAI()
thread_id = "thread_123"
assistant_id = "asst_123"

run = openai.beta.threads.runs.create(
    thread_id=thread_id,
    assistant_id=assistant_id,
)

while run.status in ("queued", "in_progress"):
    time.sleep(1)
    run = openai.beta.threads.runs.retrieve(thread_id=thread_id, run_id=run.id)

Response对象

来源示例 10(python):

代码内提示词/文本译释:

  • What are the 5 Ds of dodgeball?:躲避球的五个D是什么?

## [中文] 向Responses发送输入并关联Conversation;替换示例会话ID,与旧Run流程对照。
## Replace the illustrative IDs and URLs below with your own resource values.

from openai import OpenAI

openai = OpenAI()
conversation_id = "conv_123"

response = openai.responses.create(
    model="gpt-6-astra",
    input=[{"role": "user", "content": "What are the 5 Ds of dodgeball?"}],
    conversation=conversation_id,
)

Go

Run对象(Go)

来源示例 11(go):

// [中文] 历史Assistants示例:在Thread上创建Run并轮询状态;停止服务后的接口不可用于当前集成。
run, err := client.Beta.Threads.Runs.New(context.Background(), "thread_abc123", openai.BetaThreadRunNewParams{
    AssistantID: "asst_abc123",
})
if err != nil {
    panic(err)
}
for run.Status == openai.RunStatusQueued || run.Status == openai.RunStatusInProgress {
    time.Sleep(time.Second)
    run, err = client.Beta.Threads.Runs.Get(context.Background(), "thread_abc123", run.ID)
    if err != nil {
        panic(err)
    }
}

Response对象(Go)

来源示例 12(go):

代码内提示词/文本译释:

  • What are the 5 Ds of dodgeball?:躲避球的五个D是什么?

// [中文] 向Responses发送输入并关联Conversation;替换示例会话ID,与旧Run流程对照。
_, err := client.Responses.New(context.Background(), responses.ResponseNewParams{
    Model: "gpt-6-astra",
    Input: responses.ResponseNewParamsInputUnion{OfInputItemList: responses.ResponseInputParam{
        responses.ResponseInputItemParamOfMessage("What are the 5 Ds of dodgeball?", responses.EasyInputMessageRoleUser),
    }},
    Conversation: responses.ResponseNewParamsConversationUnion{OfString: openai.String("conv_abc123")},
})
if err != nil {
    panic(err)
}

JavaScript

Run对象(JavaScript)

来源示例 13(javascript):

// [中文] 历史Assistants示例:在Thread上创建Run并轮询状态;停止服务后的接口不可用于当前集成。
import { setTimeout } from "node:timers/promises";
import OpenAI from "openai";

const client = new OpenAI();
// Replace these illustrative IDs with your own resources.
const threadId = "thread_123";
const assistantId = "asst_123";
let run = await client.beta.threads.runs.create(threadId, {
  assistant_id: assistantId,
});
while (run.status === "queued" || run.status === "in_progress") {
  await setTimeout(1000);
  run = await client.beta.threads.runs.retrieve(run.id, {
    thread_id: threadId,
  });
}
console.log(run.status);

Response对象(JavaScript)

来源示例 14(javascript):

代码内提示词/文本译释:

  • What are the five Ds of dodgeball?:躲避球的五个D是什么?

// [中文] 向Responses发送输入并关联Conversation;替换示例会话ID,与旧Run流程对照。
// Replace the illustrative IDs and URLs below with your own resource values.
import OpenAI from "openai";

const client = new OpenAI();
const conversationId = "conv_123";

const response = await client.responses.create({
  model: "gpt-6-astra",
  input: [{ role: "user", content: "What are the five Ds of dodgeball?" }],
  conversation: conversationId,
});

console.log(response.output_text);

响应示例

Run对象

来源示例 15(json):

中文译释:历史Run响应展示状态、线程/助手ID、工具配置及用量。completed表示该次示例运行完成,不表示旧接口现在可用。

{
  "id": "run_FKIpcs5ECSwuCmehBqsqkORj",
  "assistant_id": "asst_8fVY45hU3IM6creFkVi5MBKB",
  "cancelled_at": null,
  "completed_at": 1752857327,
  "created_at": 1752857322,
  "expires_at": null,
  "failed_at": null,
  "incomplete_details": null,
  "instructions": null,
  "last_error": null,
  "max_completion_tokens": null,
  "max_prompt_tokens": null,
  "metadata": {},
  "model": "gpt-4.1",
  "object": "thread.run",
  "parallel_tool_calls": true,
  "required_action": null,
  "response_format": "auto",
  "started_at": 1752857324,
  "status": "completed",
  "thread_id": "thread_CrXtCzcyEQbkAcXuNmVSKFs1",
  "tool_choice": "auto",
  "tools": [],
  "truncation_strategy": {
    "type": "auto",
    "last_messages": null
  },
  "usage": {
    "completion_tokens": 130,
    "prompt_tokens": 34,
    "total_tokens": 164,
    "prompt_token_details": {
      "cached_tokens": 0
    },
    "completion_tokens_details": {
      "reasoning_tokens": 0
    }
  },
  "temperature": 1.0,
  "top_p": 1.0,
  "tool_resources": {},
  "reasoning_effort": null
}

Response对象

来源示例 16(json):

中文译释:Response对象以output条目返回消息,并携带会话、推理、状态和用量信息。采用可解析的MD版本;HTML中的相同文本将JSON字符串内的换行转为实际换行,属于来源格式差异。

响应正文完整译文:所谓“躲避球的五个D”,是2004年喜剧电影《Dodgeball: A True Underdog Story》带火的一组幽默规则。教练Patches O’Houlihan用它训练球队:1. Dodge(躲闪);2. Duck(低头闪避);3. Dip(下蹲);4. Dive(扑身闪避);5. Dodge(再次强调躲闪)。电影的概括是:“能躲开扳手,就能躲开球!”这些并非正式比赛规则,而是与躲避球有关的趣味流行文化表达。

{
  "id": "resp_687a7b53036c819baad6012d58b39bcb074adcd9e24850fc",
  "created_at": 1752857427,
  "conversation": {
    "id": "conv_689667905b048191b4740501625afd940c7533ace33a2dab"
  },
  "error": null,
  "incomplete_details": null,
  "instructions": null,
  "metadata": {},
  "model": "gpt-5.5",
  "object": "response",
  "output": [
    {
      "id": "msg_687a7b542948819ba79e77e14791ef83074adcd9e24850fc",
      "content": [
        {
          "annotations": [],
          "text": "The \"5 Ds of Dodgeball\" are a humorous set of rules made famous by the 2004 comedy film **\"Dodgeball: A True Underdog Story.\"** In the movie, dodgeball coach Patches O’Houlihan teaches these basics to his team. The **5 Ds** are:\n\n1. **Dodge**\n2. **Duck**\n3. **Dip**\n4. **Dive**\n5. **Dodge** (yes, dodge is listed twice for emphasis!)\n\nIn summary:  \n> **“If you can dodge a wrench, you can dodge a ball!”**\n\nThese 5 Ds are not official competitive rules, but have become a fun and memorable pop culture reference for the sport of dodgeball.",
          "type": "output_text",
          "logprobs": []
        }
      ],
      "role": "assistant",
      "status": "completed",
      "type": "message"
    }
  ],
  "parallel_tool_calls": true,
  "temperature": 1.0,
  "tool_choice": "auto",
  "tools": [],
  "top_p": 1.0,
  "background": false,
  "max_output_tokens": null,
  "previous_response_id": null,
  "reasoning": {
    "effort": null,
    "generate_summary": null,
    "summary": null
  },
  "service_tier": "scale",
  "status": "completed",
  "text": {
    "format": {
      "type": "text"
    }
  },
  "truncation": "disabled",
  "usage": {
    "input_tokens": 17,
    "input_tokens_details": {
      "cached_tokens": 0
    },
    "output_tokens": 150,
    "output_tokens_details": {
      "reasoning_tokens": 0
    },
    "total_tokens": 167
  },
  "user": null,
  "max_tool_calls": null,
  "store": true,
  "top_logprobs": 0
}

迁移现有集成

按以下步骤从Assistants迁移到Responses,保留原有功能支持。

1. 根据assistants创建prompts

  1. 找出应用中最重要的Assistant对象。
  2. 在控制台找到对象,选择Create prompt。

这会根据每个已有Assistant创建prompt对象。

可复用prompt对象也正在弃用。若采用此迁移路径,应先查看prompt弃用时间表,再决定是否用于长期集成。

2. 将新聊天切换到conversations与responses

使用Conversations API和Responses API开始新聊天。需要保留此前历史时,使用应用自己已经保存的消息。

以下示例展示服务关闭前如何迁移Thread历史。其中检索Thread消息的Assistants调用现在已不可用,须改用自行保存的消息。

来源示例 17(python):

## [中文] 历史迁移示例:分页读取旧Thread消息,转换文本/图像为Item后创建Conversation;旧读取接口现不可用,须使用应用已保存的消息。
## Replace the illustrative IDs and URLs below with your own resource values.

from openai import OpenAI

openai = OpenAI()
messages = []
thread_id = "thread_123"

for page in openai.beta.threads.messages.list(
    thread_id=thread_id, order="asc"
).iter_pages():
    messages += page.data

items = []
for m in messages:
    item = {"role": m.role}
    item_content = []

    for content in m.content:
        match content.type:
            case "text":
                item_content_type = "input_text" if m.role == "user" else "output_text"
                item_content += [
                    {"type": item_content_type, "text": content.text.value}
                ]
            case "image_url":
                item_content += [
                    {
                        "type": "input_image",
                        "image_url": content.image_url.url,
                        "detail": content.image_url.detail,
                    }
                ]

    item |= {"content": item_content}
    items.append(item)

## create a conversation with your converted items
conversation = openai.conversations.create(items=items)

来源示例 18(ruby):

## [中文] 历史迁移示例:分页读取旧Thread消息,转换文本/图像为Item后创建Conversation;旧读取接口现不可用,须使用应用已保存的消息。
## Replace the illustrative IDs and URLs below with your own resource values.
require "openai"

client = OpenAI::Client.new
thread_id = "thread_123"
messages = client.beta.threads.messages.list(thread_id, order: :asc)
items = []
messages.auto_paging_each do |message|
  content = message.content.filter_map do |part|
    case part
    when OpenAI::Models::Beta::Threads::TextContentBlock
      type = if message.role == OpenAI::Models::Beta::Threads::Message::Role::USER
               :input_text
             else
               :output_text
             end
      {
        type: type,
        text: part.text.value
      }
    when OpenAI::Models::Beta::Threads::ImageURLContentBlock
      {
        type: :input_image,
        image_url: part.image_url.url,
        detail: part.image_url.detail
      }
    end
  end
  items << {
    role: message.role,
    content: content
  }
end
conversation = client.conversations.create(
  items: items
)
puts(conversation.id)

完整示例对照

以下集成分别使用Assistants API和Responses API,便于比较。

用户聊天应用

Assistants API(历史示例)

来源示例 19(python):

## [中文] 历史聊天后端:按session保存Thread、追加消息、运行并轮询Assistant后取回结果;片段依赖未展示的应用框架,旧API已不可用。
## Replace the illustrative IDs and URLs below with your own resource values.
threads_by_session: dict[str, str] = {}


@app.post("/messages")
async def message(message: Message):
    thread_id = threads_by_session.get(message.session_id)
    if thread_id is None:
        thread_id = openai.beta.threads.create().id
        threads_by_session[message.session_id] = thread_id

    openai.beta.threads.messages.create(
        thread_id=thread_id,
        role="user",
        content=message.content,
    )

    example_assistant_id = "asst_123"
    run = openai.beta.threads.runs.create(
        assistant_id=example_assistant_id,
        thread_id=thread_id,
    )
    while run.status in ("queued", "in_progress"):
        await asyncio.sleep(1)
        run = openai.beta.threads.runs.retrieve(
            thread_id=thread_id,
            run_id=run.id,
        )

    messages = openai.beta.threads.messages.list(
        order="desc",
        limit=1,
        thread_id=thread_id,
    )

    return {"content": messages.data[0].content}

来源示例 20(ruby):

代码内提示词/文本译释:

  • What are the five Ds of dodgeball?:躲避球的五个D是什么?

## [中文] Ruby历史聊天示例:初始化SDK客户端,定义并调用lambda,按session复用Thread、追加消息、创建并轮询Run,最后读取消息;旧API已不可用,仅供迁移对照。
## Replace the illustrative IDs and URLs below with your own resource values.
require "openai"

client = OpenAI::Client.new
assistant_id = "asst_123"
threads_by_session = {}

handle_message = lambda do |session_id:, content:|
  thread_id = threads_by_session[session_id]
  unless thread_id
    thread_id = client.beta.threads.create.id
    threads_by_session[session_id] = thread_id
  end

  client.beta.threads.messages.create(
    thread_id,
    role: :user,
    content: content
  )
  run = client.beta.threads.runs.create(
    thread_id,
    assistant_id: assistant_id
  )
  while [:queued, :in_progress].include?(run.status)
    sleep(1)
    run = client.beta.threads.runs.retrieve(run.id, thread_id: thread_id)
  end

  messages = client.beta.threads.messages.list(
    thread_id,
    order: :desc,
    limit: 1
  )
  { content: messages.data&.first&.content }
end

puts(
  handle_message.call(
    session_id: "example-session",
    content: "What are the five Ds of dodgeball?"
  )
)

Responses API

来源示例 21(javascript):

// [中文] Express聊天后端:校验输入,按session复用创建Conversation的Promise,再调用Responses并返回output_text;prompt ID与会话存储需按实际应用替换。
// Replace the illustrative IDs and URLs below with your own resource values.
import express from "express";
import OpenAI from "openai";

const app = express();
const client = new OpenAI();
const conversationsBySession = new Map();

app.use(express.json());

app.post("/messages", async (request, response) => {
  const { content, session_id: sessionId } = request.body ?? {};
  if (
    typeof content !== "string" ||
    !content.trim() ||
    typeof sessionId !== "string" ||
    !sessionId.trim()
  ) {
    response.status(400).json({
      error: "content and session_id must be non-empty strings.",
    });
    return;
  }

  let conversationIdPromise = conversationsBySession.get(sessionId);

  if (!conversationIdPromise) {
    conversationIdPromise = client.conversations
      .create()
      .then((conversation) => conversation.id)
      .catch((error) => {
        conversationsBySession.delete(sessionId);
        throw error;
      });
    conversationsBySession.set(sessionId, conversationIdPromise);
  }
  const conversationId = await conversationIdPromise;

  const promptId = "pmpt_123";

  const result = await client.responses.create({
    prompt: { id: promptId },
    input: [{ role: "user", content }],
    conversation: conversationId,
  });

  response.json({ content: result.output_text });
});

app.listen(Number(process.env.OPENAI_EXAMPLE_PORT ?? 8000), "127.0.0.1");

来源示例 22(python):

## [中文] 聊天处理片段:内存中按session复用Conversation,通过示例prompt ID调用Responses并返回output_text;框架、持久化与用户绑定由应用实现。
## Replace the illustrative IDs and URLs below with your own resource values.
conversations_by_session: dict[str, str] = {}


@app.post("/messages")
async def message(message: Message):
    # [中文] 缺少会话 ID 或消息内容时返回 400。完整应用需先从 fastapi 导入 HTTPException。
    if not message.session_id.strip() or not message.content.strip():
        raise HTTPException(
            status_code=400, detail="session_id and content are required"
        )
    conversation_id = conversations_by_session.get(message.session_id)
    if conversation_id is None:
        conversation_id = openai.conversations.create().id
        conversations_by_session[message.session_id] = conversation_id

    example_prompt_id = "pmpt_123"
    response = openai.responses.create(
        prompt={"id": example_prompt_id},
        input=[{"role": "user", "content": message.content}],
        conversation=conversation_id,
    )

    return {"content": response.output_text}

来源示例 23(go):

// [中文] Go聊天处理片段:校验输入、共享会话创建、允许等待请求取消,并在同一Conversation内串行响应;示例内存映射需绑定真实认证用户。
func main() {
    client := openai.NewClient()
    server := &http.Server{
        Addr:              "127.0.0.1:8000",
        Handler:           newChatHandler(client),
        ReadHeaderTimeout: 5 * time.Second,
    }
    log.Fatal(server.ListenAndServe())
}

func newChatHandler(client openai.Client) http.Handler {
    var mutex sync.Mutex
    type sessionConversation struct {
        ready        chan struct{}
        id           string
        err          error
        responseSlot chan struct{}
    }
    conversationsBySession := map[string]*sessionConversation{}
    mux := http.NewServeMux()
    mux.HandleFunc("POST /messages", func(w http.ResponseWriter, r *http.Request) {
        var message struct {
            Content   string `json:"content"`
            SessionID string `json:"session_id"`
        }
        if err := json.NewDecoder(http.MaxBytesReader(w, r.Body, 1<<20)).Decode(&message); err != nil || strings.TrimSpace(message.Content) == "" || strings.TrimSpace(message.SessionID) == "" {
            http.Error(w, "content and session_id must be non-empty strings", 400)
            return
        }
        // A demo session map. Bind session IDs to authenticated users in your application.
        mutex.Lock()
        session, exists := conversationsBySession[message.SessionID]
        if !exists {
            session = &sessionConversation{ready: make(chan struct{}), responseSlot: make(chan struct{}, 1)}
            conversationsBySession[message.SessionID] = session
        }
        mutex.Unlock()
        if !exists {
            go func() {
                // Creation belongs to the shared session, not the first HTTP request.
                ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
                defer cancel()
                conversation, err := client.Conversations.New(ctx, conversations.ConversationNewParams{})
                session.err = err
                if err == nil {
                    session.id = conversation.ID
                }
                mutex.Lock()
                if err != nil {
                    delete(conversationsBySession, message.SessionID)
                }
                close(session.ready)
                mutex.Unlock()
            }()
        }
        select {
        case <-r.Context().Done():
            http.Error(w, "Request cancelled", http.StatusRequestTimeout)
            return
        case <-session.ready:
        }
        if session.err != nil {
            http.Error(w, "Could not create conversation", http.StatusInternalServerError)
            return
        }
        // Serialize responses within this conversation; waiting requests can cancel.
        select {
        case session.responseSlot <- struct{}{}:
            defer func() { <-session.responseSlot }()
        case <-r.Context().Done():
            http.Error(w, "Request cancelled", http.StatusRequestTimeout)
            return
        }
        if r.Context().Err() != nil {
            http.Error(w, "Request cancelled", http.StatusRequestTimeout)
            return
        }
        // Replace this illustrative stored prompt ID with your prompt.
        result, err := client.Responses.New(r.Context(), responses.ResponseNewParams{
            Prompt: responses.ResponsePromptParam{
                ID: "pmpt_123",
            },
            Input: responses.ResponseNewParamsInputUnion{
                OfString: openai.String(message.Content),
            },
            Conversation: responses.ResponseNewParamsConversationUnion{
                OfString: openai.String(session.id),
            },
        })
        if err != nil || result.Status != responses.ResponseStatusCompleted {
            http.Error(w, "Could not create response", 500)
            return
        }
        w.Header().Set("Content-Type", "application/json")
        if err := json.NewEncoder(w).Encode(map[string]string{
            "content": result.OutputText(),
        }); err != nil {
            log.Print(err)
        }
    })
    return mux
}

来源示例 24(ruby):

代码内提示词/文本译释:

  • What are the five Ds of dodgeball?:躲避球的五个D是什么?

## [中文] Ruby聊天处理器:校验session和content,按session创建或复用Conversation,再调用Responses;示例prompt仍受弃用时间表约束。
## Replace the illustrative IDs and URLs below with your own resource values.
require "openai"

client = OpenAI::Client.new
conversations_by_session = {}

handle_message = lambda do |session_id:, content:|
  unless session_id.is_a?(String) && !session_id.strip.empty? && content.is_a?(String) && !content.strip.empty?
    raise ArgumentError, "session_id and content are required"
  end

  conversation_id = conversations_by_session[session_id]
  unless conversation_id
    conversation_id = client.conversations.create.id
    conversations_by_session[session_id] = conversation_id
  end

  response = client.responses.create(
    prompt: { id: "pmpt_123" },
    input: [
      {
        role: :user,
        content: content
      }
    ],
    conversation: conversation_id
  )
  { content: response.output_text }
end

puts(
  handle_message.call(
    session_id: "example-session",
    content: "What are the five Ds of dodgeball?"
  )
)
以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号