Open Responses là gì?
Open Responses là một đặc tả mở, được công bố dưới dạng tài liệu OpenAPI 3.1, mô tả một hình dạng yêu cầu và phản hồi duy nhất để gọi các mô hình ngôn ngữ trên nhiều nhà cung cấp. Nó dựa trên OpenAI Responses API: bạn gửi model, input và tools tùy chọn tới POST /v1/responses, và bạn nhận lại các item có kiểu và các sự kiện streaming ngữ nghĩa thay vì một định dạng riêng của nhà cung cấp. OpenAI ra mắt Open Responses vào 2026-01-15, nó được cấp phép theo Apache 2.0, và vào 2026-10-22 OpenAI đã đóng góp nó cho Agentic AI Foundation (AAIF), tổ chức thuộc Linux Foundation cũng đang vận hành MCP.
{% cta apidog.com %} Dùng thử Apidog ngay hôm nay {% endcta %}
Bước cuối cùng đó chính là tin tức: đặc tả giờ đây đã có một hiến chương kỹ thuật, một ủy ban chỉ đạo và một ngôi nhà trung lập. Bài viết này đề cập đến những gì nó định nghĩa, ai triển khai nó, việc chuyển sang AAIF thay đổi điều gì, và cách kiểm tra xem một endpoint mà bạn phụ thuộc có tuân thủ hay không. Nếu bạn mới làm quen với API nền tảng, hãy bắt đầu với cách sử dụng OpenAI Responses API.
Open Responses định nghĩa những gì
Đặc tả mô tả vấn đề một cách rõ ràng: các nhà cung cấp đã hội tụ về cùng những khối xây dựng (tin nhắn, lệnh gọi công cụ, streaming, đầu vào đa phương thức) nhưng mỗi bên mã hóa chúng theo cách khác nhau. Open Responses chọn một cách mã hóa và ghi nó ra.
Tài liệu OpenAPI hiện tại là phiên bản 2026-04-24 và bao phủ một bề mặt nhỏ:
| Thao tác | Chức năng |
| --- | --- |
| POST /responses (createResponse) | Tạo một phản hồi, có hoặc không streaming |
| WebSocket trên /responses | Cùng mô hình phản hồi qua một socket liên tục (thêm vào 2026-04-24) |
| POST /responses/compact (compactResponse) | Trả về một cửa sổ đầu vào đã nén cho các cuộc hội thoại dài |
Phần thân yêu cầu chấp nhận các trường mà bạn sẽ mong đợi nếu đã từng dùng API của OpenAI: model, input, instructions, tools, tool_choice, stream, store, previous_response_id, reasoning, text, truncation, temperature, top_p, max_output_tokens, prompt_cache_key và một vài trường khác. Đối tượng phản hồi (ResponseResource) mang id, status, output, usage, error và một bản sao của các thiết lập bạn đã gửi. Tài liệu định nghĩa tổng cộng 108 schema, hầu hết là các kiểu item và sự kiện streaming.
Ba ý tưởng mang thiết kế này.
Item là đơn vị ngữ cảnh
Mọi thứ mô hình đọc hoặc tạo ra đều là một item: một message, một function_call, một function_call_output, một item reasoning. Các item có tính hai chiều, vì vậy đầu ra của một lượt có thể được đưa thẳng trở lại làm đầu vào cho lượt tiếp theo. Mỗi kiểu item được phân biệt bởi trường type của nó và có schema riêng.
Các item cũng là máy trạng thái: mỗi item chuyển từ in_progress sang completed hoặc incomplete (ngân sách token đã cạn), và một item incomplete phải là item cuối cùng được phát ra, với toàn bộ phản hồi được đánh dấu là incomplete. Trạng thái không nói lên điều gì về việc máy chủ có lưu trữ item hay không; việc lưu trữ là một mối quan tâm riêng.
Streaming là các sự kiện ngữ nghĩa, không phải các delta thô
Khi bạn đặt stream: true, máy chủ phải trả lời với Content-Type: text/event-stream và một chuỗi sự kiện được định nghĩa. Một item đầu ra mở đầu bằng response.output_item.added; văn bản bên trong nó đến dưới dạng response.content_part.added, sau đó là các sự kiện response.output_text.delta lặp lại, rồi response.output_text.done và response.content_part.done; item kết thúc bằng response.output_item.done. Luồng phải kết thúc bằng một sự kiện kết thúc: response.completed, response.failed hoặc response.incomplete. Một [DONE] ở cuối là tùy chọn, và các client phải xử lý được một luồng kết thúc mà không có nó.
!Diagram of the Open Responses streaming event order: output_item.added, content_part.added, output_text.delta repeated, output_text.done, content_part.done, output_item.done, then a terminal completed, failed or incomplete event
Điều này quan trọng nhất đối với mã client: nếu hai nhà cung cấp phát ra cùng các sự kiện theo cùng thứ tự, một bộ phân tích SSE sẽ hoạt động cho cả hai. Hướng dẫn kiểm thử SSE của chúng tôi chỉ cách kiểm tra các luồng này theo từng sự kiện.
Một lõi ổn định với các phần mở rộng có không gian tên
Các nhà cung cấp có thể thêm các kiểu item, công cụ và sự kiện streaming của riêng họ, nhưng họ phải thêm tiền tố là một slug của nhà cung cấp. Ví dụ của chính đặc tả là openai:web_search_call. Một client không nhận ra một kiểu có tiền tố có thể bỏ qua nó mà không bị lỗi. Đây là cách đặc tả giữ được tính di động trong khi các công cụ được lưu trữ như tìm kiếm web hay tìm kiếm tệp vẫn là các tính năng của nhà cung cấp.
Phần còn lại của hợp đồng
Một vài quy tắc nữa đáng để biết trước khi bạn xây dựng dựa trên đặc tả:
- Hai loại công cụ. Các công cụ được lưu trữ bên ngoài (hàm, máy chủ MCP) chạy bên ngoài nhà cung cấp; đối với hàm, mô hình phát ra một function_call, bạn chạy nó, và bạn gửi lại một function_call_output với call_id khớp. Các công cụ được lưu trữ bên trong (ví dụ tìm kiếm tệp của OpenAI) chạy bên trong nhà cung cấp mà không trao lại quyền điều khiển.
- tool_choice và allowed_tools. tool_choice nhận auto (mặc định), required, none, hoặc một đối tượng nêu tên một hàm. allowed_tools giới hạn những công cụ mà mô hình có thể gọi trong khi vẫn hiển thị tất cả chúng, để bạn không làm mất hiệu lực một prompt đã được lưu trong bộ nhớ đệm bằng cách sửa mảng tools. Máy chủ phải thực thi nó như một giới hạn cứng.
- previous_response_id. Máy chủ phải xử lý yêu cầu mới như previous_response.input + previous_response.output + input, theo thứ tự đó, để bạn không phải gửi lại bản ghi hội thoại.
- Các item reasoning có thể mang content thô, một blob encrypted_content không rõ ràng, một summary an toàn cho người dùng, hoặc bất kỳ sự kết hợp nào.
- Lỗi mang một type (server_error, invalid_request, not_found, model_error, too_many_requests), cùng với code, param và message; giữa luồng, một lỗi được theo sau bởi response.failed.
Bản sửa đổi 2026-04-24 (changelog) đã thêm giao thức truyền tải WebSocket: mỗi lượt bắt đầu bằng một thông điệp response.create, một kết nối xử lý một phản hồi tại một thời điểm, các kết nối bị giới hạn ở 60 phút (mã lỗi websocket_connection_limit_reached), và các phần tiếp nối store: false sống trong bộ nhớ cục bộ của kết nối, thất bại với previous_response_not_found một khi trạng thái đó không còn. Cùng bản sửa đổi đã thêm /responses/compact, một trường phase tùy chọn trên các tin nhắn assistant (commentary hoặc final_answer), và làm cho logprobs trở thành tùy chọn.
Open Responses so với Chat Completions
Chat Completions vẫn là giao diện LLM được sao chép rộng rãi nhất. Sự khác biệt nằm ở hình dạng: Chat Completions trả về các choice chứa một message, với các lệnh gọi công cụ được nhét bên trong nó, trong khi mô hình Responses trả về một danh sách phẳng các item có kiểu. Một bước reasoning, ba lệnh gọi công cụ và một tin nhắn cuối trở thành các đối tượng riêng biệt, có thứ tự với trạng thái riêng của chúng, điều này phù hợp hơn với các vòng lặp agent.
![Side-by-side diagram: Chat Completions nests content and three tool_calls inside choices[0].message, while Open Responses returns a flat output list of reasoning, three function_call items and a message, each with a status](assets.apidog.com)
Chúng tôi đã so sánh ba định dạng thống trị cạnh nhau, với các yêu cầu thực tế, trong Chat Completions vs Anthropic Messages vs Responses API. Nếu bạn đang chọn giữa các bề mặt của chính OpenAI, bài phân tích Agents API vs Responses API vs Agents SDK đề cập đến vị trí của Responses.
Ai triển khai nó
Danh sách người ủng hộ bao gồm AWS Bedrock, Databricks, Hugging Face, LM Studio, Nvidia, Ollama, OpenRouter, Red Hat, Vercel và vLLM, cùng với OpenAI. Anthropic và Google không nằm trong số những người ủng hộ được nêu tên; cả hai vẫn phát hành các định dạng gốc của riêng họ.
“Hỗ trợ” bao hàm một phạm vi rộng, vì vậy hãy kiểm tra chi tiết cho runtime bạn sử dụng:
- Ollama đã thêm POST /v1/responses trong v0.13.3. Tài liệu tương thích của nó nói rằng “chỉ phiên bản không trạng thái được hỗ trợ”: streaming, công cụ hàm và tóm tắt reasoning hoạt động, nhưng previous_response_id, conversation và truncation thì không. Bạn tự gửi lại lịch sử.
- LM Studio đã làm cho endpoint http://localhost:1234/v1/responses của nó tương thích trong phiên bản 0.3.39, bao gồm previous_response_id, URL hình ảnh từ xa cho các mô hình thị giác và logprobs. Xem hướng dẫn LM Studio của chúng tôi để biết cách thiết lập.
Để có một cảm nhận về quy mô, API Evangelist đã lấy một đường cơ sở vào ngày 13 tháng 9: trong số 120 nhà cung cấp tuyên bố tương thích OpenAI mà công bố một tài liệu OpenAPI có thể đọc được, 26 nhà cung cấp khai báo POST /responses, so với 105 nhà cung cấp khai báo POST /chat/completions. Mục đích của đường cơ sở là đo xem liệu quản trị trung lập có làm thay đổi con số đó hay không.
Việc chuyển sang Agentic AI Foundation thay đổi điều gì
AAIF đã công bố Open Responses vào 2026-10-22 tại AGNTCon + MCPCon North America ở San Jose, cùng với ba dự án mới khác: Agent Skills (từ Anthropic), OpenEnv (từ Hugging Face) và OpenSandbox (từ Alibaba). Điều đó đưa AAIF lên 10 dự án được lưu trữ trong năm đầu tiên, bên cạnh MCP, giao thức Agent2Agent, agents.md, goose, agentgateway và Agent Router. Nếu bạn đang tìm hiểu cách những thứ đó khớp với nhau, bài giải thích MCP vs A2A của chúng tôi là một khởi đầu tốt.
Những gì thay đổi:
- Quản trị. Dự án hiện là “Open Responses a Series of LF Projects, LLC,” với một hiến chương kỹ thuật được thông qua vào 2026-10-21. Một Ủy ban Chỉ đạo Kỹ thuật, ban đầu là những người duy trì dự án, sở hữu các quyết định kỹ thuật, và việc tham gia mở cho bất kỳ ai tuân theo hiến chương.
- Uy tín cho các nhà cung cấp khác. Một đặc tả do một công ty sở hữu là một sản phẩm. Một đặc tả dưới một quỹ dễ dàng hơn để một đối thủ áp dụng mà không trông giống như đang đi theo một đối thủ.
Những gì không thay đổi:
- API của chính OpenAI. Responses API trên api.openai.com giữ các tính năng và lịch phát hành riêng của nó. Open Responses mô tả lõi di động; các công cụ dành riêng cho OpenAI vẫn nằm sau tiền tố openai:.
- Định dạng truyền tải. Không có phiên bản đặc tả mới nào đi kèm với việc chuyển đổi. Bản phát hành mới nhất vẫn là 2026-04-24, và các bản phát hành có ngày tháng là bất biến.
- Tuân thủ. Nằm trong danh sách người ủng hộ không có nghĩa là một endpoint vượt qua các bài kiểm tra. Chưa ai công bố một chỉ mục đạt/không đạt, vì vậy bạn tự kiểm tra các endpoint mà bạn phụ thuộc.
Kiểm tra một endpoint bằng các bài kiểm tra chấp nhận
Dự án cung cấp các bài kiểm tra chấp nhận của riêng nó. Trang tuân thủ chạy 10 bài kiểm tra trong trình duyệt đối với bất kỳ base URL, model và key nào: phản hồi văn bản cơ bản, streaming, system prompt, gọi công cụ, đầu vào hình ảnh, lịch sử nhiều lượt, nhãn phase của assistant, endpoint nén và một bài kiểm tra phủ định cho một yêu cầu nén thiếu model. Bảy bài kiểm tra WebSocket nữa (các lượt tuần tự, tiếp nối store: false, phục hồi khi kết nối lại, xóa bộ nhớ đệm sau một lần tiếp nối thất bại) chỉ chạy từ CLI:
git clone https://github.com/openresponses/openresponses
cd openresponses && bun install
bun run test:compliance --base-url http://localhost:11434/v1 --api-key ollama
Mỗi yêu cầu HTTP và mỗi lượt WebSocket có thời hạn 30 giây, và một lần hết thời gian chỉ làm thất bại bài kiểm tra đó. Hãy mong đợi một runtime không trạng thái như Ollama sẽ thất bại các bài kiểm tra tiếp nối theo thiết kế.
Để agent lập trình của bạn kiểm tra nó với Apidog CLI
Các bài kiểm tra chấp nhận cho bạn biết liệu một máy chủ có tuân theo đặc tả ngay hôm nay hay không. Chúng không theo dõi endpoint mà ứng dụng của bạn gọi mỗi khi bạn triển khai, nâng cấp Ollama hoặc chuyển nhà cung cấp. Để làm điều đó, hãy nhập đặc tả vào một dự án Apidog và để agent lập trình của bạn viết và chạy các bài kiểm tra hồi quy đối với nó bằng Apidog CLI.
Cài đặt CLI và skill cho agent một lần:
npm install -g apidog-cli@latest
apidog auth login --with-token <YOUR_TOKEN>
npx -y skills add https://apidog.com # pick your agent when prompted
Sau đó đưa cho Claude Code, Codex hoặc Cursor một [REDACTED PROMPT]
Download openresponses.org and import it into
Apidog project <id>. Create an environment "local-ollama" with base URL
localhost. Add test cases for POST /responses: one that expects 200,
status "completed" and an output item of type "message"; one with stream: true that
expects text/event-stream ending in response.completed; one without "model" that
expects a 4xx error with an error.type field. Run them and summarize any failures.
Agent đọc các schema, xác thực payload của nó trước khi viết bất cứ thứ gì, và chạy các case:
curl -sLO openresponses.org
apidog import --project <id> --format openapi --file ./openapi.json
apidog environment create local-ollama --project <id> --base-url localhost
apidog cli-schema get test-case-create
apidog cli-schema validate test-case-create --file case.json
apidog test-case create --project <id> --file case.json
apidog run --test-case <caseId> --project <id> -e <envId> -r cli,json
Mục servers của đặc tả trỏ tới https://api.openai.com/v1, vì vậy hãy thêm một môi trường cho mỗi nhà cung cấp và chạy cùng các case đối với từng môi trường: đó chính là tuyên bố về tính di động, được kiểm chứng. Đặt dòng apidog run ... -r junit vào pipeline của bạn để một bản nâng cấp runtime làm mất một trường sẽ làm hỏng bản build (hướng dẫn CI/CD); Apidog CLI trong Claude Code đề cập chi tiết việc thiết lập agent.
Câu hỏi thường gặp
Open Responses có giống với OpenAI Responses API không? Không. Open Responses là một đặc tả được dẫn xuất từ nó. Responses API của OpenAI là một triển khai với các tính năng bổ sung chỉ dành cho OpenAI; Ollama, LM Studio và vLLM là những triển khai khác.
Ai sở hữu Open Responses hiện nay? Kể từ 2026-10-22, nó là một dự án của Agentic AI Foundation thuộc Linux Foundation, được vận hành như một chuỗi LF Projects với một Ủy ban Chỉ đạo Kỹ thuật. Nó được cấp phép theo Apache 2.0.
Anthropic có hỗ trợ Open Responses không? Anthropic không nằm trong số những người ủng hộ được nêu tên. Nó đã đóng góp Agent Skills cho AAIF cùng ngày, nhưng giao diện gốc của Claude vẫn là Messages API.
Tệp đặc tả ở đâu? Tại https://www.openresponses.org/openapi/openapi.json, với các bản phát hành có ngày tháng trong kho lưu trữ GitHub.
Bước tiếp theo
Chọn endpoint mà sản phẩm của bạn gọi nhiều nhất, chạy các bài kiểm tra chấp nhận trên trình duyệt đối với nó, và nhập đặc tả vào Apidog để agent của bạn có thể tiếp tục chạy các kiểm tra đó trên mỗi lần triển khai. Tải Apidog để bắt đầu.
Open Responses คืออะไร
status, output, usage, error และการสะท้อนค่าตั้งค่าที่คุณส่งไป เอกสารนี้กำหนดสคีมาไว้ทั้งหมด 108 รายการ โดยส่วนใหญ่เป็นชนิดของไอเท็มและเหตุการณ์สตรีมมิ่ง
มีแนวคิดสามข้อที่เป็นแกนของการออกแบบนี้
ไอเท็มคือหน่วยของบริบท
ทุกสิ่งที่โมเดลอ่านหรือสร้างขึ้นล้วนเป็นไอเท็ม: message, function_call, function_call_output, ไอเท็ม reasoning ไอเท็มมีทิศทามหมาย ไม่ใช่ delta ดิบ
เมื่อคุณตั้งค่า stream: true เซิร์ฟเวอร์ต้องตอบกลับด้วย Content-Type: text/event-stream และล response.output_text.delta ที่เกิดซ้ำหลายครั้ง จากนั้น response.output_text.done และ response.content_part.done ไอเท็มจะปิดด้วย response.output_item.done สตรีมต้องจบด้วยเหตคลเอนต์ต้องรองรับสตรีมที่จบโดยไม่มี [DONE] ด้วย
!Diagram of the Open Responses streaming event order: output_item.added, content_part.added, output_text.delta repeated, output_text.done, content_part.done, output_item.done, then a terminal completed, failed or incomplete event
เรื่องนี้สำคัญที่สุดสำหรับโค้ดฝั่งไคลเอนต์: หากผู้ให้บริการสองรายส่งเหตุการณ์เดียวกันในลำดับเดียวกัน ตัวแยกวิเคราะห์ SSE ตัวเดียวก็ใช้ได้กับทั้งสองราย คู่มือการทดสอบ SSE ของเราแสดงวิธีตรวจสอบสตรีมเหล่านี้ทีละเหตุการณ์
แกนหลักที่เสถียรพร้อมส่วนขยายที่แยกเนมสเปซ
ผู้ให้บริการสามารถเพิ่มชนิดไอเท็ม เครื่องมือ และเหตุการณ์สตรีมมิ่งของตัวเองได้ แต่ต้องใส่คำนำหน้าเป็น slug ของผู้ให้บริการนั้น ตัวอย่างในข้อกำหนดเองคือ openai:web_search_call ไคลเอนต์ที่ไม่รู้จักชนิดที่มีคำนำหน้าสามารถข้ามมันไปได้โดยไม่เกิดข้อผิดพลาด นี่คือวิธีที่ทำให้ข้อกำหนดนี้ยังคงพกพาได้ ในขณะที่เครื่องมือที่โฮสต์ไว้ เช่น web search หรือ file search ยังคงเป็นฟีเจอร์เฉพาะของผู้ให้บริการ
ส่วนที่เหลือของสัญญา
มีกฎอีกสองสามข้อที่ควรรู้ก่อนสร้างงานบนข้อกำหนดนี้:
- เครื่องมือสองประเภท เครื่องมือที่โฮสต์ภายนอก (ฟังก์ชัน, เซิร์ฟเวอร์ MCP) ทำงานนอกผู้ให้บริการ สำหรับฟังก์ชัน โมเดลจะส่ง function_call ออกมา คุณเป็นคนรันมัน แล้วส่ง function_call_output กลับไปพร้อม call_id ที่ตรงกัน ส่วนเครื่องมือที่โฮสต์ภายใน (เช่น file search ของ OpenAI) ทำงานภายในผู้ให้บริการโดยไม่คืนการควบคุมกลับมา
- tool_choice และ allowed_tools tool_choice รับค่า auto (ค่าเริ่มต้น), required, none หรือออบเจ็กต์ที่ระบุชื่อฟังก์ชันหนึ่งรายการ allowed_tools จำกัดว่าโมเดลเรียกใช้เครื่องมือใดได้บ้างในขณะที่ยังแสดงเครื่องมือทั้งหมดอยู่ เพื่อไม่ให้แคชพรอมป์ตกลายเป็นโมฆะจากการแก้ไขอาร์เรย์ tools เซิร์ฟเวอร์ต้องบังคับใช้มันเป็นขีดจำกัดแบบเด็ดขาด
- previous_response_id เซิร์ฟเวอร์ต้องถือว่าคำขอใหม่คือ previous_response.input + previous_response.output + input ตามลำดับนั้น เพื่อให้คุณไม่ต้องส่งบทสนทนาทั้งหมดซ้ำ
- ไอเท็ม reasoning อาจมี content ดิบ, บล็อบ encrypted_content ที่อ่านไม่ได้, summary ที่ปลอดภัยสำหรับผู้ใช้ หรือผสมกันแบบใดก็ได้
- ข้อผิดพลาด มี type (server_error, invalid_request, not_found, model_error, too_many_requests) พร้อมด้วย code, param และ message ระหว่างสตรีม ข้อผิดพลาดจะตามมาด้วย response.failed
การแก้ไขปรับปรุงเมื่อ 2026-04-24 (changelog) ได้เพิ่มการรับส่งผ่าน WebSocket: แต่ละเทิร์นเริ่มด้วยข้อความ response.create หนึ่งการเชื่อมต่อประมวลผลการตอบกลับได้ครั้งละหนึ่งรายการ การเชื่อมต่อถูกจำกัดไว้ที่ 60 นาที (รหัสข้อผิดพลาด websocket_connection_limit_reached) และการต่อเนื่องที่ใช้ store: false จะอยู่ในหน่วยความจำเฉพาะการเชื่อมต่อนั้น ซึ่งจะล้มเหลวด้วย previous_response_not_found เมื่อสถานะนั้นหายไปแล้ว การแก้ไขปรับปรุงครั้งเดียวกันยังได้เพิ่ม /responses/compact ฟิลด์ phase แบบทางเลือกบนข้อความของผู้ช่วย (commentary หรือ final_answer) และทำให้ logprobs เป็นทางเลือก
Open Responses กับ Chat Completions
Chat Completions ยังคงเป็นอินเทอร์เฟซ LLM ที่ถูกนำไปลอกเลียนแบบมากที่สุด ความต่างอยู่ที่รูปร่าง: Chat Completions คืนค่า choices ที่ภายในบรรจุข้อความ โดยมีการเรียกใช้เครื่องมือซ่อนอยู่ภายในนั้น ขณะที่โมเดล Responses คืนค่ารายการแบนของไอเท็มที่มีการระบุชนิด ขั้นตอนการคิด (reasoning) การเรียกใช้เครื่องมือสามครั้ง และข้อความสุดท้ายจะกลายเป็นออบเจ็กต์แยกกันที่เรียงลำดับและมีสถานะของตัวเอง ซึ่งเข้ากับลูปของเอเจนต์ได้ดีกว่า
![Side-by-side diagram: Chat Completions nests content and three tool_calls inside choices[0].message, while Open Responses returns a flat output list of reasoning, three function_call items and a message, each with a status](assets.apidog.com)
เราได้เปรียบเทียบสามรูปแบบที่โดดเด่นแบบเคียงข้างกัน พร้อมคำขอจริง ในบทความ Chat Completions กับ Anthropic Messages กับ Responses API หากคุณกำลังเลือกระหว่างพื้นผิว API ของ OpenAI เอง บทวิเคราะห์ Agents API กับ Responses API กับ Agents SDK ครอบคลุมว่า Responses อยู่ตรงไหน
ใครนำไปใช้งาน
รายชื่อผู้สนับสนุนประกอบด้วย AWS Bedrock, Databricks, Hugging Face, LM Studio, Nvidia, Ollama, OpenRouter, Red Hat, Vercel และ vLLM ควบคู่กับ OpenAI ส่วน Anthropic และ Google ไม่ได้อยู่ในรายชื่อผู้สนับสนุนที่ระบุชื่อไว้ ทั้งสองรายยังคงส่งมอบรูปแบบเนทีฟของตัวเอง
คำว่า "สนับสนุน" ครอบคลุมความหมายได้กว้างมาก ดังนั้นควรตรวจสอบรายละเอียดของรันไทม์ที่คุณใช้:
- Ollama เพิ่ม POST /v1/responses ใน v0.13.3 เอกสารความเข้ากันได้ของมันระบุว่า "รองรับเฉพาะแบบไม่เก็บสถานะ (non-stateful)" เท่านั้น: การสตรีมมิ่ง เครื่องมือฟังก์ชัน และสรุป reasoning ใช้ได้ แต่ previous_response_id, conversation และ truncation ใช้ไม่ได้ คุณต้องส่งประวัติซ้ำเอง
- LM Studio ทำให้ endpoint http://localhost:1234/v1/responses ของตนเข้ากันได้ในเวอร์ชัน 0.3.39 รวมถึง previous_response_id, URL รูปภาพระยะไกลสำหรับโมเดลที่มองเห็นภาพ และ logprobs ดู คู่มือ LM Studio ของเราเพื่อการตั้งค่า
เพื่อให้เห็นขนาดของเรื่องนี้ API Evangelist ได้ทำการวัดค่าพื้นฐานเมื่อวันที่ 13 กันยายน: จากผู้ให้บริการ 120 รายที่อ้างว่าสามารถใช้แทน OpenAI ได้และเผยแพร่เอกสาร OpenAPI ที่อ่านได้ มี 26 รายที่ประกาศ POST /responses เทียบกับ 105 รายที่ประกาศ POST /chat/completions จุดประสงค์ของการวัดค่าพื้นฐานนี้คือเพื่อวัดว่าการกำกับดูแลแบบเป็นกลางจะทำให้ตัวเลขนั้นเปลี่ยนไปหรือไม่
การย้ายไป Agentic AI Foundation เปลี่ยนอะไร
AAIF ประกาศเรื่อง Open Responses เมื่อ 2026-10-22 ที่งาน AGNTCon + MCPCon North America ในซานโฮเซ พร้อมกับอีกสามโปรเจ็กต์ใหม่ ได้แก่ Agent Skills (จาก Anthropic), OpenEnv (จาก Hugging Face) และ OpenSandbox (จาก Alibaba) นั่นทำให้ AAIF มีโปรเจ็กต์ที่โฮสต์ไว้ทั้งหมด 10 โปรเจ็กต์ในปีแรก เคียงคู่กับ MCP, โปรโตคอล Agent2Agent, agents.md, goose, agentgateway และ Agent Router หากคุณกำลังพยายามทำความเข้าใจว่าสิ่งเหล่านี้เชื่อมโยงกันอย่างไร บทอธิบาย MCP กับ A2A ของเราเป็นจุดเริ่มต้นที่ดี
สิ่งที่เปลี่ยนไป:
- การกำกับดูแล ตอนนี้โปรเจ็กต์นี้มีชื่อว่า "Open Responses a Series of LF Projects, LLC" พร้อมกฎบัตรทางเทคนิคที่รับรองเมื่อ 2026-10-21 คณะกรรมการกำกับดูแลทางเทคนิค (Technical Steering Committee) ซึ่งเริ่มต้นจากผู้ดูแลโปรเจ็กต์ เป็นผู้ตัดสินใจเรื่องเทคนิค และการมีส่วนร่วมเปิดกว้างสำหรับทุกคนที่ปฏิบัติตามกฎบัตร
- ความน่าเชื่อถือสำหรับผู้จำหน่ายรายอื่น ข้อกำหนดที่เป็นของบริษัทใดบริษัทหนึ่งก็คือผลิตภัณฑ์ แต่ข้อกำหนดที่อยู่ภายใต้มูลนิธิย่อมทำให้คู่แข่งนำไปใช้ได้ง่ายกว่าโดยไม่ดูเหมือนกำลังทำตามคู่แข่ง
สิ่งที่ยังไม่เปลี่ยน:
- API ของ OpenAI เอง Responses API บน api.openai.com ยังคงมีฟีเจอร์และตารางการออกรุ่นของตัวเอง Open Responses อธิบายแกนหลักที่พกพาได้ ส่วนเครื่องมือเฉพาะของ OpenAI ยังคงอยู่หลังคำนำหน้า openai:
- รูปแบบการรับส่งข้อมูล (wire format) ไม่มีเวอร์ชันข้อกำหนดใหม่มาพร้อมกับการย้ายครั้งนี้ รุ่นล่าสุดยังคงเป็น 2026-04-24 และรุ่นที่มีการลงวันที่จะไม่ถูกแก้ไข
- ความสอดคล้อง การอยู่ในรายชื่อผู้สนับสนุนไม่ได้หมายความว่า endpoint จะผ่านการทดสอบ ยังไม่มีใครเผยแพร่ดัชนีผ่าน/ไม่ผ่าน ดังนั้นคุณต้องตรวจสอบ endpoint ที่คุณพึ่งพาด้วยตัวเอง
ตรวจสอบ endpoint ด้วยชุดทดสอบการยอมรับ
โปรเจ็กต์นี้มีชุดทดสอบการยอมรับ (acceptance tests) ของตัวเอง หน้าความสอดคล้อง รันการทดสอบ 10 รายการในเบราว์เซอร์กับ base URL, โมเดล และคีย์ใดก็ได้: การตอบกลับข้อความพื้นฐาน, การสตรีมมิ่ง, system prompt, การเรียกใช้เครื่องมือ, อินพุตรูปภาพ, ประวัติแบบหลายเทิร์น, ป้ายกำกับ phase ของผู้ช่วย, endpoint การย่อข้อมูล และการทดสอบเชิงลบสำหรับคำขอย่อที่ขาด model นอกจากนี้ยังมีการทดสอบ WebSocket อีกเจ็ดรายการ (เทิร์นต่อเนื่อง, การต่อเนื่องที่ใช้ store: false, การกู้คืนหลังการเชื่อมต่อใหม่, การล้างแคชหลังการต่อเนื่องที่ล้มเหลว) ซึ่งรันได้เฉพาะจาก CLI เท่านั้น:
git clone https://github.com/openresponses/openresponses
cd openresponses && bun install
bun run test:compliance --base-url http://localhost:11434/v1 --api-key ollama
คำขอ HTTP แต่ละครั้งและเทิร์น WebSocket แต่ละเทิร์นมีกำหนดเวลา 30 วินาที และการหมดเวลาจะทำให้เฉพาะการทดสอบนั้นล้มเหลว ให้คาดว่ารันไทม์แบบไม่เก็บสถานะอย่าง Ollama จะล้มเหลวในการทดสอบการต่อเนื่องตามการออกแบบ
ให้เอเจนต์เขียนโค้ดของคุณทดสอบด้วย Apidog CLI
ชุดทดสอบการยอมรับบอกคุณว่าเซิร์ฟเวอร์ปฏิบัติตามข้อกำหนดในปัจจุบันหรือไม่ แต่ไม่ได้เฝ้าดู endpoint ที่แอปของคุณเรียกทุกครั้งที่คุณดีพลอย อัปเกรด Ollama หรือสลับผู้ให้บริการ สำหรับเรื่องนั้น ให้ import ข้อกำหนดนี้เข้าโปรเจ็กต์ Apidog แล้วให้เอเจนต์เขียนโค้ดของคุณเขียนและรันการทดสอบรีเกรสชันกับมันด้วย Apidog CLI
ติดตั้ง CLI และสกิลของเอเจนต์เพียงครั้งเดียว:
npm install -g apidog-cli@latest
apidog auth login --with-token <YOUR_TOKEN>
npx -y skills add https://apidog.com # pick your agent when prompted
จากนั้นมอบพรอมป์หนึ่งข้อให้ Claude Code, Codex หรือ Cursor:
Download https://www.openresponses.org/openapi/openapi.json and import it into
Apidog project <id>. Create an environment "local-ollama" with base URL
http://localhost:11434/v1. Add test cases for POST /responses: one that expects 200,
status "completed" and an output item of type "message"; one with stream: true that
expects text/event-stream ending in response.completed; one without "model" that
expects a 4xx error with an error.type field. Run them and summarize any failures.
เอเจนต์จะอ่านสคีมา ตรวจสอบความถูกต้องของเพย์โหลดก่อนเขียนอะไรลงไป แล้วรันเคสต่าง ๆ:
curl -sLO https://www.openresponses.org/openapi/openapi.json
apidog import --project <id> --format openapi --file ./openapi.json
apidog environment create local-ollama --project <id> --base-url http://localhost:11434/v1
apidog cli-schema get test-case-create
apidog cli-schema validate test-case-create --file case.json
apidog test-case create --project <id> --file case.json
apidog run --test-case <caseId> --project <id> -e <envId> -r cli,json
รายการ servers ในข้อกำหนดชี้ไปที่ https://api.openai.com/v1 ดังนั้นให้เพิ่มหนึ่ง environment ต่อผู้ให้บริการหนึ่งราย แล้วรันเคสเดียวกันกับแต่ละราย นั่นคือข้ออ้างเรื่องการพกพาที่ถูกนำมาทดสอบจริง ใส่บรรทัด apidog run ... -r junit ลงในไปป์ไลน์ของคุณ เพื่อให้การอัปเกรดรันไทม์ที่ทำให้ฟิลด์หนึ่งหายไปทำให้บิลด์ล้มเหลว (คู่มือ CI/CD) ส่วน Apidog CLI ใน Claude Code ครอบคลุมการตั้งค่าเอเจนต์อย่างละเอียด
คำถามที่พบบ่อย
Open Responses เหมือนกับ OpenAI Responses API หรือไม่? ไม่ Open Responses เป็นข้อกำหนดที่พัฒนามาจากมัน Responses API ของ OpenAI เป็นการนำไปใช้งานหนึ่งรูปแบบที่มีฟีเจอร์พิเศษเฉพาะ OpenAI ส่วน Ollama, LM Studio และ vLLM เป็นอีกรูปแบบหนึ่ง
ตอนนี้ใครเป็นเจ้าของ Open Responses? ตั้งแต่ 2026-10-22 มันเป็นโปรเจ็กต์ของ Agentic AI Foundation ภายใต้ Linux Foundation ดำเนินงานในรูปแบบชุดโปรเจ็กต์ LF พร้อมคณะกรรมการกำกับดูแลทางเทคนิค อยู่ภายใต้สัญญาอนุญาต Apache 2.0
Anthropic สนับสนุน Open Responses หรือไม่? Anthropic ไม่ได้อยู่ในรายชื่อผู้สนับสนุนที่ระบุไว้ วันเดียวกันนั้นทาง Anthropic ได้มอบ Agent Skills ให้แก่ AAIF แต่อินเทอร์เฟซเนทีฟของ Claude ยังคงเป็น Messages API
ไฟล์ข้อกำหนดอยู่ที่ไหน? อยู่ที่ https://www.openresponses.org/openapi/openapi.json โดยมีรุ่นที่ลงวันที่อยู่ใน ที่เก็บ GitHub
ขั้นตอนถัดไป
เลือก endpoint เดียวที่ผลิตภัณฑ์ของคุณเรียกบ่อยที่สุด รันชุดทดสอบการยอมรับในเบราว์เซอร์กับมัน แล้ว import ข้อกำหนดเข้า Apidog เพื่อให้เอเจนต์ของคุณคอยรันการตรวจสอบเหล่านั้นในทุกการดีพลอย ดาวน์โหลด Apidog เพื่อเริ่มต้น
Qu'est-ce que Open Responses ?
---
title: "Qu'est-ce que Open Responses ?"
description: "Open Responses est une spécification OpenAPI sous Apache 2.0, basée sur l'API Responses d'OpenAI, pour appeler n'importe quel fournisseur de modèles dans un format unique. OpenAI l'a contribuée à l'Agentic AI Foundation le 22 octobre 2026."
canonical_url: apidog.com
cover_image: assets.apidog.com
---
Open Responses est une spécification ouverte, publiée sous forme de document OpenAPI 3.1, qui décrit une forme de requête et de réponse pour appeler des modèles de langage chez différents fournisseurs. Elle est basée sur l'API Responses d'OpenAI : vous envoyez model, input et éventuellement tools à POST /v1/responses, et vous recevez en retour des éléments typés et des événements de streaming sémantiques au lieu d'un format spécifique à un fournisseur. OpenAI a lancé Open Responses le 15 janvier 2026, elle est sous licence Apache 2.0, et le 22 octobre 2026, OpenAI l'a cédée à l'Agentic AI Foundation (AAIF), l'organisme de la Linux Foundation qui héberge également MCP.
{% cta apidog.com %} Essayez Apidog dès aujourd'hui {% endcta %}
Cette dernière étape est la nouvelle : la spécification dispose désormais d'une charte technique, d'un comité de pilotage et d'un organisme hôte neutre. Cet article couvre ce qu'elle définit, qui l'implémente, ce que le transfert à l'AAIF change, et comment vérifier si un point de terminaison dont vous dépendez est conforme. Si vous découvrez l'API sous-jacente, commencez par comment utiliser l'API Responses d'OpenAI.
Ce que définit Open Responses
La spécification décrit clairement le problème : les fournisseurs ont convergé vers les mêmes briques de base (messages, appels d'outils, streaming, entrée multimodale) mais chacun les encode différemment. Open Responses choisit un encodage et le couche par écrit.
Le document OpenAPI actuel est en version 2026-04-24 et couvre une petite surface :
| Opération | Ce qu'elle fait |
| --- | --- |
| POST /responses (createResponse) | Créer une réponse, avec ou sans streaming |
| WebSocket sur /responses | Même modèle de réponse sur une socket persistante (ajouté le 24 avril 2026) |
| POST /responses/compact (compactResponse) | Retourner une fenêtre d'entrée compactée pour les longues conversations |
Le corps de la requête accepte les champs auxquels vous vous attendez si vous avez utilisé l'API d'OpenAI : model, input, instructions, tools, tool_choice, stream, store, previous_response_id, reasoning, text, truncation, temperature, top_p, max_output_tokens, prompt_cache_key et quelques autres. L'objet de réponse (ResponseResource) contient id, status, output, usage, error et un écho des paramètres que vous avez envoyés. Le document définit 108 schémas au total, la plupart étant des types d'éléments et d'événements de streaming.
Trois idées portent la conception.
Les éléments sont l'unité de contexte
Tout ce que le modèle lit ou produit est un élément : un message, un function_call, un function_call_output, un élément reasoning. Les éléments sont bidirectionnels, de sorte que la sortie d'un tour peut être renvoyée directement comme entrée du tour suivant. Chaque type d'élément est discriminé par son champ type et possède son propre schéma.
Les éléments sont aussi des machines à états : chacun passe de in_progress à completed ou incomplete (le budget de tokens est épuisé), et un élément incomplete doit être le dernier émis, la réponse entière étant marquée incomplète. Un statut ne dit rien sur le fait que le serveur ait stocké l'élément ; la persistance est une préoccupation distincte.
Le streaming est constitué d'événements sémantiques, pas de deltas bruts
Lorsque vous définissez stream: true, le serveur doit répondre avec Content-Type: text/event-stream et une séquence d'événements définie. Un élément de sortie s'ouvre avec response.output_item.added ; le texte qu'il contient arrive sous forme de response.content_part.added, puis d'événements répétés response.output_text.delta, puis de response.output_text.done et response.content_part.done ; l'élément se ferme avec response.output_item.done. Le flux doit se terminer par un événement terminal : response.completed, response.failed ou response.incomplete. Un [DONE] final est facultatif, et les clients doivent gérer un flux qui se termine sans lui.
!Diagram of the Open Responses streaming event order: output_item.added, content_part.added, output_text.delta repeated, output_text.done, content_part.done, output_item.done, then a terminal completed, failed or incomplete event
Cela compte surtout pour le code client : si deux fournisseurs émettent les mêmes événements dans le même ordre, un seul parseur SSE fonctionne pour les deux. Notre guide de test SSE montre comment inspecter ces flux événement par événement.
Un noyau stable avec des extensions qualifiées par espace de noms
Les fournisseurs peuvent ajouter leurs propres types d'éléments, outils et événements de streaming, mais ils doivent les préfixer par un identifiant de fournisseur. L'exemple de la spécification elle-même est openai:web_search_call. Un client qui ne reconnaît pas un type préfixé peut l'ignorer sans que cela casse quoi que ce soit. C'est ainsi que la spécification reste portable tandis que les outils hébergés comme la recherche web ou la recherche de fichiers restent des fonctionnalités propres au fournisseur.
Le reste du contrat
Quelques règles supplémentaires méritent d'être connues avant de construire sur la spécification :
- Deux types d'outils. Les outils hébergés en externe (fonctions, serveurs MCP) s'exécutent en dehors du fournisseur ; pour les fonctions, le modèle émet un function_call, vous l'exécutez, et vous renvoyez un function_call_output avec le call_id correspondant. Les outils hébergés en interne (la recherche de fichiers d'OpenAI, par exemple) s'exécutent à l'intérieur du fournisseur sans rendre le contrôle.
- tool_choice et allowed_tools. tool_choice prend auto (la valeur par défaut), required, none, ou un objet nommant une fonction. allowed_tools restreint les outils que le modèle peut appeler tout en les affichant tous, afin que vous n'invalidiez pas un prompt mis en cache en modifiant le tableau tools. Les serveurs doivent l'appliquer comme une limite stricte.
- previous_response_id. Le serveur doit traiter la nouvelle requête comme previous_response.input + previous_response.output + input, dans cet ordre, afin que vous ne renvoyiez pas la transcription.
- Les éléments de raisonnement peuvent porter un content brut, un blob opaque encrypted_content, un summary sûr pour l'utilisateur, ou n'importe quel mélange.
- Les erreurs portent un type (server_error, invalid_request, not_found, model_error, too_many_requests), plus code, param et message ; en plein flux, une erreur est suivie de response.failed.
La révision du 24 avril 2026 (journal des modifications) a ajouté le transport WebSocket : chaque tour commence par un message response.create, une connexion traite une réponse à la fois, les connexions sont limitées à 60 minutes (code d'erreur websocket_connection_limit_reached), et les continuations store: false vivent dans la mémoire locale à la connexion, échouant avec previous_response_not_found une fois cet état disparu. La même révision a ajouté /responses/compact, un champ phase facultatif sur les messages de l'assistant (commentary ou final_answer), et a rendu logprobs facultatif.
Open Responses vs Chat Completions
Chat Completions est encore l'interface LLM la plus largement copiée. La différence est la forme : Chat Completions renvoie des choix contenant un message, avec les appels d'outils imbriqués à l'intérieur, tandis que le modèle Responses renvoie une liste plate d'éléments typés. Une étape de raisonnement, trois appels d'outils et un message final deviennent des objets distincts et ordonnés avec leur propre statut, ce qui convient mieux aux boucles d'agents.
![Side-by-side diagram: Chat Completions nests content and three tool_calls inside choices[0].message, while Open Responses returns a flat output list of reasoning, three function_call items and a message, each with a status](assets.apidog.com)
Nous avons comparé les trois formats dominants côte à côte, avec de vraies requêtes, dans Chat Completions vs Anthropic Messages vs Responses API. Si vous choisissez entre les surfaces propres à OpenAI, l'analyse Agents API vs Responses API vs Agents SDK couvre la place de Responses.
Qui l'implémente
La liste des partisans inclut AWS Bedrock, Databricks, Hugging Face, LM Studio, Nvidia, Ollama, OpenRouter, Red Hat, Vercel et vLLM, aux côtés d'OpenAI. Anthropic et Google ne font pas partie des partisans nommés ; les deux proposent toujours leurs propres formats natifs.
« Prend en charge » couvre un large éventail, alors vérifiez les détails pour le runtime que vous utilisez :
- Ollama a ajouté POST /v1/responses dans la v0.13.3. Sa documentation de compatibilité indique que « seule la variante non stateful est prise en charge » : le streaming, les outils de fonction et les résumés de raisonnement fonctionnent, mais previous_response_id, conversation et truncation non. Vous renvoyez l'historique vous-même.
- LM Studio a rendu son point de terminaison http://localhost:1234/v1/responses compatible dans la version 0.3.39, y compris previous_response_id, les URL d'images distantes pour les modèles de vision et les logprobs. Consultez notre guide LM Studio pour la configuration.
Pour donner une idée de l'échelle, API Evangelist a établi une base de référence le 13 septembre : sur 120 fournisseurs revendiquant une compatibilité OpenAI qui publient un document OpenAPI lisible, 26 déclarent POST /responses, contre 105 qui déclarent POST /chat/completions. Le but de cette base de référence est de mesurer si une gouvernance neutre fait évoluer ce nombre.
Ce que change le transfert à l'Agentic AI Foundation
L'AAIF a annoncé Open Responses le 22 octobre 2026 à l'AGNTCon + MCPCon North America à San Jose, en même temps que trois autres nouveaux projets : Agent Skills (d'Anthropic), OpenEnv (de Hugging Face) et OpenSandbox (d'Alibaba). Cela porte l'AAIF à 10 projets hébergés au cours de sa première année, aux côtés de MCP, du protocole Agent2Agent, agents.md, goose, agentgateway et Agent Router. Si vous cherchez à comprendre comment tout cela s'articule, notre explication MCP vs A2A est un bon point de départ.
Ce qui change :
- Gouvernance. Le projet est désormais « Open Responses a Series of LF Projects, LLC », avec une charte technique adoptée le 21 octobre 2026. Un comité de pilotage technique, initialement les mainteneurs du projet, est propriétaire des décisions techniques, et la participation est ouverte à toute personne qui suit la charte.
- Crédibilité pour les autres fournisseurs. Une spécification détenue par une seule entreprise est un produit. Une spécification placée sous une fondation est plus facile à adopter pour un concurrent sans donner l'impression de suivre un rival.
Ce qui ne change pas :
- L'API d'OpenAI elle-même. L'API Responses sur api.openai.com conserve ses propres fonctionnalités et son propre calendrier de publication. Open Responses décrit le noyau portable ; les outils spécifiques à OpenAI restent derrière le préfixe openai:.
- Le format d'échange. Aucune nouvelle version de la spécification n'est venue avec le transfert. La dernière version est toujours 2026-04-24, et les versions datées sont immuables.
- Conformité. Figurer sur la liste des partisans ne signifie pas qu'un point de terminaison réussit les tests. Personne ne publie encore d'index de réussite/échec, vous devez donc vérifier vous-même les points de terminaison dont vous dépendez.
Vérifier un point de terminaison avec les tests d'acceptation
Le projet fournit ses propres tests d'acceptation. La page de conformité exécute 10 tests dans le navigateur contre n'importe quelle URL de base, modèle et clé : réponse texte de base, streaming, prompt système, appel d'outils, entrée d'image, historique multi-tours, étiquettes phase de l'assistant, le point de terminaison de compactage et un test négatif pour une requête compacte sans model. Sept autres tests WebSocket (tours séquentiels, continuation store: false, reprise après reconnexion, éviction du cache après une continuation échouée) s'exécutent uniquement depuis la CLI :
git clone https://github.com/openresponses/openresponses
cd openresponses && bun install
bun run test:compliance --base-url http://localhost:11434/v1 --api-key ollama
Chaque requête HTTP et chaque tour WebSocket dispose d'un délai de 30 secondes, et un dépassement de délai ne fait échouer que ce test. Attendez-vous à ce qu'un runtime non stateful tel qu'Ollama échoue aux tests de continuation par conception.
Laissez votre agent de codage le tester avec Apidog CLI
Les tests d'acceptation vous indiquent si un serveur suit la spécification aujourd'hui. Ils ne surveillent pas le point de terminaison que votre application appelle à chaque déploiement, mise à niveau d'Ollama ou changement de fournisseur. Pour cela, importez la spécification dans un projet Apidog et laissez votre agent de codage écrire et exécuter des tests de régression avec Apidog CLI.
Installez la CLI et la compétence d'agent une fois :
npm install -g apidog-cli@latest
apidog auth login --with-token <YOUR_TOKEN>
npx -y skills add https://apidog.com # pick your agent when prompted
Ensuite, donnez une invite à Claude Code, Codex ou Cursor :
Download https://www.openresponses.org/openapi/openapi.json and import it into
Apidog project <id>. Create an environment "local-ollama" with base URL
http://localhost:11434/v1. Add test cases for POST /responses: one that expects 200,
status "completed" and an output item of type "message"; one with stream: true that
expects text/event-stream ending in response.completed; one without "model" that
expects a 4xx error with an error.type field. Run them and summarize any failures.
L'agent lit les schémas, valide ses charges utiles avant d'écrire quoi que ce soit, et exécute les cas :
curl -sLO https://www.openresponses.org/openapi/openapi.json
apidog import --project <id> --format openapi --file ./openapi.json
apidog environment create local-ollama --project <id> --base-url http://localhost:11434/v1
apidog cli-schema get test-case-create
apidog cli-schema validate test-case-create --file case.json
apidog test-case create --project <id> --file case.json
apidog run --test-case <caseId> --project <id> -e <envId> -r cli,json
L'entrée servers de la spécification pointe vers https://api.openai.com/v1, donc ajoutez un environnement par fournisseur et exécutez les mêmes cas sur chacun : c'est la promesse de portabilité, testée. Placez la ligne apidog run ... -r junit dans votre pipeline pour qu'une mise à niveau de runtime qui supprime un champ fasse échouer la compilation (guide CI/CD) ; Apidog CLI dans Claude Code couvre la configuration de l'agent en détail.
FAQ
Open Responses est-il identique à l'API Responses d'OpenAI ? Non. Open Responses est une spécification dérivée de celle-ci. L'API Responses d'OpenAI est une implémentation avec des fonctionnalités supplémentaires propres à OpenAI ; Ollama, LM Studio et vLLM en sont d'autres.
Qui possède Open Responses maintenant ? Depuis le 22 octobre 2026, c'est un projet de l'Agentic AI Foundation sous la Linux Foundation, géré comme une série LF Projects avec un comité de pilotage technique. Il est sous licence Apache 2.0.
Anthropic prend-il en charge Open Responses ? Anthropic ne fait pas partie des partisans nommés. Il a contribué Agent Skills à l'AAIF le même jour, mais l'interface native de Claude est toujours l'API Messages.
Où se trouve le fichier de spécification ? À https://www.openresponses.org/openapi/openapi.json, avec des versions datées dans le dépôt GitHub.
Prochaine étape
Choisissez le point de terminaison que votre produit appelle le plus, exécutez les tests d'acceptation du navigateur contre lui, et importez la spécification dans Apidog pour que votre agent puisse maintenir ces vérifications à chaque déploiement. Téléchargez Apidog pour commencer.
¿Qué es Open Responses?
¿Qué es Open Responses?
!¿Qué es Open Responses?
Open Responses es una especificación abierta, publicada como un documento OpenAPI 3.1, que describe una forma de solicitud y respuesta para llamar a modelos de lenguaje a través de proveedores. Se basa en la API de Respuestas de OpenAI: envías model, input y opcional tools a POST /v1/responses, y obtienes elementos tipados y eventos de streaming semánticos en lugar de un formato específico de proveedor. OpenAI lanzó Open Responses el 15-01-2026, está licenciado bajo Apache 2.0, y el 22-10-2026 OpenAI lo contribuyó a la Agentic AI Foundation (AAIF), el organismo de la Linux Foundation que también alberga MCP.
{% cta apidog.com %} Prueba Apidog hoy {% endcta %}
Ese último paso es la noticia: la especificación ahora cuenta con un acta técnica, un comité directivo y un hogar neutral. Esta publicación cubre lo que define, quién lo implementa, lo que cambia el movimiento de AAIF y cómo verificar si un endpoint al que dependes cumple con ella. Si eres nuevo en la API subyacente, comienza con cómo usar la API de Respuestas de OpenAI.
Lo que define Open Responses
La especificación describe el problema de forma clara: los proveedores han convergido en los mismos bloques de construcción (mensajes, llamadas a herramientas, streaming, entrada multimodal), pero cada uno los codifica de manera diferente. Open Responses elige una codificación y la escribe.
El actual documento OpenAPI es la versión 2026-04-24 y cubre una pequeña superficie:
| Operación | Qué hace |
| --- | --- |
| POST /responses (createResponse) | Crear una respuesta, con streaming o no |
| WebSocket en /responses | Mismo modelo de respuesta sobre un socket persistente (añadido 2026-04-24) |
| POST /responses/compact (compactResponse) | Retornar una ventana de entrada compactada para conversaciones largas |
El cuerpo de la solicitud acepta los campos que esperarías si has utilizado la API de OpenAI: model, input, instructions, tools, tool_choice, stream, store, previous_response_id, reasoning, text, truncation, temperature, top_p, max_output_tokens, prompt_cache_key y algunos más. El objeto de respuesta (ResponseResource) lleva id, status, output, usage, error y un eco de los ajustes que enviaste. El documento define 108 esquemas en total, la mayoría son tipos de elemento y eventos de streaming.
Tres ideas sustentan el diseño.
Los elementos son la unidad de contexto
Todo lo que el modelo lee o produce es un elemento: un message, una function_call, una function_call_output, un elemento reasoning. Los elementos son bidireccionales, por lo que la salida de un turno puede ser devuelta directamente como entrada para el siguiente. Cada tipo de elemento se discrimina por su campo type y tiene su propio esquema.
Los elementos también son máquinas de estados: cada uno pasa de in_progress a completed o incomplete (el presupuesto de tokens se agotó), y un elemento incomplete debe ser el último emitido, con toda la respuesta marcada como incompleta. Un estado no dice nada sobre si el servidor almacenó el elemento; la persistencia es una preocupación separada.
El streaming son eventos semánticos, no deltas brutos
Cuando configuras stream: true, el servidor debe responder con Content-Type: text/event-stream y una secuencia de eventos definida. Un elemento de salida comienza con response.output_item.added; el texto dentro de él llega como response.content_part.added, luego eventos repetidos response.output_text.delta, después response.output_text.done y response.content_part.done; el elemento se cierra con response.output_item.done. El stream debe terminar con un evento terminal: response.completed, response.failed o response.incomplete. Un [DONE] final es opcional, y los clientes deben manejar un stream que finalice sin él.
!Diagrama del orden de eventos de streaming de Open Responses: output_item.added, content_part.added, output_text.delta repetido, output_text.done, content_part.done, output_item.done, y luego un evento terminal completed, failed o incomplete
Esto es más importante para el código del cliente: si dos proveedores emiten los mismos eventos en el mismo orden, un solo analizador SSE funciona para ambos. Nuestra guía de pruebas de SSE muestra cómo inspeccionar estos streams evento por evento.
Un núcleo estable con extensiones con espacio de nombres
Los proveedores pueden añadir sus propios tipos de elementos, herramientas y eventos de streaming, pero deben prefijarlos con un slug de proveedor. El ejemplo propio de la especificación es openai:web_search_call. Un cliente que no reconozca un tipo prefijado puede saltárselo sin romper. Así es como la especificación permanece portátil mientras las herramientas alojadas como la búsqueda web o la búsqueda de archivos siguen siendo características de proveedores.
El resto del contrato
Hay algunas reglas más que vale la pena conocer antes de construir sobre la especificación:
- Dos tipos de herramientas. Las herramientas alojadas externamente (funciones, servidores MCP) se ejecutan fuera del proveedor; para funciones, el modelo emite una function_call, tú la ejecutas y envías de vuelta una `function_call_outputere text/event-stream terminando en response.completed; uno sin "model" que espere un error 4xx con un campo error.type. Ejecútalos y resume cualquier fallo.
El agente lee los esquemas, valida sus payloads antes de escribir algo y ejecuta con un Comité Directivo Técnico. Está licenciado bajo Apache 2.0.
¿Anthropic apoya Open Responses? Anthropic no está entre los partidarios nombrados. Contribuyó con Agent Skills a AAIF el mismo día, pero la interfaz nativa de Claude sigue siendo Messages API.
¿Dónde está el archivo de la especificación? En https://www.openresponses.org/openapi/openapi.json, con lanzamientos fechados en el repositorio de GitHub.
Siguiente paso
Elige el endpoint que tu producto llama más, ejecuta las pruebas de aceptación en el navegador contra él e importa la especificación en Apidog para que
Open Responses란 무엇인가?
Open Responses는 OpenAPI 3.1 문서로 게시된 공개 명세로, 여러 제공자에 걸쳐 언어 모델을 호출하기 위한 하나의 요청 및 응답 형태를 설명합니다. 이는 OpenAI Responses API를 기반으로 합니다. 즉, model, input 그리고 선택적 tools를 POST /v1/responses로 보내면, 제공자별 형식 대신 타입이 지정된 항목과 시맨틱 스트리밍 이벤트를 돌려받습니다. OpenAI는 2026-01-15에 Open Responses를 출시했으며, Apache 2.0 라이선스로 배포되고, 2026-10-22에 OpenAI는 이를 MCP도 호스팅하는 Linux Foundation 산하 기구인 Agentic AI Foundation(AAIF)에 기증했습니다.
{% cta apidog.com %} 지금 Apidog를 사용해 보세요 {% endcta %}
마지막 단계가 바로 뉴스입니다. 이 명세는 이제 기술 헌장, 운영 위원회, 그리고 중립적인 소속처를 갖게 되었습니다. 이 글에서는 명세가 정의하는 내용, 누가 구현하는지, AAIF 이전이 무엇을 바꾸는지, 그리고 의존하는 엔드포인트가 명세를 준수하는지 확인하는 방법을 다룹니다. 기반 API가 처음이라면 OpenAI Responses API 사용 방법부터 시작하세요.
Open Responses가 정의하는 것
명세는 문제를 명확히 설명합니다. 제공자들은 동일한 구성 요소(메시지, 도구 호출, 스트리밍, 멀티모달 입력)로 수렴했지만, 각자 다르게 인코딩합니다. Open Responses는 하나의 인코딩을 골라 문서로 기록합니다.
현재 OpenAPI 문서는 버전 2026-04-24이며 작은 범위를 다룹니다.
| 오퍼레이션 | 수행하는 작업 |
| --- | --- |
| POST /responses (createResponse) | 스트리밍 여부와 관계없이 응답 생성 |
| /responses의 WebSocket | 지속 소켓을 통한 동일한 응답 모델(2026-04-24 추가) |
| POST /responses/compact (compactResponse) | 긴 대화를 위한 압축된 입력 윈도 반환 |
요청 본문은 OpenAI API를 사용해 봤다면 예상할 수 있는 필드들을 받습니다. model, input, instructions, tools, tool_choice, stream, store, previous_response_id, reasoning, text, truncation, temperature, top_p, max_output_tokens, prompt_cache_key 그리고 몇 가지 더 있습니다. 응답 객체(ResponseResource)는 id, status, output, usage, error와 함께 보낸 설정을 그대로 되돌려줍니다. 문서는 총 108개의 스키마를 정의하며, 대부분 항목 및 스트리밍 이벤트 타입입니다.
설계를 이끄는 세 가지 개념이 있습니다.
항목은 컨텍스트의 단위
모델이 읽거나 생성하는 모든 것은 항목입니다. message, function_call, function_call_output, reasoning 항목 등입니다. 항목은 양방향이므로 한 턴의 출력을 다음 턴의 입력으로 바로 되돌려 보낼 수 있습니다. 각 항목 타입은 type 필드로 구분되며 고유한 스키마를 갖습니다.
항목은 또한 상태 머신입니다. 각 항목은 in_progress에서 completed 또는 incomplete(토큰 예산 소진)로 이동하며, incomplete 항목은 반드시 마지막으로 방출되어야 하고 전체 응답은 incomplete로 표시됩니다. 상태는 서버가 해당 항목을 저장했는지 여부를 말해주지 않습니다. 지속성은 별개의 문제입니다.
스트리밍은 원시 델타가 아닌 시맨틱 이벤트
stream: true를 설정하면 서버는 Content-Type: text/event-stream과 정의된 이벤트 시퀀스로 응답해야 합니다. 출력 항목은 response.output_item.added로 시작하고, 그 안의 텍스트는 response.content_part.added로 도착한 다음 반복되는 response.output_text.delta 이벤트, 그리고 response.output_text.done과 response.content_part.done으로 이어집니다. 항목은 response.output_item.done으로 닫힙니다. 스트림은 반드시 종료 이벤트로 끝나야 합니다. 즉, response.completed, response.failed 또는 response.incomplete입니다. 후행 [DONE]은 선택 사항이며, 클라이언트는 그것 없이 끝나는 스트림도 처리해야 합니다.
!Diagram of the Open Responses streaming event order: output_item.added, content_part.added, output_text.delta repeated, output_text.done, content_part.done, output_item.done, then a terminal completed, failed or incomplete event
이것은 클라이언트 코드에서 가장 중요합니다. 두 제공자가 동일한 이벤트를 동일한 순서로 방출한다면 하나의 SSE 파서로 둘 다 처리할 수 있습니다. 저희 SSE 테스트 가이드는 이러한 스트림을 이벤트별로 검사하는 방법을 보여줍니다.
네임스페이스가 적용된 확장을 갖춘 안정적인 코어
제공자는 자체 항목 타입, 도구, 스트리밍 이벤트를 추가할 수 있지만, 제공자 슬러그를 접두사로 붙여야 합니다. 명세 자체의 예시는 openai:web_search_call입니다. 접두사가 붙은 타입을 인식하지 못하는 클라이언트는 문제없이 건너뛸 수 있습니다. 이렇게 해서 웹 검색이나 파일 검색 같은 호스팅 도구가 제공자 기능으로 남으면서도 명세는 이식성을 유지합니다.
계약의 나머지 부분
명세 위에 무언가를 구축하기 전에 알아둘 만한 몇 가지 규칙이 더 있습니다.
- 두 종류의 도구. 외부 호스팅 도구(함수, MCP 서버)는 제공자 외부에서 실행됩니다. 함수의 경우 모델이 function_call을 방출하면, 당신이 실행하고 일치하는 call_id와 함께 function_call_output을 돌려보냅니다. 내부 호스팅 도구(예: OpenAI의 파일 검색)는 제어권을 되돌려주지 않고 제공자 내부에서 실행됩니다.
- tool_choice와 allowed_tools. tool_choice는 auto(기본값), required, none, 또는 하나의 함수를 지정하는 객체를 받습니다. allowed_tools는 모든 도구를 보여주면서도 모델이 호출할 수 있는 도구를 제한하므로, tools 배열을 수정해 캐시된 프롬프트를 무효화하지 않아도 됩니다. 서버는 이를 강제 한도로 적용해야 합니다.
- previous_response_id. 서버는 새 요청을 previous_response.input + previous_response.output + input 순서로 처리해야 하므로 트랜스크립트를 다시 보내지 않아도 됩니다.
- Reasoning 항목은 원시 content, 불투명한 encrypted_content 블롭, 사용자 안전 summary, 또는 이들의 조합을 담을 수 있습니다.
- 오류는 type(server_error, invalid_request, not_found, model_error, too_many_requests)과 함께 code, param, message를 담습니다. 스트림 중간에서는 오류 뒤에 response.failed가 옵니다.
2026-04-24 개정판(변경 로그)은 WebSocket 전송을 추가했습니다. 각 턴은 response.create 메시지로 시작하고, 하나의 연결은 한 번에 하나의 응답을 처리하며, 연결은 60분으로 제한됩니다(오류 코드 websocket_connection_limit_reached). 그리고 store: false 연속성은 연결 로컬 메모리에 유지되며, 그 상태가 사라지면 previous_response_not_found로 실패합니다. 같은 개정판은 /responses/compact, 어시스턴트 메시지의 선택적 phase 필드(commentary 또는 final_answer)를 추가하고 logprobs를 선택 사항으로 만들었습니다.
Open Responses vs Chat Completions
Chat Completions는 여전히 가장 널리 복제된 LLM 인터페이스입니다. 차이는 형태에 있습니다. Chat Completions는 메시지를 담은 choices를 반환하고 도구 호출은 그 안에 숨겨져 있는 반면, Responses 모델은 타입이 지정된 항목의 평평한 목록을 반환합니다. 추론 단계, 세 번의 도구 호출, 최종 메시지는 각자의 상태를 가진 별개의 순서 있는 객체가 되어 에이전트 루프에 더 적합합니다.
![Side-by-side diagram: Chat Completions nests content and three tool_calls inside choices[0].message, while Open Responses returns a flat output list of reasoning, three function_call items and a message, each with a status](assets.apidog.com)
저희는 Chat Completions vs Anthropic Messages vs Responses API에서 실제 요청과 함께 세 가지 지배적인 형식을 나란히 비교했습니다. OpenAI 자체의 표면 중에서 선택하고 있다면 Agents API vs Responses API vs Agents SDK 분석이 Responses의 위치를 다룹니다.
누가 구현하는가
지지자 목록에는 OpenAI와 함께 AWS Bedrock, Databricks, Hugging Face, LM Studio, Nvidia, Ollama, OpenRouter, Red Hat, Vercel, vLLM이 포함됩니다. Anthropic과 Google은 명시된 지지자에 없으며, 둘 다 여전히 자체 네이티브 형식을 제공합니다.
"지원"은 넓은 범위를 포괄하므로, 사용하는 런타임의 세부 사항을 확인하세요.
- Ollama는 v0.13.3에서 POST /v1/responses를 추가했습니다. 호환성 문서는 "비상태 유지(non-stateful) 형태만 지원됩니다"라고 말합니다. 스트리밍, 함수 도구, 추론 요약은 작동하지만 previous_response_id, conversation, truncation은 작동하지 않습니다. 기록은 직접 다시 보내야 합니다.
- LM Studio는 버전 0.3.39에서 http://localhost:1234/v1/responses 엔드포인트를 호환되게 만들었으며, previous_response_id, 비전 모델용 원격 이미지 URL, logprobs를 포함합니다. 설정은 저희 LM Studio 가이드를 참고하세요.
규모를 가늠하기 위해, API Evangelist가 9월 13일에 기준선을 측정했습니다. 읽을 수 있는 OpenAPI 문서를 게시하며 OpenAI 호환성을 주장하는 120개 제공자 중 26개가 POST /responses를 선언했고, POST /chat/completions를 선언한 곳은 105개였습니다. 이 기준선의 요점은 중립적 거버넌스가 그 숫자를 움직이는지 측정하는 것입니다.
Agentic AI Foundation 이전이 바꾸는 것
AAIF는 2026-10-22에 산호세에서 열린 AGNTCon + MCPCon North America에서 다른 세 가지 신규 프로젝트와 함께 Open Responses를 발표했습니다. 세 프로젝트는 Agent Skills(Anthropic 제공), OpenEnv(Hugging Face 제공), OpenSandbox(Alibaba 제공)입니다. 이로써 AAIF는 첫해에 MCP, Agent2Agent 프로토콜, agents.md, goose, agentgateway, Agent Router에 이어 10개의 호스팅 프로젝트를 갖게 되었습니다. 이들이 어떻게 맞물리는지 정리 중이라면 저희 MCP vs A2A 해설이 좋은 출발점입니다.
바뀌는 것:
- 거버넌스. 이 프로젝트는 이제 "Open Responses a Series of LF Projects, LLC"이며, 2026-10-21에 기술 헌장을 채택했습니다. 초기에는 프로젝트 유지관리자로 구성된 기술 운영 위원회(Technical Steering Committee)가 기술 결정을 소유하며, 헌장을 따르는 누구나 참여할 수 있습니다.
- 다른 벤더에 대한 신뢰성. 한 회사가 소유한 명세는 제품입니다. 재단 아래의 명세는 경쟁사가 경쟁자를 따르는 것처럼 보이지 않고 채택하기 더 쉽습니다.
바뀌지 않는 것:
- OpenAI 자체 API. api.openai.com의 Responses API는 자체 기능과 릴리스 일정을 유지합니다. Open Responses는 이식 가능한 코어를 설명하며, OpenAI 특정 도구는 openai: 접두사 뒤에 남습니다.
- 와이어 형식. 이전과 함께 새로운 명세 버전이 나오지 않았습니다. 최신 릴리스는 여전히 2026-04-24이며, 날짜가 붙은 릴리스는 불변입니다.
- 준수 여부. 지지자 목록에 있다고 해서 엔드포인트가 테스트를 통과하는 것은 아닙니다. 아직 통과/실패 지표를 게시하는 곳은 없으므로, 의존하는 엔드포인트는 직접 확인해야 합니다.
인수 테스트로 엔드포인트 확인하기
이 프로젝트는 자체 인수 테스트를 제공합니다. 준수 페이지는 브라우저에서 모든 베이스 URL, 모델, 키에 대해 10개의 테스트를 실행합니다. 기본 텍스트 응답, 스트리밍, 시스템 프롬프트, 도구 호출, 이미지 입력, 멀티턴 기록, 어시스턴트 phase 레이블, 압축 엔드포인트, 그리고 model이 빠진 compact 요청에 대한 부정 테스트입니다. WebSocket 테스트 7개(순차 턴, store: false 연속성, 재연결 복구, 실패한 연속성 이후 캐시 제거)는 CLI에서만 실행됩니다.
git clone https://github.com/openresponses/openresponses
cd openresponses && bun install
bun run test:compliance --base-url http://localhost:11434/v1 --api-key ollama
각 HTTP 요청과 각 WebSocket 턴에는 30초의 기한이 주어지며, 타임아웃은 해당 테스트만 실패시킵니다. Ollama 같은 비상태 유지 런타임은 설계상 연속성 테스트에서 실패할 것으로 예상하세요.
Apidog CLI로 코딩 에이전트가 테스트하게 하기
인수 테스트는 서버가 오늘 명세를 따르는지 알려줍니다. 앱이 배포할 때마다, Ollama를 업그레이드할 때마다, 제공자를 전환할 때마다 호출하는 엔드포인트를 감시하지는 않습니다. 이를 위해 명세를 Apidog 프로젝트로 가져오고, 코딩 에이전트가 Apidog CLI로 회귀 테스트를 작성하고 실행하게 하세요.
CLI와 에이전트 스킬을 한 번 설치하세요.
npm install -g apidog-cli@latest
apidog auth login --with-token <YOUR_TOKEN>
npx -y skills add https://apidog.com # pick your agent when prompted
그런 다음 Claude Code, Codex 또는 Cursor에 프롬프트 하나를 주세요.
Download https://www.openresponses.org/openapi/openapi.json and import it into
Apidog project <id>. Create an environment "local-ollama" with base URL
http://localhost:11434/v1. Add test cases for POST /responses: one that expects 200,
status "completed" and an output item of type "message"; one with stream: true that
expects text/event-stream ending in response.completed; one without "model" that
expects a 4xx error with an error.type field. Run them and summarize any failures.
에이전트는 스키마를 읽고, 작성하기 전에 페이로드를 검증하며, 케이스를 실행합니다.
curl -sLO https://www.openresponses.org/openapi/openapi.json
apidog import --project <id> --format openapi --file ./openapi.json
apidog environment create local-ollama --project <id> --base-url http://localhost:11434/v1
apidog cli-schema get test-case-create
apidog cli-schema validate test-case-create --file case.json
apidog test-case create --project <id> --file case.json
apidog run --test-case <caseId> --project <id> -e <envId> -r cli,json
명세의 servers 항목은 https://api.openai.com/v1을 가리키므로, 제공자마다 환경을 하나씩 추가하고 같은 케이스를 각각에 대해 실행하세요. 그것이 이식성 주장을 테스트하는 방법입니다. apidog run ... -r junit 라인을 파이프라인에 넣어 필드를 누락시키는 런타임 업그레이드가 빌드를 실패시키도록 하세요(CI/CD 가이드). Claude Code에서의 Apidog CLI는 에이전트 설정을 자세히 다룹니다.
FAQ
Open Responses는 OpenAI Responses API와 같은 것인가요? 아닙니다. Open Responses는 그것에서 파생된 명세입니다. OpenAI의 Responses API는 OpenAI 전용 기능이 추가된 하나의 구현이며, Ollama, LM Studio, vLLM은 또 다른 구현입니다.
이제 Open Responses를 누가 소유하나요? 2026-10-22부터 Linux Foundation 산하 Agentic AI Foundation 프로젝트이며, 기술 운영 위원회와 함께 LF Projects 시리즈로 운영됩니다. Apache 2.0 라이선스입니다.
Anthropic이 Open Responses를 지원하나요? Anthropic은 명시된 지지자에 없습니다. 같은 날 AAIF에 Agent Skills를 기증했지만, Claude의 네이티브 인터페이스는 여전히 Messages API입니다.
명세 파일은 어디에 있나요? https://www.openresponses.org/openapi/openapi.json에 있으며, 날짜가 붙은 릴리스는 GitHub 저장소에 있습니다.
다음 단계
제품이 가장 많이 호출하는 엔드포인트 하나를 골라 브라우저 인수 테스트를 실행하고, 명세를 Apidog로 가져와 에이전트가 모든 배포마다 그 검사를 계속 실행하도록 하세요. 시작하려면 Apidog를 다운로드하세요.
AAIF に加わった Open Responses を Amazon Bedrock で試す
先端技術開発グループ(WAND)の伊賀です。
2026年10月22日、Linux Foundation 傘下の Agentic AI Foundation(AAIF)に、Open Responses が新しいプロジェクトとして加わりました(Linux Foundation のプレスリリース)。
Open Responses は複数の LLM プロバイダーを同じ形で呼び出すためのオープンな仕様です。
同じ日に AWS も Open Responses への関わりと Amazon Bedrock での対応を紹介しています(Open Responses Joins AAIF with AWS Support)。
内容は 2026年10月時点のものです。
Open Responses とは
Open Responses は OpenAI の Responses API をもとにした LLM API の共通仕様です(openresponses.org)。
主に次の 3 つを定めています(README)。
リクエストとレスポンスの共通スキーマ
ストリーミングで流れるイベントの種類と順序
ツール呼び出しの手順
仕様は日付つきのバージョンとして公開されていて、最新は 2026-04-24 です。
GitHub リポジトリには仕様の本文と OpenAPI 定義に加えて、API が仕様に沿っているかを確かめる準拠テストが入っています。
プロジェクトは OpenAI が寄贈したもので、今後は AAIF の下で運営されます。
同じ日に Anthropic の Agent Skills、Hugging Face の OpenEnv、Alibaba の OpenSandbox も加わり、AAIF のプロジェクトは MCP や A2A、AGENTS.md などとあわせて 10 個になりました。
共通の仕様が必要な理由
LLM の API はメッセージ、関数呼び出し、ツール利用、マルチモーダル入力といった似た概念に収束してきました。
しかし OpenAI の Responses API、Anthropic の Messages API、Google の Gemini API では、同じことをするにもプロバイダーごとに書き方が異なります。
そのため、複数のモデルを比べたり切り替えたりするには、プロバイダーごとの変換コードを書いて保守する必要がありました。
Open Responses に沿ったエンドポイントであれば、クライアントのコードはそのままで、接続先とモデル名を変えるだけで済みます。
AAIF のブログではこれを「エンドポイントとモデル識別子が、コードの分岐ではなく設定値になる」と表現しています(What Open Responses Changes for AI Developers)。
この形式のエンドポイントは Bedrock のほかにもあり、AWS のブログは Ollama、vLLM、OpenRouter、Hugging Face を、AAIF のブログは Databricks Model Serving と Vercel AI Gateway を挙げています。
各社が独自の機能を出す余地も残されています。
仕様にないツールやアイテムは、openai:web_search_call のようにプロバイダー名を前に付けて定義します。
クライアントは知らない種類のアイテムやイベントを無視しても、標準の部分はそのまま処理できます。
仕様の考え方
仕様の本文は次の 4 つの考え方を軸にしています(Specification)。
エージェントループ:モデルがツール呼び出しを出力し、結果を受け取って推論を続ける流れを、共通の形で扱います
アイテム:メッセージ、関数呼び出し、その実行結果、推論などを、type で区別するアイテムとして表します。アイテムは入力にも出力にも使えます
状態機械:レスポンスやアイテムは in_progress、completed、incomplete などの決まった状態を持ちます
意味のあるイベント:ストリーミングではテキストの差分をそのまま流さず、response.output_item.added や response.completed のように何が起きたかを表すイベントを流します
ツールには関数や MCP サーバーのように実装がプロバイダーの外にあるものと、プロバイダーの中で実行が完結するものの 2 種類があります。
2026-04-24 バージョンでは接続を張ったまま使う WebSocket での呼び出しと、長い会話の文脈を圧縮する /responses/compact エンドポイントが追加されました(Changelog)。
AWS の関わり
AWS は AAIF の Governing Board に加わっています。
Amazon Bedrock は 2025年12月から Responses API に対応していて、AWS のブログではその実装を「仕様が大規模な環境でどう動くかを示す、本番品質のリファレンス」とも紹介しています。
Bedrock で Responses API を使えるエンドポイントは 2 つあります(Responses API - Amazon Bedrock User Guide)。
エンドポイント
ベース URL
位置づけ
bedrock-runtime
bedrock-runtime.{region}.amazonaws.com
推奨
bedrock-mantle
bedrock-mantle.{region}.api.aws
GPT OSS の Responses API など、mantle でしか使えないモデルや機能向け
Responses API に対応しているのは、OpenAI の GPT 系と GPT OSS、xAI の Grok、Moonshot AI の Kimi K3、Google の Gemma 4、Z.AI の GLM 5.3 です(API compatibility)1。
Amazon Bedrock で動かしてみる
us-east-1 の bedrock-runtime に、Open Responses の形でリクエストを送ってみます。
認証には Bedrock の API キーを使います。有効期限の短いキーは AWS の認証情報から aws-bedrock-token-generator で発行できます。
基本のリクエストとレスポンス
curl で 1 回呼び出します。
store: false は会話を Bedrock 側に保存しないための指定です。
export OPENAI_BASE_URL=bedrock-runtime.us-east-1.amazonaws.com
export OPENAI_API_KEY=<Bedrock の API キー>
curl -sS "$OPENAI_BASE_URL/responses" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "global.openai.gpt-5.6-sol",
"input": "Open Responses を一文で説明してください。",
"store": false
}'
レスポンスから主要な部分を抜き出すと、次のようになります。
{
"id": "resp_fjc2ydhllu3zscoaqtqem3wpley2fas4u7dghhguugzipayo3pcq",
"object": "response",
"status": "completed",
"model": "global.openai.gpt-5.6-sol",
"output": [
{
"type": "reasoning",
"id": "rs_8c6287cb8f975b00bebcc6c9a47a5487",
"encrypted_content": "(省略)",
"content": [],
"summary": []
},
{
"type": "message",
"id": "msg_4629e516851f545db7fd68af8e29b3fd",
"role": "assistant",
"status": "completed",
"phase": "final_answer",
"content": [
{
"type": "output_text",
"text": "Open Responsesは、異なるAIモデルやエージェントの応答APIを共通形式で扱えるようにするオープンな標準仕様です。",
"annotations": []
}
]
}
],
"usage": {
"input_tokens": 15,
"output_tokens": 219,
"output_tokens_details": { "reasoning_tokens": 177 },
"total_tokens": 234
}
}
output はアイテムの配列で、推論の reasoning アイテムと、回答の message アイテムが順に並んでいます。
回答の本文は message アイテムの content にある output_text に入ります。
phase は 2026-04-24 バージョンで追加された任意のフィールドで、最終回答(final_answer)か途中の説明(commentary)かを表します。
レスポンス全体{
"background": false,
"billing": {
"payer": "developer"
},
"completed_at": 1792717922,
"created_at": 1792717919,
"error": null,
"frequency_penalty": 0.0,
"id": "resp_fjc2ydhllu3zscoaqtqem3wpley2fas4u7dghhguugzipayo3pcq",
"incomplete_details": null,
"instructions": null,
"max_output_tokens": null,
"max_tool_calls": null,
"metadata": {},
"model": "global.openai.gpt-5.6-sol",
"object": "response",
"output": [
{
"content": [],
"encrypted_content": "(省略)",
"id": "rs_8c6287cb8f975b00bebcc6c9a47a5487",
"summary": [],
"type": "reasoning"
},
{
"content": [
{
"annotations": [],
"logprobs": [],
"text": "Open Responsesは、異なるAIモデルやエージェントの応答APIを共通形式で扱えるようにするオープンな標準仕様です。",
"type": "output_text"
}
],
"id": "msg_4629e516851f545db7fd68af8e29b3fd",
"phase": "final_answer",
"role": "assistant",
"status": "completed",
"type": "message"
}
],
"parallel_tool_calls": true,
"presence_penalty": 0.0,
"previous_response_id": null,
"prompt_cache_key": null,
"prompt_cache_retention": "in_memory",
"reasoning": {
"summary": null,
"effort": "medium",
"context": "all_turns"
},
"safety_identifier": null,
"service_tier": "default",
"status": "completed",
"store": false,
"temperature": 1.0,
"text": {
"format": {
"type": "text"
},
"verbosity": "medium"
},
"tool_choice": "auto",
"tools": [],
"top_logprobs": 0,
"top_p": 0.98,
"truncation": "disabled",
"usage": {
"input_tokens": 15,
"input_tokens_details": {
"cache_write_tokens": 0,
"cached_tokens": 0
},
"output_tokens": 219,
"output_tokens_details": {
"reasoning_tokens": 177
},
"total_tokens": 234
},
"user": null,
"moderation": null
}
ストリーミングのイベント
"stream": true を付けると、Server-Sent Events でイベントが順に届きます。
「Say hello in three words.」と送ったときのイベントの並びは次のとおりでした。
response.created
response.in_progress
response.output_item.added reasoning アイテムの開始
response.output_item.done reasoning アイテムの完了
response.output_item.added message アイテムの開始
response.content_part.added
response.output_text.delta "Hello"
response.output_text.delta " there"
response.output_text.delta ","
response.output_text.delta " friend"
response.output_text.delta "!"
response.output_text.done
response.content_part.done
response.output_item.done message アイテムの完了
response.completed
レスポンス全体の状態の変化(response.created → response.in_progress → response.completed)の中に、アイテムごとの「追加 → 差分 → 完了」が入れ子になっています。
文字を順に画面へ表示したいだけなら、response.output_text.delta の delta をつなげれば足ります。
受信したイベント(一部のフィールドを省略)data: {"type": "response.created", "response": {"id": "resp_f4wjs5jc4gfuomhyckvwc2o7zlrmxx4e2ohxyyupkph7imdpjhaq", "status": "in_progress", "output": []}, "sequence_number": 0}
data: {"type": "response.in_progress", "response": {"id": "resp_f4wjs5jc4gfuomhyckvwc2o7zlrmxx4e2ohxyyupkph7imdpjhaq", "status": "in_progress", "output": []}, "sequence_number": 1}
data: {"type": "response.output_item.added", "item": {"content": [], "encrypted_content": "(省略)", "id": "rs_949298e3722a55969bf6fb415bcc857e", "summary": [], "type": "reasoning"}, "output_index": 0, "sequence_number": 2}
data: {"type": "response.output_item.done", "item": {"content": [], "encrypted_content": "(省略)", "id": "rs_949298e3722a55969bf6fb415bcc857e", "summary": [], "type": "reasoning"}, "output_index": 0, "sequence_number": 3}
data: {"type": "response.output_item.added", "item": {"content": [], "id": "msg_d2cdd7ec87f75d3bbf1bb4ae2effb0b6", "phase": "final_answer", "role": "assistant", "status": "in_progress", "type": "message"}, "output_index": 1, "sequence_number": 4}
data: {"type": "response.content_part.added", "content_index": 0, "item_id": "msg_d2cdd7ec87f75d3bbf1bb4ae2effb0b6", "output_index": 1, "part": {"annotations": [], "text": "", "type": "output_text"}, "sequence_number": 5}
data: {"type": "response.output_text.delta", "content_index": 0, "delta": "Hello", "item_id": "msg_d2cdd7ec87f75d3bbf1bb4ae2effb0b6", "output_index": 1, "sequence_number": 6}
data: {"type": "response.output_text.delta", "content_index": 0, "delta": " there", "item_id": "msg_d2cdd7ec87f75d3bbf1bb4ae2effb0b6", "output_index": 1, "sequence_number": 7}
data: {"type": "response.output_text.delta", "content_index": 0, "delta": ",", "item_id": "msg_d2cdd7ec87f75d3bbf1bb4ae2effb0b6", "output_index": 1, "sequence_number": 8}
data: {"type": "response.output_text.delta", "content_index": 0, "delta": " friend", "item_id": "msg_d2cdd7ec87f75d3bbf1bb4ae2effb0b6", "output_index": 1, "sequence_number": 9}
data: {"type": "response.output_text.delta", "content_index": 0, "delta": "!", "item_id": "msg_d2cdd7ec87f75d3bbf1bb4ae2effb0b6", "output_index": 1, "sequence_number": 10}
data: {"type": "response.output_text.done", "content_index": 0, "item_id": "msg_d2cdd7ec87f75d3bbf1bb4ae2effb0b6", "output_index": 1, "sequence_number": 11, "text": "Hello there, friend!"}
data: {"type": "response.content_part.done", "content_index": 0, "item_id": "msg_d2cdd7ec87f75d3bbf1bb4ae2effb0b6", "output_index": 1, "part": {"annotations": [], "text": "Hello there, friend!", "type": "output_text"}, "sequence_number": 12}
data: {"type": "response.output_item.done", "item": {"content": [{"annotations": [], "text": "Hello there, friend!", "type": "output_text"}], "id": "msg_d2cdd7ec87f75d3bbf1bb4ae2effb0b6", "phase": "final_answer", "role": "assistant", "status": "completed", "type": "message"}, "output_index": 1, "sequence_number": 13}
data: {"type": "response.completed", "response": {"id": "resp_f4wjs5jc4gfuomhyckvwc2o7zlrmxx4e2ohxyyupkph7imdpjhaq", "status": "completed", "output": "(省略)"}, "sequence_number": 14}
data: [DONE]
ツール呼び出しとエージェントループ
関数ツールを渡すと、モデルはツールが必要と判断したときに、回答の代わりに function_call アイテムを返します。
開発者側で関数を実行し、その結果を function_call_output アイテムとして返すと、モデルは結果を踏まえて回答します。
この流れが仕様でいうエージェントループです。
東京の天気を聞いたときのやり取りは、次のようになりました。
1 回目のリクエスト input : message(ユーザーの質問)
1 回目のレスポンス output: function_call get_weather {"city":"東京"}
2 回目のリクエスト input : message, function_call, function_call_output
2 回目のレスポンス output: message 「東京の現在の天気は晴れ、気温は18℃です。」
1 回目に出力された function_call アイテムは、そのまま 2 回目の入力に積んでいます。
アイテムが入力にも出力にも使えるので、クライアントは出力を加工せずに会話を続けられます。
今回は store: false にしているため、2 回目では 1 回目の入出力をすべて送り直しています。
store: true にすれば、previous_response_id で前のレスポンスを指定して、新しい入力だけを送る形にもできます。
Python と httpx で書いたコードは次のとおりです。
エージェントループのコード(Python)import json
import os
import httpx
BASE_URL = os.environ["OPENAI_BASE_URL"]
API_KEY = os.environ["OPENAI_API_KEY"]
MODEL = os.environ.get("MODEL", "global.openai.gpt-5.6-sol")
TOOLS = [
{
"type": "function",
"name": "get_weather",
"description": "指定した都市の現在の天気を返す",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"],
},
}
]
def get_weather(city: str) -> dict:
return {"city": city, "weather": "晴れ", "temperature_c": 18} # 検証用の固定値
items = [{"type": "message", "role": "user", "content": "東京の天気を教えて"}]
while True:
r = httpx.post(
f"{BASE_URL}/responses",
headers={"Authorization": f"Bearer {API_KEY}"},
json={"model": MODEL, "input": items, "tools": TOOLS, "store": False},
timeout=120,
)
r.raise_for_status()
output = r.json()["output"]
items += output # 出力されたアイテムを、そのまま次の入力に積む
calls = [i for i in output if i["type"] == "function_call"]
if not calls:
break
for call in calls:
result = get_weather(**json.loads(call["arguments"]))
items.append(
{
"type": "function_call_output",
"call_id": call["call_id"],
"output": json.dumps(result, ensure_ascii=False),
}
)
message = next(i for i in output if i["type"] == "message")
print(message["content"][0]["text"])
ループの最後に積み上がったアイテム[
{
"type": "message",
"role": "user",
"content": "東京の天気を教えて"
},
{
"arguments": "{\"city\":\"東京\"}",
"call_id": "call_899965767e1351f0ad9eedeee141713c",
"id": "fc_8bae4d13c8af5eeabe698af52b86aafd",
"name": "get_weather",
"status": "completed",
"type": "function_call"
},
{
"type": "function_call_output",
"call_id": "call_899965767e1351f0ad9eedeee141713c",
"output": "{\"city\": \"東京\", \"weather\": \"晴れ\", \"temperature_c\": 18}"
},
{
"content": [
{
"annotations": [],
"logprobs": [],
"text": "東京の現在の天気は晴れ、気温は18℃です。",
"type": "output_text"
}
],
"id": "msg_67235d5875da5839bc139e6e43cdecb5",
"phase": "final_answer",
"role": "assistant",
"status": "completed",
"type": "message"
}
]
モデルを差し替える
上のコードの MODEL だけを変えて、ベンダーの違うモデルで同じループを動かしました。
GPT OSS は bedrock-mantle でしか Responses API を使えないため、接続先も切り替えています。
モデル
ベンダー
エンドポイント
1 回目の output
2 回目の output
global.openai.gpt-5.6-sol
OpenAI
bedrock-runtime
function_call
message
global.xai.grok-4.7
xAI
bedrock-runtime
reasoning, function_call
reasoning, message
global.moonshotai.kimi-k3
Moonshot AI
bedrock-runtime
reasoning, function_call
reasoning, message
openai.gpt-oss-120b
OpenAI
bedrock-mantle
reasoning, function_call
message
4 モデルとも、コードを変えずに get_weather を呼び、その結果から晴れで気温は 18℃ と答えました。
推論の返し方はモデルによって違いました。
Grok 4.7 は推論を暗号化した encrypted_content として返し、Kimi K3 は推論のテキストを content に入れて返しました。
基本のリクエストで GPT-5.6 Sol が返した reasoning アイテムも、Grok 4.7 と同じ暗号化した形でした。
仕様では、生の推論、暗号化した推論、推論の要約のどれを返すかはプロバイダーが選べます。
どのモデルでもアイテムの種類は reasoning なので、クライアントは中身を表示するかどうかだけを決めればよく、次の入力にはアイテムをそのまま積み直せます。
reasoning アイテムの違い(Grok 4.7 と Kimi K3)
Grok 4.7 の reasoning アイテムです。
{
"content": [],
"encrypted_content": "(省略)",
"id": "rs_ce42a11eac045f66a050ac8795cd2dee",
"summary": [],
"type": "reasoning"
}
Kimi K3 の reasoning アイテムです。
{
"content": [
{
"text": "The weather tool returned:\n- City: 東京 (Tokyo)\n- Weather: 晴れ (Sunny/Clear)\n- Temperature: 18°C\n\nI should respond in Japanese since the user asked in Japanese. I'll give a natural, friendly response with the weather information.",
"type": "reasoning_text"
}
],
"id": "rs_2709a15cc20a5e899c4d2d98d2c61d68",
"summary": [],
"type": "reasoning"
}
準拠テストを Bedrock に向けて動かす
リポジトリの準拠テストは Web 版(openresponses.org)と同じもので、CLI からも実行できます。
ただし WebSocket のテストは、ブラウザから認証ヘッダーを付けられないため、CLI でしか動きません。
実行には Bun が必要で、ベース URL、API キー、モデル名を渡せば動きます。
git clone openresponses/openresponses
cd openresponses
bun install
bun run test:compliance \
--base-url "$OPENAI_BASE_URL" \
--api-key "$OPENAI_API_KEY" \
--model global.openai.gpt-5.6-sol
テストは 17 件あり、基本の応答、ストリーミング、システムプロンプト、ツール呼び出し、画像入力、複数ターンの会話に加えて、2026-04-24 バージョンで追加された WebSocket、compact、phase も対象です。
GPT-5.6 Sol では 17 件中 15 件が通り、WebSocket での応答や会話の継続も確認できました。
実行結果(GPT-5.6 Sol、途中経過の表示を省略)Running compliance tests against: bedrock-runtime.us-east-1.amazonaws.com
Model: global.openai.gpt-5.6-sol
✓ Response Output Phase Schema
✓ Compaction Missing Required Model (676ms)
✗ WebSocket Missing Previous Response (992ms) [1 events]
✗ Expected previous_response_not_found but got model_not_found
✓ Basic Text Response (1139ms)
✓ Image Input (1150ms)
✓ Multi-turn Conversation (1156ms)
✓ Tool Calling (1158ms)
✓ Streaming Response (1290ms) [22 events]
✓ System Prompt (1283ms)
✓ Assistant Message Phase (1311ms)
✓ Compaction Endpoint (1435ms)
✓ WebSocket Continuation (2336ms) [19 events]
✓ WebSocket Response (2359ms) [13 events]
✓ WebSocket Sequential Responses (2397ms) [18 events]
✗ WebSocket Failed Continuation Evicts Cache (2637ms) [22 events]
✗ Expected previous_response_not_found after failed continuation eviction but got no error code
✓ WebSocket Compact New Chain (3024ms) [10 events]
✓ WebSocket Store False Reconnect Recovery (4157ms) [20 events]
==================================================
Results: 15 passed, 2 failed, 0 skipped, 17 total
結果はモデルによって変わり、たとえば Grok 4.7 と Kimi K3 は compact に対応していませんでした。
準拠テストは、使いたいモデルが仕様のどこまでに対応しているかを手元で手軽に確かめる道具として使えます。
まとめ
Open Responses は OpenAI の Responses API をもとにした LLM API の共通仕様で、2026年10月22日に AAIF のプロジェクトになりました。
アイテム、状態、イベントの形が決まっているので、接続先とモデル名を変えるだけで、同じクライアントのコードを使い回せます。
Amazon Bedrock では bedrock-runtime と bedrock-mantle の 2 つのエンドポイントで使え、今回は 3 ベンダー・4 モデルで同じエージェントループが動きました。
リポジトリの準拠テストを使えば、モデルごとの対応範囲も手元で確かめられます。
複数のモデルを比べたり切り替えたりする場面で、まず試してみる価値のある仕様だと感じました。
脚注
AWS のブログには Amazon、Anthropic、Meta、Mistral、DeepSeek などのモデルも Responses API で使えると書かれています。ただし Bedrock のドキュメントの対応表では、これらのモデルは Responses API に対応していません。今回の検証でも、Claude Sonnet 5.5、Llama 4 Maverick、Nova Pro、Mistral Large 3、DeepSeek V3.2 への Responses API のリクエストは受け付けられませんでした。Claude Sonnet 5.5 は Messages API で、Mistral Large 3 と DeepSeek V3.2 は Chat Completions で呼び出せます。 ↩︎
Mentions
Open Responses là gì? Open Responses là một đặc tả mở, được công bố dưới dạng tài liệu OpenAPI 3.1, mô tả một hình dạng yêu cầu và phản hồi duy nhất để gọi các mô hình ngôn ngữ trên nhiều nhà cung cấp. Nó dựa trên OpenAI Responses API: bạn gửi model, input và tools tùy chọn tới POST /v1/responses, và bạn nhận lại các item có kiểu và các sự kiện streaming ngữ nghĩa thay vì một định dạng riêng của nhà cung cấp. OpenAI ra mắt Open Responses vào 2026-01-15, nó được cấp phép theo Apache 2.0, và vào 2026-10-22 OpenAI đã đóng góp nó cho Agentic AI Foundation (AAIF), tổ chức thuộc Linux Foundation cũng đang vận hành MCP. {% cta apidog.com %} Dùng thử Apidog ngay hôm nay {% endcta %} Bước cuối cùng đó chính là tin tức: đặc tả giờ đây đã có một hiến chương kỹ thuật, một ủy ban chỉ đạo và một ngôi nhà trung lập. Bài viết này đề cập đến những gì nó định nghĩa, ai triển khai nó, việc chuyển sang AAIF thay đổi điều gì, và cách kiểm tra xem một endpoint mà bạn phụ thuộc có tuân thủ hay không. Nếu bạn mới làm quen với API nền tảng, hãy bắt đầu với cách sử dụng OpenAI Responses API. Open Responses định nghĩa những gì Đặc tả mô tả vấn đề một cách rõ ràng: các nhà cung cấp đã hội tụ về cùng những khối xây dựng (tin nhắn, lệnh gọi công cụ, streaming, đầu vào đa phương thức) nhưng mỗi bên mã hóa chúng theo cách khác nhau. Open Responses chọn một cách mã hóa và ghi nó ra. Tài liệu OpenAPI hiện tại là phiên bản 2026-04-24 và bao phủ một bề mặt nhỏ: | Thao tác | Chức năng | | --- | --- | | POST /responses (createResponse) | Tạo một phản hồi, có hoặc không streaming | | WebSocket trên /responses | Cùng mô hình phản hồi qua một socket liên tục (thêm vào 2026-04-24) | | POST /responses/compact (compactResponse) | Trả về một cửa sổ đầu vào đã nén cho các cuộc hội thoại dài | Phần thân yêu cầu chấp nhận các trường mà bạn sẽ mong đợi nếu đã từng dùng API của OpenAI: model, input, instructions, tools, tool_choice, stream, store, previous_response_id, reasoning, text, truncation, temperature, top_p, max_output_tokens, prompt_cache_key và một vài trường khác. Đối tượng phản hồi (ResponseResource) mang id, status, output, usage, error và một bản sao của các thiết lập bạn đã gửi. Tài liệu định nghĩa tổng cộng 108 schema, hầu hết là các kiểu item và sự kiện streaming. Ba ý tưởng mang thiết kế này. Item là đơn vị ngữ cảnh Mọi thứ mô hình đọc hoặc tạo ra đều là một item: một message, một function_call, một function_call_output, một item reasoning. Các item có tính hai chiều, vì vậy đầu ra của một lượt có thể được đưa thẳng trở lại làm đầu vào cho lượt tiếp theo. Mỗi kiểu item được phân biệt bởi trường type của nó và có schema riêng. Các item cũng là máy trạng thái: mỗi item chuyển từ in_progress sang completed hoặc incomplete (ngân sách token đã cạn), và một item incomplete phải là item cuối cùng được phát ra, với toàn bộ phản hồi được đánh dấu là incomplete. Trạng thái không nói lên điều gì về việc máy chủ có lưu trữ item hay không; việc lưu trữ là một mối quan tâm riêng. Streaming là các sự kiện ngữ nghĩa, không phải các delta thô Khi bạn đặt stream: true, máy chủ phải trả lời với Content-Type: text/event-stream và một chuỗi sự kiện được định nghĩa. Một item đầu ra mở đầu bằng response.output_item.added; văn bản bên trong nó đến dưới dạng response.content_part.added, sau đó là các sự kiện response.output_text.delta lặp lại, rồi response.output_text.done và response.content_part.done; item kết thúc bằng response.output_item.done. Luồng phải kết thúc bằng một sự kiện kết thúc: response.completed, response.failed hoặc response.incomplete. Một [DONE] ở cuối là tùy chọn, và các client phải xử lý được một luồng kết thúc mà không có nó. !Diagram of the Open Responses streaming event order: output_item.added, content_part.added, output_text.delta repeated, output_text.done, content_part.done, output_item.done, then a terminal completed, failed or incomplete event Điều này quan trọng nhất đối với mã client: nếu hai nhà cung cấp phát ra cùng các sự kiện theo cùng thứ tự, một bộ phân tích SSE sẽ hoạt động cho cả hai. Hướng dẫn kiểm thử SSE của chúng tôi chỉ cách kiểm tra các luồng này theo từng sự kiện. Một lõi ổn định với các phần mở rộng có không gian tên Các nhà cung cấp có thể thêm các kiểu item, công cụ và sự kiện streaming của riêng họ, nhưng họ phải thêm tiền tố là một slug của nhà cung cấp. Ví dụ của chính đặc tả là openai:web_search_call. Một client không nhận ra một kiểu có tiền tố có thể bỏ qua nó mà không bị lỗi. Đây là cách đặc tả giữ được tính di động trong khi các công cụ được lưu trữ như tìm kiếm web hay tìm kiếm tệp vẫn là các tính năng của nhà cung cấp. Phần còn lại của hợp đồng Một vài quy tắc nữa đáng để biết trước khi bạn xây dựng dựa trên đặc tả: - Hai loại công cụ. Các công cụ được lưu trữ bên ngoài (hàm, máy chủ MCP) chạy bên ngoài nhà cung cấp; đối với hàm, mô hình phát ra một function_call, bạn chạy nó, và bạn gửi lại một function_call_output với call_id khớp. Các công cụ được lưu trữ bên trong (ví dụ tìm kiếm tệp của OpenAI) chạy bên trong nhà cung cấp mà không trao lại quyền điều khiển. - tool_choice và allowed_tools. tool_choice nhận auto (mặc định), required, none, hoặc một đối tượng nêu tên một hàm. allowed_tools giới hạn những công cụ mà mô hình có thể gọi trong khi vẫn hiển thị tất cả chúng, để bạn không làm mất hiệu lực một prompt đã được lưu trong bộ nhớ đệm bằng cách sửa mảng tools. Máy chủ phải thực thi nó như một giới hạn cứng. - previous_response_id. Máy chủ phải xử lý yêu cầu mới như previous_response.input + previous_response.output + input, theo thứ tự đó, để bạn không phải gửi lại bản ghi hội thoại. - Các item reasoning có thể mang content thô, một blob encrypted_content không rõ ràng, một summary an toàn cho người dùng, hoặc bất kỳ sự kết hợp nào. - Lỗi mang một type (server_error, invalid_request, not_found, model_error, too_many_requests), cùng với code, param và message; giữa luồng, một lỗi được theo sau bởi response.failed. Bản sửa đổi 2026-04-24 (changelog) đã thêm giao thức truyền tải WebSocket: mỗi lượt bắt đầu bằng một thông điệp response.create, một kết nối xử lý một phản hồi tại một thời điểm, các kết nối bị giới hạn ở 60 phút (mã lỗi websocket_connection_limit_reached), và các phần tiếp nối store: false sống trong bộ nhớ cục bộ của kết nối, thất bại với previous_response_not_found một khi trạng thái đó không còn. Cùng bản sửa đổi đã thêm /responses/compact, một trường phase tùy chọn trên các tin nhắn assistant (commentary hoặc final_answer), và làm cho logprobs trở thành tùy chọn. Open Responses so với Chat Completions Chat Completions vẫn là giao diện LLM được sao chép rộng rãi nhất. Sự khác biệt nằm ở hình dạng: Chat Completions trả về các choice chứa một message, với các lệnh gọi công cụ được nhét bên trong nó, trong khi mô hình Responses trả về một danh sách phẳng các item có kiểu. Một bước reasoning, ba lệnh gọi công cụ và một tin nhắn cuối trở thành các đối tượng riêng biệt, có thứ tự với trạng thái riêng của chúng, điều này phù hợp hơn với các vòng lặp agent. ![Side-by-side diagram: Chat Completions nests content and three tool_calls inside choices[0].message, while Open Responses returns a flat output list of reasoning, three function_call items and a message, each with a status](assets.apidog.com) Chúng tôi đã so sánh ba định dạng thống trị cạnh nhau, với các yêu cầu thực tế, trong Chat Completions vs Anthropic Messages vs Responses API. Nếu bạn đang chọn giữa các bề mặt của chính OpenAI, bài phân tích Agents API vs Responses API vs Agents SDK đề cập đến vị trí của Responses. Ai triển khai nó Danh sách người ủng hộ bao gồm AWS Bedrock, Databricks, Hugging Face, LM Studio, Nvidia, Ollama, OpenRouter, Red Hat, Vercel và vLLM, cùng với OpenAI. Anthropic và Google không nằm trong số những người ủng hộ được nêu tên; cả hai vẫn phát hành các định dạng gốc của riêng họ. “Hỗ trợ” bao hàm một phạm vi rộng, vì vậy hãy kiểm tra chi tiết cho runtime bạn sử dụng: - Ollama đã thêm POST /v1/responses trong v0.13.3. Tài liệu tương thích của nó nói rằng “chỉ phiên bản không trạng thái được hỗ trợ”: streaming, công cụ hàm và tóm tắt reasoning hoạt động, nhưng previous_response_id, conversation và truncation thì không. Bạn tự gửi lại lịch sử. - LM Studio đã làm cho endpoint http://localhost:1234/v1/responses của nó tương thích trong phiên bản 0.3.39, bao gồm previous_response_id, URL hình ảnh từ xa cho các mô hình thị giác và logprobs. Xem hướng dẫn LM Studio của chúng tôi để biết cách thiết lập. Để có một cảm nhận về quy mô, API Evangelist đã lấy một đường cơ sở vào ngày 13 tháng 9: trong số 120 nhà cung cấp tuyên bố tương thích OpenAI mà công bố một tài liệu OpenAPI có thể đọc được, 26 nhà cung cấp khai báo POST /responses, so với 105 nhà cung cấp khai báo POST /chat/completions. Mục đích của đường cơ sở là đo xem liệu quản trị trung lập có làm thay đổi con số đó hay không. Việc chuyển sang Agentic AI Foundation thay đổi điều gì AAIF đã công bố Open Responses vào 2026-10-22 tại AGNTCon + MCPCon North America ở San Jose, cùng với ba dự án mới khác: Agent Skills (từ Anthropic), OpenEnv (từ Hugging Face) và OpenSandbox (từ Alibaba). Điều đó đưa AAIF lên 10 dự án được lưu trữ trong năm đầu tiên, bên cạnh MCP, giao thức Agent2Agent, agents.md, goose, agentgateway và Agent Router. Nếu bạn đang tìm hiểu cách những thứ đó khớp với nhau, bài giải thích MCP vs A2A của chúng tôi là một khởi đầu tốt. Những gì thay đổi: - Quản trị. Dự án hiện là “Open Responses a Series of LF Projects, LLC,” với một hiến chương kỹ thuật được thông qua vào 2026-10-21. Một Ủy ban Chỉ đạo Kỹ thuật, ban đầu là những người duy trì dự án, sở hữu các quyết định kỹ thuật, và việc tham gia mở cho bất kỳ ai tuân theo hiến chương. - Uy tín cho các nhà cung cấp khác. Một đặc tả do một công ty sở hữu là một sản phẩm. Một đặc tả dưới một quỹ dễ dàng hơn để một đối thủ áp dụng mà không trông giống như đang đi theo một đối thủ. Những gì không thay đổi: - API của chính OpenAI. Responses API trên api.openai.com giữ các tính năng và lịch phát hành riêng của nó. Open Responses mô tả lõi di động; các công cụ dành riêng cho OpenAI vẫn nằm sau tiền tố openai:. - Định dạng truyền tải. Không có phiên bản đặc tả mới nào đi kèm với việc chuyển đổi. Bản phát hành mới nhất vẫn là 2026-04-24, và các bản phát hành có ngày tháng là bất biến. - Tuân thủ. Nằm trong danh sách người ủng hộ không có nghĩa là một endpoint vượt qua các bài kiểm tra. Chưa ai công bố một chỉ mục đạt/không đạt, vì vậy bạn tự kiểm tra các endpoint mà bạn phụ thuộc. Kiểm tra một endpoint bằng các bài kiểm tra chấp nhận Dự án cung cấp các bài kiểm tra chấp nhận của riêng nó. Trang tuân thủ chạy 10 bài kiểm tra trong trình duyệt đối với bất kỳ base URL, model và key nào: phản hồi văn bản cơ bản, streaming, system prompt, gọi công cụ, đầu vào hình ảnh, lịch sử nhiều lượt, nhãn phase của assistant, endpoint nén và một bài kiểm tra phủ định cho một yêu cầu nén thiếu model. Bảy bài kiểm tra WebSocket nữa (các lượt tuần tự, tiếp nối store: false, phục hồi khi kết nối lại, xóa bộ nhớ đệm sau một lần tiếp nối thất bại) chỉ chạy từ CLI: git clone https://github.com/openresponses/openresponses cd openresponses && bun install bun run test:compliance --base-url http://localhost:11434/v1 --api-key ollama Mỗi yêu cầu HTTP và mỗi lượt WebSocket có thời hạn 30 giây, và một lần hết thời gian chỉ làm thất bại bài kiểm tra đó. Hãy mong đợi một runtime không trạng thái như Ollama sẽ thất bại các bài kiểm tra tiếp nối theo thiết kế. Để agent lập trình của bạn kiểm tra nó với Apidog CLI Các bài kiểm tra chấp nhận cho bạn biết liệu một máy chủ có tuân theo đặc tả ngay hôm nay hay không. Chúng không theo dõi endpoint mà ứng dụng của bạn gọi mỗi khi bạn triển khai, nâng cấp Ollama hoặc chuyển nhà cung cấp. Để làm điều đó, hãy nhập đặc tả vào một dự án Apidog và để agent lập trình của bạn viết và chạy các bài kiểm tra hồi quy đối với nó bằng Apidog CLI. Cài đặt CLI và skill cho agent một lần: npm install -g apidog-cli@latest apidog auth login --with-token <YOUR_TOKEN> npx -y skills add https://apidog.com # pick your agent when prompted Sau đó đưa cho Claude Code, Codex hoặc Cursor một [REDACTED PROMPT] Download openresponses.org and import it into Apidog project <id>. Create an environment "local-ollama" with base URL localhost. Add test cases for POST /responses: one that expects 200, status "completed" and an output item of type "message"; one with stream: true that expects text/event-stream ending in response.completed; one without "model" that expects a 4xx error with an error.type field. Run them and summarize any failures. Agent đọc các schema, xác thực payload của nó trước khi viết bất cứ thứ gì, và chạy các case: curl -sLO openresponses.org apidog import --project <id> --format openapi --file ./openapi.json apidog environment create local-ollama --project <id> --base-url localhost apidog cli-schema get test-case-create apidog cli-schema validate test-case-create --file case.json apidog test-case create --project <id> --file case.json apidog run --test-case <caseId> --project <id> -e <envId> -r cli,json Mục servers của đặc tả trỏ tới https://api.openai.com/v1, vì vậy hãy thêm một môi trường cho mỗi nhà cung cấp và chạy cùng các case đối với từng môi trường: đó chính là tuyên bố về tính di động, được kiểm chứng. Đặt dòng apidog run ... -r junit vào pipeline của bạn để một bản nâng cấp runtime làm mất một trường sẽ làm hỏng bản build (hướng dẫn CI/CD); Apidog CLI trong Claude Code đề cập chi tiết việc thiết lập agent. Câu hỏi thường gặp Open Responses có giống với OpenAI Responses API không? Không. Open Responses là một đặc tả được dẫn xuất từ nó. Responses API của OpenAI là một triển khai với các tính năng bổ sung chỉ dành cho OpenAI; Ollama, LM Studio và vLLM là những triển khai khác. Ai sở hữu Open Responses hiện nay? Kể từ 2026-10-22, nó là một dự án của Agentic AI Foundation thuộc Linux Foundation, được vận hành như một chuỗi LF Projects với một Ủy ban Chỉ đạo Kỹ thuật. Nó được cấp phép theo Apache 2.0. Anthropic có hỗ trợ Open Responses không? Anthropic không nằm trong số những người ủng hộ được nêu tên. Nó đã đóng góp Agent Skills cho AAIF cùng ngày, nhưng giao diện gốc của Claude vẫn là Messages API. Tệp đặc tả ở đâu? Tại https://www.openresponses.org/openapi/openapi.json, với các bản phát hành có ngày tháng trong kho lưu trữ GitHub. Bước tiếp theo Chọn endpoint mà sản phẩm của bạn gọi nhiều nhất, chạy các bài kiểm tra chấp nhận trên trình duyệt đối với nó, và nhập đặc tả vào Apidog để agent của bạn có thể tiếp tục chạy các kiểm tra đó trên mỗi lần triển khai. Tải Apidog để bắt đầu.
Open Responses คืออะไร status, output, usage, error และการสะท้อนค่าตั้งค่าที่คุณส่งไป เอกสารนี้กำหนดสคีมาไว้ทั้งหมด 108 รายการ โดยส่วนใหญ่เป็นชนิดของไอเท็มและเหตุการณ์สตรีมมิ่ง มีแนวคิดสามข้อที่เป็นแกนของการออกแบบนี้ ไอเท็มคือหน่วยของบริบท ทุกสิ่งที่โมเดลอ่านหรือสร้างขึ้นล้วนเป็นไอเท็ม: message, function_call, function_call_output, ไอเท็ม reasoning ไอเท็มมีทิศทามหมาย ไม่ใช่ delta ดิบ เมื่อคุณตั้งค่า stream: true เซิร์ฟเวอร์ต้องตอบกลับด้วย Content-Type: text/event-stream และล response.output_text.delta ที่เกิดซ้ำหลายครั้ง จากนั้น response.output_text.done และ response.content_part.done ไอเท็มจะปิดด้วย response.output_item.done สตรีมต้องจบด้วยเหตคลเอนต์ต้องรองรับสตรีมที่จบโดยไม่มี [DONE] ด้วย !Diagram of the Open Responses streaming event order: output_item.added, content_part.added, output_text.delta repeated, output_text.done, content_part.done, output_item.done, then a terminal completed, failed or incomplete event เรื่องนี้สำคัญที่สุดสำหรับโค้ดฝั่งไคลเอนต์: หากผู้ให้บริการสองรายส่งเหตุการณ์เดียวกันในลำดับเดียวกัน ตัวแยกวิเคราะห์ SSE ตัวเดียวก็ใช้ได้กับทั้งสองราย คู่มือการทดสอบ SSE ของเราแสดงวิธีตรวจสอบสตรีมเหล่านี้ทีละเหตุการณ์ แกนหลักที่เสถียรพร้อมส่วนขยายที่แยกเนมสเปซ ผู้ให้บริการสามารถเพิ่มชนิดไอเท็ม เครื่องมือ และเหตุการณ์สตรีมมิ่งของตัวเองได้ แต่ต้องใส่คำนำหน้าเป็น slug ของผู้ให้บริการนั้น ตัวอย่างในข้อกำหนดเองคือ openai:web_search_call ไคลเอนต์ที่ไม่รู้จักชนิดที่มีคำนำหน้าสามารถข้ามมันไปได้โดยไม่เกิดข้อผิดพลาด นี่คือวิธีที่ทำให้ข้อกำหนดนี้ยังคงพกพาได้ ในขณะที่เครื่องมือที่โฮสต์ไว้ เช่น web search หรือ file search ยังคงเป็นฟีเจอร์เฉพาะของผู้ให้บริการ ส่วนที่เหลือของสัญญา มีกฎอีกสองสามข้อที่ควรรู้ก่อนสร้างงานบนข้อกำหนดนี้: - เครื่องมือสองประเภท เครื่องมือที่โฮสต์ภายนอก (ฟังก์ชัน, เซิร์ฟเวอร์ MCP) ทำงานนอกผู้ให้บริการ สำหรับฟังก์ชัน โมเดลจะส่ง function_call ออกมา คุณเป็นคนรันมัน แล้วส่ง function_call_output กลับไปพร้อม call_id ที่ตรงกัน ส่วนเครื่องมือที่โฮสต์ภายใน (เช่น file search ของ OpenAI) ทำงานภายในผู้ให้บริการโดยไม่คืนการควบคุมกลับมา - tool_choice และ allowed_tools tool_choice รับค่า auto (ค่าเริ่มต้น), required, none หรือออบเจ็กต์ที่ระบุชื่อฟังก์ชันหนึ่งรายการ allowed_tools จำกัดว่าโมเดลเรียกใช้เครื่องมือใดได้บ้างในขณะที่ยังแสดงเครื่องมือทั้งหมดอยู่ เพื่อไม่ให้แคชพรอมป์ตกลายเป็นโมฆะจากการแก้ไขอาร์เรย์ tools เซิร์ฟเวอร์ต้องบังคับใช้มันเป็นขีดจำกัดแบบเด็ดขาด - previous_response_id เซิร์ฟเวอร์ต้องถือว่าคำขอใหม่คือ previous_response.input + previous_response.output + input ตามลำดับนั้น เพื่อให้คุณไม่ต้องส่งบทสนทนาทั้งหมดซ้ำ - ไอเท็ม reasoning อาจมี content ดิบ, บล็อบ encrypted_content ที่อ่านไม่ได้, summary ที่ปลอดภัยสำหรับผู้ใช้ หรือผสมกันแบบใดก็ได้ - ข้อผิดพลาด มี type (server_error, invalid_request, not_found, model_error, too_many_requests) พร้อมด้วย code, param และ message ระหว่างสตรีม ข้อผิดพลาดจะตามมาด้วย response.failed การแก้ไขปรับปรุงเมื่อ 2026-04-24 (changelog) ได้เพิ่มการรับส่งผ่าน WebSocket: แต่ละเทิร์นเริ่มด้วยข้อความ response.create หนึ่งการเชื่อมต่อประมวลผลการตอบกลับได้ครั้งละหนึ่งรายการ การเชื่อมต่อถูกจำกัดไว้ที่ 60 นาที (รหัสข้อผิดพลาด websocket_connection_limit_reached) และการต่อเนื่องที่ใช้ store: false จะอยู่ในหน่วยความจำเฉพาะการเชื่อมต่อนั้น ซึ่งจะล้มเหลวด้วย previous_response_not_found เมื่อสถานะนั้นหายไปแล้ว การแก้ไขปรับปรุงครั้งเดียวกันยังได้เพิ่ม /responses/compact ฟิลด์ phase แบบทางเลือกบนข้อความของผู้ช่วย (commentary หรือ final_answer) และทำให้ logprobs เป็นทางเลือก Open Responses กับ Chat Completions Chat Completions ยังคงเป็นอินเทอร์เฟซ LLM ที่ถูกนำไปลอกเลียนแบบมากที่สุด ความต่างอยู่ที่รูปร่าง: Chat Completions คืนค่า choices ที่ภายในบรรจุข้อความ โดยมีการเรียกใช้เครื่องมือซ่อนอยู่ภายในนั้น ขณะที่โมเดล Responses คืนค่ารายการแบนของไอเท็มที่มีการระบุชนิด ขั้นตอนการคิด (reasoning) การเรียกใช้เครื่องมือสามครั้ง และข้อความสุดท้ายจะกลายเป็นออบเจ็กต์แยกกันที่เรียงลำดับและมีสถานะของตัวเอง ซึ่งเข้ากับลูปของเอเจนต์ได้ดีกว่า ![Side-by-side diagram: Chat Completions nests content and three tool_calls inside choices[0].message, while Open Responses returns a flat output list of reasoning, three function_call items and a message, each with a status](assets.apidog.com) เราได้เปรียบเทียบสามรูปแบบที่โดดเด่นแบบเคียงข้างกัน พร้อมคำขอจริง ในบทความ Chat Completions กับ Anthropic Messages กับ Responses API หากคุณกำลังเลือกระหว่างพื้นผิว API ของ OpenAI เอง บทวิเคราะห์ Agents API กับ Responses API กับ Agents SDK ครอบคลุมว่า Responses อยู่ตรงไหน ใครนำไปใช้งาน รายชื่อผู้สนับสนุนประกอบด้วย AWS Bedrock, Databricks, Hugging Face, LM Studio, Nvidia, Ollama, OpenRouter, Red Hat, Vercel และ vLLM ควบคู่กับ OpenAI ส่วน Anthropic และ Google ไม่ได้อยู่ในรายชื่อผู้สนับสนุนที่ระบุชื่อไว้ ทั้งสองรายยังคงส่งมอบรูปแบบเนทีฟของตัวเอง คำว่า "สนับสนุน" ครอบคลุมความหมายได้กว้างมาก ดังนั้นควรตรวจสอบรายละเอียดของรันไทม์ที่คุณใช้: - Ollama เพิ่ม POST /v1/responses ใน v0.13.3 เอกสารความเข้ากันได้ของมันระบุว่า "รองรับเฉพาะแบบไม่เก็บสถานะ (non-stateful)" เท่านั้น: การสตรีมมิ่ง เครื่องมือฟังก์ชัน และสรุป reasoning ใช้ได้ แต่ previous_response_id, conversation และ truncation ใช้ไม่ได้ คุณต้องส่งประวัติซ้ำเอง - LM Studio ทำให้ endpoint http://localhost:1234/v1/responses ของตนเข้ากันได้ในเวอร์ชัน 0.3.39 รวมถึง previous_response_id, URL รูปภาพระยะไกลสำหรับโมเดลที่มองเห็นภาพ และ logprobs ดู คู่มือ LM Studio ของเราเพื่อการตั้งค่า เพื่อให้เห็นขนาดของเรื่องนี้ API Evangelist ได้ทำการวัดค่าพื้นฐานเมื่อวันที่ 13 กันยายน: จากผู้ให้บริการ 120 รายที่อ้างว่าสามารถใช้แทน OpenAI ได้และเผยแพร่เอกสาร OpenAPI ที่อ่านได้ มี 26 รายที่ประกาศ POST /responses เทียบกับ 105 รายที่ประกาศ POST /chat/completions จุดประสงค์ของการวัดค่าพื้นฐานนี้คือเพื่อวัดว่าการกำกับดูแลแบบเป็นกลางจะทำให้ตัวเลขนั้นเปลี่ยนไปหรือไม่ การย้ายไป Agentic AI Foundation เปลี่ยนอะไร AAIF ประกาศเรื่อง Open Responses เมื่อ 2026-10-22 ที่งาน AGNTCon + MCPCon North America ในซานโฮเซ พร้อมกับอีกสามโปรเจ็กต์ใหม่ ได้แก่ Agent Skills (จาก Anthropic), OpenEnv (จาก Hugging Face) และ OpenSandbox (จาก Alibaba) นั่นทำให้ AAIF มีโปรเจ็กต์ที่โฮสต์ไว้ทั้งหมด 10 โปรเจ็กต์ในปีแรก เคียงคู่กับ MCP, โปรโตคอล Agent2Agent, agents.md, goose, agentgateway และ Agent Router หากคุณกำลังพยายามทำความเข้าใจว่าสิ่งเหล่านี้เชื่อมโยงกันอย่างไร บทอธิบาย MCP กับ A2A ของเราเป็นจุดเริ่มต้นที่ดี สิ่งที่เปลี่ยนไป: - การกำกับดูแล ตอนนี้โปรเจ็กต์นี้มีชื่อว่า "Open Responses a Series of LF Projects, LLC" พร้อมกฎบัตรทางเทคนิคที่รับรองเมื่อ 2026-10-21 คณะกรรมการกำกับดูแลทางเทคนิค (Technical Steering Committee) ซึ่งเริ่มต้นจากผู้ดูแลโปรเจ็กต์ เป็นผู้ตัดสินใจเรื่องเทคนิค และการมีส่วนร่วมเปิดกว้างสำหรับทุกคนที่ปฏิบัติตามกฎบัตร - ความน่าเชื่อถือสำหรับผู้จำหน่ายรายอื่น ข้อกำหนดที่เป็นของบริษัทใดบริษัทหนึ่งก็คือผลิตภัณฑ์ แต่ข้อกำหนดที่อยู่ภายใต้มูลนิธิย่อมทำให้คู่แข่งนำไปใช้ได้ง่ายกว่าโดยไม่ดูเหมือนกำลังทำตามคู่แข่ง สิ่งที่ยังไม่เปลี่ยน: - API ของ OpenAI เอง Responses API บน api.openai.com ยังคงมีฟีเจอร์และตารางการออกรุ่นของตัวเอง Open Responses อธิบายแกนหลักที่พกพาได้ ส่วนเครื่องมือเฉพาะของ OpenAI ยังคงอยู่หลังคำนำหน้า openai: - รูปแบบการรับส่งข้อมูล (wire format) ไม่มีเวอร์ชันข้อกำหนดใหม่มาพร้อมกับการย้ายครั้งนี้ รุ่นล่าสุดยังคงเป็น 2026-04-24 และรุ่นที่มีการลงวันที่จะไม่ถูกแก้ไข - ความสอดคล้อง การอยู่ในรายชื่อผู้สนับสนุนไม่ได้หมายความว่า endpoint จะผ่านการทดสอบ ยังไม่มีใครเผยแพร่ดัชนีผ่าน/ไม่ผ่าน ดังนั้นคุณต้องตรวจสอบ endpoint ที่คุณพึ่งพาด้วยตัวเอง ตรวจสอบ endpoint ด้วยชุดทดสอบการยอมรับ โปรเจ็กต์นี้มีชุดทดสอบการยอมรับ (acceptance tests) ของตัวเอง หน้าความสอดคล้อง รันการทดสอบ 10 รายการในเบราว์เซอร์กับ base URL, โมเดล และคีย์ใดก็ได้: การตอบกลับข้อความพื้นฐาน, การสตรีมมิ่ง, system prompt, การเรียกใช้เครื่องมือ, อินพุตรูปภาพ, ประวัติแบบหลายเทิร์น, ป้ายกำกับ phase ของผู้ช่วย, endpoint การย่อข้อมูล และการทดสอบเชิงลบสำหรับคำขอย่อที่ขาด model นอกจากนี้ยังมีการทดสอบ WebSocket อีกเจ็ดรายการ (เทิร์นต่อเนื่อง, การต่อเนื่องที่ใช้ store: false, การกู้คืนหลังการเชื่อมต่อใหม่, การล้างแคชหลังการต่อเนื่องที่ล้มเหลว) ซึ่งรันได้เฉพาะจาก CLI เท่านั้น: git clone https://github.com/openresponses/openresponses cd openresponses && bun install bun run test:compliance --base-url http://localhost:11434/v1 --api-key ollama คำขอ HTTP แต่ละครั้งและเทิร์น WebSocket แต่ละเทิร์นมีกำหนดเวลา 30 วินาที และการหมดเวลาจะทำให้เฉพาะการทดสอบนั้นล้มเหลว ให้คาดว่ารันไทม์แบบไม่เก็บสถานะอย่าง Ollama จะล้มเหลวในการทดสอบการต่อเนื่องตามการออกแบบ ให้เอเจนต์เขียนโค้ดของคุณทดสอบด้วย Apidog CLI ชุดทดสอบการยอมรับบอกคุณว่าเซิร์ฟเวอร์ปฏิบัติตามข้อกำหนดในปัจจุบันหรือไม่ แต่ไม่ได้เฝ้าดู endpoint ที่แอปของคุณเรียกทุกครั้งที่คุณดีพลอย อัปเกรด Ollama หรือสลับผู้ให้บริการ สำหรับเรื่องนั้น ให้ import ข้อกำหนดนี้เข้าโปรเจ็กต์ Apidog แล้วให้เอเจนต์เขียนโค้ดของคุณเขียนและรันการทดสอบรีเกรสชันกับมันด้วย Apidog CLI ติดตั้ง CLI และสกิลของเอเจนต์เพียงครั้งเดียว: npm install -g apidog-cli@latest apidog auth login --with-token <YOUR_TOKEN> npx -y skills add https://apidog.com # pick your agent when prompted จากนั้นมอบพรอมป์หนึ่งข้อให้ Claude Code, Codex หรือ Cursor: Download https://www.openresponses.org/openapi/openapi.json and import it into Apidog project <id>. Create an environment "local-ollama" with base URL http://localhost:11434/v1. Add test cases for POST /responses: one that expects 200, status "completed" and an output item of type "message"; one with stream: true that expects text/event-stream ending in response.completed; one without "model" that expects a 4xx error with an error.type field. Run them and summarize any failures. เอเจนต์จะอ่านสคีมา ตรวจสอบความถูกต้องของเพย์โหลดก่อนเขียนอะไรลงไป แล้วรันเคสต่าง ๆ: curl -sLO https://www.openresponses.org/openapi/openapi.json apidog import --project <id> --format openapi --file ./openapi.json apidog environment create local-ollama --project <id> --base-url http://localhost:11434/v1 apidog cli-schema get test-case-create apidog cli-schema validate test-case-create --file case.json apidog test-case create --project <id> --file case.json apidog run --test-case <caseId> --project <id> -e <envId> -r cli,json รายการ servers ในข้อกำหนดชี้ไปที่ https://api.openai.com/v1 ดังนั้นให้เพิ่มหนึ่ง environment ต่อผู้ให้บริการหนึ่งราย แล้วรันเคสเดียวกันกับแต่ละราย นั่นคือข้ออ้างเรื่องการพกพาที่ถูกนำมาทดสอบจริง ใส่บรรทัด apidog run ... -r junit ลงในไปป์ไลน์ของคุณ เพื่อให้การอัปเกรดรันไทม์ที่ทำให้ฟิลด์หนึ่งหายไปทำให้บิลด์ล้มเหลว (คู่มือ CI/CD) ส่วน Apidog CLI ใน Claude Code ครอบคลุมการตั้งค่าเอเจนต์อย่างละเอียด คำถามที่พบบ่อย Open Responses เหมือนกับ OpenAI Responses API หรือไม่? ไม่ Open Responses เป็นข้อกำหนดที่พัฒนามาจากมัน Responses API ของ OpenAI เป็นการนำไปใช้งานหนึ่งรูปแบบที่มีฟีเจอร์พิเศษเฉพาะ OpenAI ส่วน Ollama, LM Studio และ vLLM เป็นอีกรูปแบบหนึ่ง ตอนนี้ใครเป็นเจ้าของ Open Responses? ตั้งแต่ 2026-10-22 มันเป็นโปรเจ็กต์ของ Agentic AI Foundation ภายใต้ Linux Foundation ดำเนินงานในรูปแบบชุดโปรเจ็กต์ LF พร้อมคณะกรรมการกำกับดูแลทางเทคนิค อยู่ภายใต้สัญญาอนุญาต Apache 2.0 Anthropic สนับสนุน Open Responses หรือไม่? Anthropic ไม่ได้อยู่ในรายชื่อผู้สนับสนุนที่ระบุไว้ วันเดียวกันนั้นทาง Anthropic ได้มอบ Agent Skills ให้แก่ AAIF แต่อินเทอร์เฟซเนทีฟของ Claude ยังคงเป็น Messages API ไฟล์ข้อกำหนดอยู่ที่ไหน? อยู่ที่ https://www.openresponses.org/openapi/openapi.json โดยมีรุ่นที่ลงวันที่อยู่ใน ที่เก็บ GitHub ขั้นตอนถัดไป เลือก endpoint เดียวที่ผลิตภัณฑ์ของคุณเรียกบ่อยที่สุด รันชุดทดสอบการยอมรับในเบราว์เซอร์กับมัน แล้ว import ข้อกำหนดเข้า Apidog เพื่อให้เอเจนต์ของคุณคอยรันการตรวจสอบเหล่านั้นในทุกการดีพลอย ดาวน์โหลด Apidog เพื่อเริ่มต้น
Qu'est-ce que Open Responses ? --- title: "Qu'est-ce que Open Responses ?" description: "Open Responses est une spécification OpenAPI sous Apache 2.0, basée sur l'API Responses d'OpenAI, pour appeler n'importe quel fournisseur de modèles dans un format unique. OpenAI l'a contribuée à l'Agentic AI Foundation le 22 octobre 2026." canonical_url: apidog.com cover_image: assets.apidog.com --- Open Responses est une spécification ouverte, publiée sous forme de document OpenAPI 3.1, qui décrit une forme de requête et de réponse pour appeler des modèles de langage chez différents fournisseurs. Elle est basée sur l'API Responses d'OpenAI : vous envoyez model, input et éventuellement tools à POST /v1/responses, et vous recevez en retour des éléments typés et des événements de streaming sémantiques au lieu d'un format spécifique à un fournisseur. OpenAI a lancé Open Responses le 15 janvier 2026, elle est sous licence Apache 2.0, et le 22 octobre 2026, OpenAI l'a cédée à l'Agentic AI Foundation (AAIF), l'organisme de la Linux Foundation qui héberge également MCP. {% cta apidog.com %} Essayez Apidog dès aujourd'hui {% endcta %} Cette dernière étape est la nouvelle : la spécification dispose désormais d'une charte technique, d'un comité de pilotage et d'un organisme hôte neutre. Cet article couvre ce qu'elle définit, qui l'implémente, ce que le transfert à l'AAIF change, et comment vérifier si un point de terminaison dont vous dépendez est conforme. Si vous découvrez l'API sous-jacente, commencez par comment utiliser l'API Responses d'OpenAI. Ce que définit Open Responses La spécification décrit clairement le problème : les fournisseurs ont convergé vers les mêmes briques de base (messages, appels d'outils, streaming, entrée multimodale) mais chacun les encode différemment. Open Responses choisit un encodage et le couche par écrit. Le document OpenAPI actuel est en version 2026-04-24 et couvre une petite surface : | Opération | Ce qu'elle fait | | --- | --- | | POST /responses (createResponse) | Créer une réponse, avec ou sans streaming | | WebSocket sur /responses | Même modèle de réponse sur une socket persistante (ajouté le 24 avril 2026) | | POST /responses/compact (compactResponse) | Retourner une fenêtre d'entrée compactée pour les longues conversations | Le corps de la requête accepte les champs auxquels vous vous attendez si vous avez utilisé l'API d'OpenAI : model, input, instructions, tools, tool_choice, stream, store, previous_response_id, reasoning, text, truncation, temperature, top_p, max_output_tokens, prompt_cache_key et quelques autres. L'objet de réponse (ResponseResource) contient id, status, output, usage, error et un écho des paramètres que vous avez envoyés. Le document définit 108 schémas au total, la plupart étant des types d'éléments et d'événements de streaming. Trois idées portent la conception. Les éléments sont l'unité de contexte Tout ce que le modèle lit ou produit est un élément : un message, un function_call, un function_call_output, un élément reasoning. Les éléments sont bidirectionnels, de sorte que la sortie d'un tour peut être renvoyée directement comme entrée du tour suivant. Chaque type d'élément est discriminé par son champ type et possède son propre schéma. Les éléments sont aussi des machines à états : chacun passe de in_progress à completed ou incomplete (le budget de tokens est épuisé), et un élément incomplete doit être le dernier émis, la réponse entière étant marquée incomplète. Un statut ne dit rien sur le fait que le serveur ait stocké l'élément ; la persistance est une préoccupation distincte. Le streaming est constitué d'événements sémantiques, pas de deltas bruts Lorsque vous définissez stream: true, le serveur doit répondre avec Content-Type: text/event-stream et une séquence d'événements définie. Un élément de sortie s'ouvre avec response.output_item.added ; le texte qu'il contient arrive sous forme de response.content_part.added, puis d'événements répétés response.output_text.delta, puis de response.output_text.done et response.content_part.done ; l'élément se ferme avec response.output_item.done. Le flux doit se terminer par un événement terminal : response.completed, response.failed ou response.incomplete. Un [DONE] final est facultatif, et les clients doivent gérer un flux qui se termine sans lui. !Diagram of the Open Responses streaming event order: output_item.added, content_part.added, output_text.delta repeated, output_text.done, content_part.done, output_item.done, then a terminal completed, failed or incomplete event Cela compte surtout pour le code client : si deux fournisseurs émettent les mêmes événements dans le même ordre, un seul parseur SSE fonctionne pour les deux. Notre guide de test SSE montre comment inspecter ces flux événement par événement. Un noyau stable avec des extensions qualifiées par espace de noms Les fournisseurs peuvent ajouter leurs propres types d'éléments, outils et événements de streaming, mais ils doivent les préfixer par un identifiant de fournisseur. L'exemple de la spécification elle-même est openai:web_search_call. Un client qui ne reconnaît pas un type préfixé peut l'ignorer sans que cela casse quoi que ce soit. C'est ainsi que la spécification reste portable tandis que les outils hébergés comme la recherche web ou la recherche de fichiers restent des fonctionnalités propres au fournisseur. Le reste du contrat Quelques règles supplémentaires méritent d'être connues avant de construire sur la spécification : - Deux types d'outils. Les outils hébergés en externe (fonctions, serveurs MCP) s'exécutent en dehors du fournisseur ; pour les fonctions, le modèle émet un function_call, vous l'exécutez, et vous renvoyez un function_call_output avec le call_id correspondant. Les outils hébergés en interne (la recherche de fichiers d'OpenAI, par exemple) s'exécutent à l'intérieur du fournisseur sans rendre le contrôle. - tool_choice et allowed_tools. tool_choice prend auto (la valeur par défaut), required, none, ou un objet nommant une fonction. allowed_tools restreint les outils que le modèle peut appeler tout en les affichant tous, afin que vous n'invalidiez pas un prompt mis en cache en modifiant le tableau tools. Les serveurs doivent l'appliquer comme une limite stricte. - previous_response_id. Le serveur doit traiter la nouvelle requête comme previous_response.input + previous_response.output + input, dans cet ordre, afin que vous ne renvoyiez pas la transcription. - Les éléments de raisonnement peuvent porter un content brut, un blob opaque encrypted_content, un summary sûr pour l'utilisateur, ou n'importe quel mélange. - Les erreurs portent un type (server_error, invalid_request, not_found, model_error, too_many_requests), plus code, param et message ; en plein flux, une erreur est suivie de response.failed. La révision du 24 avril 2026 (journal des modifications) a ajouté le transport WebSocket : chaque tour commence par un message response.create, une connexion traite une réponse à la fois, les connexions sont limitées à 60 minutes (code d'erreur websocket_connection_limit_reached), et les continuations store: false vivent dans la mémoire locale à la connexion, échouant avec previous_response_not_found une fois cet état disparu. La même révision a ajouté /responses/compact, un champ phase facultatif sur les messages de l'assistant (commentary ou final_answer), et a rendu logprobs facultatif. Open Responses vs Chat Completions Chat Completions est encore l'interface LLM la plus largement copiée. La différence est la forme : Chat Completions renvoie des choix contenant un message, avec les appels d'outils imbriqués à l'intérieur, tandis que le modèle Responses renvoie une liste plate d'éléments typés. Une étape de raisonnement, trois appels d'outils et un message final deviennent des objets distincts et ordonnés avec leur propre statut, ce qui convient mieux aux boucles d'agents. ![Side-by-side diagram: Chat Completions nests content and three tool_calls inside choices[0].message, while Open Responses returns a flat output list of reasoning, three function_call items and a message, each with a status](assets.apidog.com) Nous avons comparé les trois formats dominants côte à côte, avec de vraies requêtes, dans Chat Completions vs Anthropic Messages vs Responses API. Si vous choisissez entre les surfaces propres à OpenAI, l'analyse Agents API vs Responses API vs Agents SDK couvre la place de Responses. Qui l'implémente La liste des partisans inclut AWS Bedrock, Databricks, Hugging Face, LM Studio, Nvidia, Ollama, OpenRouter, Red Hat, Vercel et vLLM, aux côtés d'OpenAI. Anthropic et Google ne font pas partie des partisans nommés ; les deux proposent toujours leurs propres formats natifs. « Prend en charge » couvre un large éventail, alors vérifiez les détails pour le runtime que vous utilisez : - Ollama a ajouté POST /v1/responses dans la v0.13.3. Sa documentation de compatibilité indique que « seule la variante non stateful est prise en charge » : le streaming, les outils de fonction et les résumés de raisonnement fonctionnent, mais previous_response_id, conversation et truncation non. Vous renvoyez l'historique vous-même. - LM Studio a rendu son point de terminaison http://localhost:1234/v1/responses compatible dans la version 0.3.39, y compris previous_response_id, les URL d'images distantes pour les modèles de vision et les logprobs. Consultez notre guide LM Studio pour la configuration. Pour donner une idée de l'échelle, API Evangelist a établi une base de référence le 13 septembre : sur 120 fournisseurs revendiquant une compatibilité OpenAI qui publient un document OpenAPI lisible, 26 déclarent POST /responses, contre 105 qui déclarent POST /chat/completions. Le but de cette base de référence est de mesurer si une gouvernance neutre fait évoluer ce nombre. Ce que change le transfert à l'Agentic AI Foundation L'AAIF a annoncé Open Responses le 22 octobre 2026 à l'AGNTCon + MCPCon North America à San Jose, en même temps que trois autres nouveaux projets : Agent Skills (d'Anthropic), OpenEnv (de Hugging Face) et OpenSandbox (d'Alibaba). Cela porte l'AAIF à 10 projets hébergés au cours de sa première année, aux côtés de MCP, du protocole Agent2Agent, agents.md, goose, agentgateway et Agent Router. Si vous cherchez à comprendre comment tout cela s'articule, notre explication MCP vs A2A est un bon point de départ. Ce qui change : - Gouvernance. Le projet est désormais « Open Responses a Series of LF Projects, LLC », avec une charte technique adoptée le 21 octobre 2026. Un comité de pilotage technique, initialement les mainteneurs du projet, est propriétaire des décisions techniques, et la participation est ouverte à toute personne qui suit la charte. - Crédibilité pour les autres fournisseurs. Une spécification détenue par une seule entreprise est un produit. Une spécification placée sous une fondation est plus facile à adopter pour un concurrent sans donner l'impression de suivre un rival. Ce qui ne change pas : - L'API d'OpenAI elle-même. L'API Responses sur api.openai.com conserve ses propres fonctionnalités et son propre calendrier de publication. Open Responses décrit le noyau portable ; les outils spécifiques à OpenAI restent derrière le préfixe openai:. - Le format d'échange. Aucune nouvelle version de la spécification n'est venue avec le transfert. La dernière version est toujours 2026-04-24, et les versions datées sont immuables. - Conformité. Figurer sur la liste des partisans ne signifie pas qu'un point de terminaison réussit les tests. Personne ne publie encore d'index de réussite/échec, vous devez donc vérifier vous-même les points de terminaison dont vous dépendez. Vérifier un point de terminaison avec les tests d'acceptation Le projet fournit ses propres tests d'acceptation. La page de conformité exécute 10 tests dans le navigateur contre n'importe quelle URL de base, modèle et clé : réponse texte de base, streaming, prompt système, appel d'outils, entrée d'image, historique multi-tours, étiquettes phase de l'assistant, le point de terminaison de compactage et un test négatif pour une requête compacte sans model. Sept autres tests WebSocket (tours séquentiels, continuation store: false, reprise après reconnexion, éviction du cache après une continuation échouée) s'exécutent uniquement depuis la CLI : git clone https://github.com/openresponses/openresponses cd openresponses && bun install bun run test:compliance --base-url http://localhost:11434/v1 --api-key ollama Chaque requête HTTP et chaque tour WebSocket dispose d'un délai de 30 secondes, et un dépassement de délai ne fait échouer que ce test. Attendez-vous à ce qu'un runtime non stateful tel qu'Ollama échoue aux tests de continuation par conception. Laissez votre agent de codage le tester avec Apidog CLI Les tests d'acceptation vous indiquent si un serveur suit la spécification aujourd'hui. Ils ne surveillent pas le point de terminaison que votre application appelle à chaque déploiement, mise à niveau d'Ollama ou changement de fournisseur. Pour cela, importez la spécification dans un projet Apidog et laissez votre agent de codage écrire et exécuter des tests de régression avec Apidog CLI. Installez la CLI et la compétence d'agent une fois : npm install -g apidog-cli@latest apidog auth login --with-token <YOUR_TOKEN> npx -y skills add https://apidog.com # pick your agent when prompted Ensuite, donnez une invite à Claude Code, Codex ou Cursor : Download https://www.openresponses.org/openapi/openapi.json and import it into Apidog project <id>. Create an environment "local-ollama" with base URL http://localhost:11434/v1. Add test cases for POST /responses: one that expects 200, status "completed" and an output item of type "message"; one with stream: true that expects text/event-stream ending in response.completed; one without "model" that expects a 4xx error with an error.type field. Run them and summarize any failures. L'agent lit les schémas, valide ses charges utiles avant d'écrire quoi que ce soit, et exécute les cas : curl -sLO https://www.openresponses.org/openapi/openapi.json apidog import --project <id> --format openapi --file ./openapi.json apidog environment create local-ollama --project <id> --base-url http://localhost:11434/v1 apidog cli-schema get test-case-create apidog cli-schema validate test-case-create --file case.json apidog test-case create --project <id> --file case.json apidog run --test-case <caseId> --project <id> -e <envId> -r cli,json L'entrée servers de la spécification pointe vers https://api.openai.com/v1, donc ajoutez un environnement par fournisseur et exécutez les mêmes cas sur chacun : c'est la promesse de portabilité, testée. Placez la ligne apidog run ... -r junit dans votre pipeline pour qu'une mise à niveau de runtime qui supprime un champ fasse échouer la compilation (guide CI/CD) ; Apidog CLI dans Claude Code couvre la configuration de l'agent en détail. FAQ Open Responses est-il identique à l'API Responses d'OpenAI ? Non. Open Responses est une spécification dérivée de celle-ci. L'API Responses d'OpenAI est une implémentation avec des fonctionnalités supplémentaires propres à OpenAI ; Ollama, LM Studio et vLLM en sont d'autres. Qui possède Open Responses maintenant ? Depuis le 22 octobre 2026, c'est un projet de l'Agentic AI Foundation sous la Linux Foundation, géré comme une série LF Projects avec un comité de pilotage technique. Il est sous licence Apache 2.0. Anthropic prend-il en charge Open Responses ? Anthropic ne fait pas partie des partisans nommés. Il a contribué Agent Skills à l'AAIF le même jour, mais l'interface native de Claude est toujours l'API Messages. Où se trouve le fichier de spécification ? À https://www.openresponses.org/openapi/openapi.json, avec des versions datées dans le dépôt GitHub. Prochaine étape Choisissez le point de terminaison que votre produit appelle le plus, exécutez les tests d'acceptation du navigateur contre lui, et importez la spécification dans Apidog pour que votre agent puisse maintenir ces vérifications à chaque déploiement. Téléchargez Apidog pour commencer.
¿Qué es Open Responses? ¿Qué es Open Responses? !¿Qué es Open Responses? Open Responses es una especificación abierta, publicada como un documento OpenAPI 3.1, que describe una forma de solicitud y respuesta para llamar a modelos de lenguaje a través de proveedores. Se basa en la API de Respuestas de OpenAI: envías model, input y opcional tools a POST /v1/responses, y obtienes elementos tipados y eventos de streaming semánticos en lugar de un formato específico de proveedor. OpenAI lanzó Open Responses el 15-01-2026, está licenciado bajo Apache 2.0, y el 22-10-2026 OpenAI lo contribuyó a la Agentic AI Foundation (AAIF), el organismo de la Linux Foundation que también alberga MCP. {% cta apidog.com %} Prueba Apidog hoy {% endcta %} Ese último paso es la noticia: la especificación ahora cuenta con un acta técnica, un comité directivo y un hogar neutral. Esta publicación cubre lo que define, quién lo implementa, lo que cambia el movimiento de AAIF y cómo verificar si un endpoint al que dependes cumple con ella. Si eres nuevo en la API subyacente, comienza con cómo usar la API de Respuestas de OpenAI. Lo que define Open Responses La especificación describe el problema de forma clara: los proveedores han convergido en los mismos bloques de construcción (mensajes, llamadas a herramientas, streaming, entrada multimodal), pero cada uno los codifica de manera diferente. Open Responses elige una codificación y la escribe. El actual documento OpenAPI es la versión 2026-04-24 y cubre una pequeña superficie: | Operación | Qué hace | | --- | --- | | POST /responses (createResponse) | Crear una respuesta, con streaming o no | | WebSocket en /responses | Mismo modelo de respuesta sobre un socket persistente (añadido 2026-04-24) | | POST /responses/compact (compactResponse) | Retornar una ventana de entrada compactada para conversaciones largas | El cuerpo de la solicitud acepta los campos que esperarías si has utilizado la API de OpenAI: model, input, instructions, tools, tool_choice, stream, store, previous_response_id, reasoning, text, truncation, temperature, top_p, max_output_tokens, prompt_cache_key y algunos más. El objeto de respuesta (ResponseResource) lleva id, status, output, usage, error y un eco de los ajustes que enviaste. El documento define 108 esquemas en total, la mayoría son tipos de elemento y eventos de streaming. Tres ideas sustentan el diseño. Los elementos son la unidad de contexto Todo lo que el modelo lee o produce es un elemento: un message, una function_call, una function_call_output, un elemento reasoning. Los elementos son bidireccionales, por lo que la salida de un turno puede ser devuelta directamente como entrada para el siguiente. Cada tipo de elemento se discrimina por su campo type y tiene su propio esquema. Los elementos también son máquinas de estados: cada uno pasa de in_progress a completed o incomplete (el presupuesto de tokens se agotó), y un elemento incomplete debe ser el último emitido, con toda la respuesta marcada como incompleta. Un estado no dice nada sobre si el servidor almacenó el elemento; la persistencia es una preocupación separada. El streaming son eventos semánticos, no deltas brutos Cuando configuras stream: true, el servidor debe responder con Content-Type: text/event-stream y una secuencia de eventos definida. Un elemento de salida comienza con response.output_item.added; el texto dentro de él llega como response.content_part.added, luego eventos repetidos response.output_text.delta, después response.output_text.done y response.content_part.done; el elemento se cierra con response.output_item.done. El stream debe terminar con un evento terminal: response.completed, response.failed o response.incomplete. Un [DONE] final es opcional, y los clientes deben manejar un stream que finalice sin él. !Diagrama del orden de eventos de streaming de Open Responses: output_item.added, content_part.added, output_text.delta repetido, output_text.done, content_part.done, output_item.done, y luego un evento terminal completed, failed o incomplete Esto es más importante para el código del cliente: si dos proveedores emiten los mismos eventos en el mismo orden, un solo analizador SSE funciona para ambos. Nuestra guía de pruebas de SSE muestra cómo inspeccionar estos streams evento por evento. Un núcleo estable con extensiones con espacio de nombres Los proveedores pueden añadir sus propios tipos de elementos, herramientas y eventos de streaming, pero deben prefijarlos con un slug de proveedor. El ejemplo propio de la especificación es openai:web_search_call. Un cliente que no reconozca un tipo prefijado puede saltárselo sin romper. Así es como la especificación permanece portátil mientras las herramientas alojadas como la búsqueda web o la búsqueda de archivos siguen siendo características de proveedores. El resto del contrato Hay algunas reglas más que vale la pena conocer antes de construir sobre la especificación: - Dos tipos de herramientas. Las herramientas alojadas externamente (funciones, servidores MCP) se ejecutan fuera del proveedor; para funciones, el modelo emite una function_call, tú la ejecutas y envías de vuelta una `function_call_outputere text/event-stream terminando en response.completed; uno sin "model" que espere un error 4xx con un campo error.type. Ejecútalos y resume cualquier fallo. El agente lee los esquemas, valida sus payloads antes de escribir algo y ejecuta con un Comité Directivo Técnico. Está licenciado bajo Apache 2.0. ¿Anthropic apoya Open Responses? Anthropic no está entre los partidarios nombrados. Contribuyó con Agent Skills a AAIF el mismo día, pero la interfaz nativa de Claude sigue siendo Messages API. ¿Dónde está el archivo de la especificación? En https://www.openresponses.org/openapi/openapi.json, con lanzamientos fechados en el repositorio de GitHub. Siguiente paso Elige el endpoint que tu producto llama más, ejecuta las pruebas de aceptación en el navegador contra él e importa la especificación en Apidog para que
Open Responses란 무엇인가? Open Responses는 OpenAPI 3.1 문서로 게시된 공개 명세로, 여러 제공자에 걸쳐 언어 모델을 호출하기 위한 하나의 요청 및 응답 형태를 설명합니다. 이는 OpenAI Responses API를 기반으로 합니다. 즉, model, input 그리고 선택적 tools를 POST /v1/responses로 보내면, 제공자별 형식 대신 타입이 지정된 항목과 시맨틱 스트리밍 이벤트를 돌려받습니다. OpenAI는 2026-01-15에 Open Responses를 출시했으며, Apache 2.0 라이선스로 배포되고, 2026-10-22에 OpenAI는 이를 MCP도 호스팅하는 Linux Foundation 산하 기구인 Agentic AI Foundation(AAIF)에 기증했습니다. {% cta apidog.com %} 지금 Apidog를 사용해 보세요 {% endcta %} 마지막 단계가 바로 뉴스입니다. 이 명세는 이제 기술 헌장, 운영 위원회, 그리고 중립적인 소속처를 갖게 되었습니다. 이 글에서는 명세가 정의하는 내용, 누가 구현하는지, AAIF 이전이 무엇을 바꾸는지, 그리고 의존하는 엔드포인트가 명세를 준수하는지 확인하는 방법을 다룹니다. 기반 API가 처음이라면 OpenAI Responses API 사용 방법부터 시작하세요. Open Responses가 정의하는 것 명세는 문제를 명확히 설명합니다. 제공자들은 동일한 구성 요소(메시지, 도구 호출, 스트리밍, 멀티모달 입력)로 수렴했지만, 각자 다르게 인코딩합니다. Open Responses는 하나의 인코딩을 골라 문서로 기록합니다. 현재 OpenAPI 문서는 버전 2026-04-24이며 작은 범위를 다룹니다. | 오퍼레이션 | 수행하는 작업 | | --- | --- | | POST /responses (createResponse) | 스트리밍 여부와 관계없이 응답 생성 | | /responses의 WebSocket | 지속 소켓을 통한 동일한 응답 모델(2026-04-24 추가) | | POST /responses/compact (compactResponse) | 긴 대화를 위한 압축된 입력 윈도 반환 | 요청 본문은 OpenAI API를 사용해 봤다면 예상할 수 있는 필드들을 받습니다. model, input, instructions, tools, tool_choice, stream, store, previous_response_id, reasoning, text, truncation, temperature, top_p, max_output_tokens, prompt_cache_key 그리고 몇 가지 더 있습니다. 응답 객체(ResponseResource)는 id, status, output, usage, error와 함께 보낸 설정을 그대로 되돌려줍니다. 문서는 총 108개의 스키마를 정의하며, 대부분 항목 및 스트리밍 이벤트 타입입니다. 설계를 이끄는 세 가지 개념이 있습니다. 항목은 컨텍스트의 단위 모델이 읽거나 생성하는 모든 것은 항목입니다. message, function_call, function_call_output, reasoning 항목 등입니다. 항목은 양방향이므로 한 턴의 출력을 다음 턴의 입력으로 바로 되돌려 보낼 수 있습니다. 각 항목 타입은 type 필드로 구분되며 고유한 스키마를 갖습니다. 항목은 또한 상태 머신입니다. 각 항목은 in_progress에서 completed 또는 incomplete(토큰 예산 소진)로 이동하며, incomplete 항목은 반드시 마지막으로 방출되어야 하고 전체 응답은 incomplete로 표시됩니다. 상태는 서버가 해당 항목을 저장했는지 여부를 말해주지 않습니다. 지속성은 별개의 문제입니다. 스트리밍은 원시 델타가 아닌 시맨틱 이벤트 stream: true를 설정하면 서버는 Content-Type: text/event-stream과 정의된 이벤트 시퀀스로 응답해야 합니다. 출력 항목은 response.output_item.added로 시작하고, 그 안의 텍스트는 response.content_part.added로 도착한 다음 반복되는 response.output_text.delta 이벤트, 그리고 response.output_text.done과 response.content_part.done으로 이어집니다. 항목은 response.output_item.done으로 닫힙니다. 스트림은 반드시 종료 이벤트로 끝나야 합니다. 즉, response.completed, response.failed 또는 response.incomplete입니다. 후행 [DONE]은 선택 사항이며, 클라이언트는 그것 없이 끝나는 스트림도 처리해야 합니다. !Diagram of the Open Responses streaming event order: output_item.added, content_part.added, output_text.delta repeated, output_text.done, content_part.done, output_item.done, then a terminal completed, failed or incomplete event 이것은 클라이언트 코드에서 가장 중요합니다. 두 제공자가 동일한 이벤트를 동일한 순서로 방출한다면 하나의 SSE 파서로 둘 다 처리할 수 있습니다. 저희 SSE 테스트 가이드는 이러한 스트림을 이벤트별로 검사하는 방법을 보여줍니다. 네임스페이스가 적용된 확장을 갖춘 안정적인 코어 제공자는 자체 항목 타입, 도구, 스트리밍 이벤트를 추가할 수 있지만, 제공자 슬러그를 접두사로 붙여야 합니다. 명세 자체의 예시는 openai:web_search_call입니다. 접두사가 붙은 타입을 인식하지 못하는 클라이언트는 문제없이 건너뛸 수 있습니다. 이렇게 해서 웹 검색이나 파일 검색 같은 호스팅 도구가 제공자 기능으로 남으면서도 명세는 이식성을 유지합니다. 계약의 나머지 부분 명세 위에 무언가를 구축하기 전에 알아둘 만한 몇 가지 규칙이 더 있습니다. - 두 종류의 도구. 외부 호스팅 도구(함수, MCP 서버)는 제공자 외부에서 실행됩니다. 함수의 경우 모델이 function_call을 방출하면, 당신이 실행하고 일치하는 call_id와 함께 function_call_output을 돌려보냅니다. 내부 호스팅 도구(예: OpenAI의 파일 검색)는 제어권을 되돌려주지 않고 제공자 내부에서 실행됩니다. - tool_choice와 allowed_tools. tool_choice는 auto(기본값), required, none, 또는 하나의 함수를 지정하는 객체를 받습니다. allowed_tools는 모든 도구를 보여주면서도 모델이 호출할 수 있는 도구를 제한하므로, tools 배열을 수정해 캐시된 프롬프트를 무효화하지 않아도 됩니다. 서버는 이를 강제 한도로 적용해야 합니다. - previous_response_id. 서버는 새 요청을 previous_response.input + previous_response.output + input 순서로 처리해야 하므로 트랜스크립트를 다시 보내지 않아도 됩니다. - Reasoning 항목은 원시 content, 불투명한 encrypted_content 블롭, 사용자 안전 summary, 또는 이들의 조합을 담을 수 있습니다. - 오류는 type(server_error, invalid_request, not_found, model_error, too_many_requests)과 함께 code, param, message를 담습니다. 스트림 중간에서는 오류 뒤에 response.failed가 옵니다. 2026-04-24 개정판(변경 로그)은 WebSocket 전송을 추가했습니다. 각 턴은 response.create 메시지로 시작하고, 하나의 연결은 한 번에 하나의 응답을 처리하며, 연결은 60분으로 제한됩니다(오류 코드 websocket_connection_limit_reached). 그리고 store: false 연속성은 연결 로컬 메모리에 유지되며, 그 상태가 사라지면 previous_response_not_found로 실패합니다. 같은 개정판은 /responses/compact, 어시스턴트 메시지의 선택적 phase 필드(commentary 또는 final_answer)를 추가하고 logprobs를 선택 사항으로 만들었습니다. Open Responses vs Chat Completions Chat Completions는 여전히 가장 널리 복제된 LLM 인터페이스입니다. 차이는 형태에 있습니다. Chat Completions는 메시지를 담은 choices를 반환하고 도구 호출은 그 안에 숨겨져 있는 반면, Responses 모델은 타입이 지정된 항목의 평평한 목록을 반환합니다. 추론 단계, 세 번의 도구 호출, 최종 메시지는 각자의 상태를 가진 별개의 순서 있는 객체가 되어 에이전트 루프에 더 적합합니다. ![Side-by-side diagram: Chat Completions nests content and three tool_calls inside choices[0].message, while Open Responses returns a flat output list of reasoning, three function_call items and a message, each with a status](assets.apidog.com) 저희는 Chat Completions vs Anthropic Messages vs Responses API에서 실제 요청과 함께 세 가지 지배적인 형식을 나란히 비교했습니다. OpenAI 자체의 표면 중에서 선택하고 있다면 Agents API vs Responses API vs Agents SDK 분석이 Responses의 위치를 다룹니다. 누가 구현하는가 지지자 목록에는 OpenAI와 함께 AWS Bedrock, Databricks, Hugging Face, LM Studio, Nvidia, Ollama, OpenRouter, Red Hat, Vercel, vLLM이 포함됩니다. Anthropic과 Google은 명시된 지지자에 없으며, 둘 다 여전히 자체 네이티브 형식을 제공합니다. "지원"은 넓은 범위를 포괄하므로, 사용하는 런타임의 세부 사항을 확인하세요. - Ollama는 v0.13.3에서 POST /v1/responses를 추가했습니다. 호환성 문서는 "비상태 유지(non-stateful) 형태만 지원됩니다"라고 말합니다. 스트리밍, 함수 도구, 추론 요약은 작동하지만 previous_response_id, conversation, truncation은 작동하지 않습니다. 기록은 직접 다시 보내야 합니다. - LM Studio는 버전 0.3.39에서 http://localhost:1234/v1/responses 엔드포인트를 호환되게 만들었으며, previous_response_id, 비전 모델용 원격 이미지 URL, logprobs를 포함합니다. 설정은 저희 LM Studio 가이드를 참고하세요. 규모를 가늠하기 위해, API Evangelist가 9월 13일에 기준선을 측정했습니다. 읽을 수 있는 OpenAPI 문서를 게시하며 OpenAI 호환성을 주장하는 120개 제공자 중 26개가 POST /responses를 선언했고, POST /chat/completions를 선언한 곳은 105개였습니다. 이 기준선의 요점은 중립적 거버넌스가 그 숫자를 움직이는지 측정하는 것입니다. Agentic AI Foundation 이전이 바꾸는 것 AAIF는 2026-10-22에 산호세에서 열린 AGNTCon + MCPCon North America에서 다른 세 가지 신규 프로젝트와 함께 Open Responses를 발표했습니다. 세 프로젝트는 Agent Skills(Anthropic 제공), OpenEnv(Hugging Face 제공), OpenSandbox(Alibaba 제공)입니다. 이로써 AAIF는 첫해에 MCP, Agent2Agent 프로토콜, agents.md, goose, agentgateway, Agent Router에 이어 10개의 호스팅 프로젝트를 갖게 되었습니다. 이들이 어떻게 맞물리는지 정리 중이라면 저희 MCP vs A2A 해설이 좋은 출발점입니다. 바뀌는 것: - 거버넌스. 이 프로젝트는 이제 "Open Responses a Series of LF Projects, LLC"이며, 2026-10-21에 기술 헌장을 채택했습니다. 초기에는 프로젝트 유지관리자로 구성된 기술 운영 위원회(Technical Steering Committee)가 기술 결정을 소유하며, 헌장을 따르는 누구나 참여할 수 있습니다. - 다른 벤더에 대한 신뢰성. 한 회사가 소유한 명세는 제품입니다. 재단 아래의 명세는 경쟁사가 경쟁자를 따르는 것처럼 보이지 않고 채택하기 더 쉽습니다. 바뀌지 않는 것: - OpenAI 자체 API. api.openai.com의 Responses API는 자체 기능과 릴리스 일정을 유지합니다. Open Responses는 이식 가능한 코어를 설명하며, OpenAI 특정 도구는 openai: 접두사 뒤에 남습니다. - 와이어 형식. 이전과 함께 새로운 명세 버전이 나오지 않았습니다. 최신 릴리스는 여전히 2026-04-24이며, 날짜가 붙은 릴리스는 불변입니다. - 준수 여부. 지지자 목록에 있다고 해서 엔드포인트가 테스트를 통과하는 것은 아닙니다. 아직 통과/실패 지표를 게시하는 곳은 없으므로, 의존하는 엔드포인트는 직접 확인해야 합니다. 인수 테스트로 엔드포인트 확인하기 이 프로젝트는 자체 인수 테스트를 제공합니다. 준수 페이지는 브라우저에서 모든 베이스 URL, 모델, 키에 대해 10개의 테스트를 실행합니다. 기본 텍스트 응답, 스트리밍, 시스템 프롬프트, 도구 호출, 이미지 입력, 멀티턴 기록, 어시스턴트 phase 레이블, 압축 엔드포인트, 그리고 model이 빠진 compact 요청에 대한 부정 테스트입니다. WebSocket 테스트 7개(순차 턴, store: false 연속성, 재연결 복구, 실패한 연속성 이후 캐시 제거)는 CLI에서만 실행됩니다. git clone https://github.com/openresponses/openresponses cd openresponses && bun install bun run test:compliance --base-url http://localhost:11434/v1 --api-key ollama 각 HTTP 요청과 각 WebSocket 턴에는 30초의 기한이 주어지며, 타임아웃은 해당 테스트만 실패시킵니다. Ollama 같은 비상태 유지 런타임은 설계상 연속성 테스트에서 실패할 것으로 예상하세요. Apidog CLI로 코딩 에이전트가 테스트하게 하기 인수 테스트는 서버가 오늘 명세를 따르는지 알려줍니다. 앱이 배포할 때마다, Ollama를 업그레이드할 때마다, 제공자를 전환할 때마다 호출하는 엔드포인트를 감시하지는 않습니다. 이를 위해 명세를 Apidog 프로젝트로 가져오고, 코딩 에이전트가 Apidog CLI로 회귀 테스트를 작성하고 실행하게 하세요. CLI와 에이전트 스킬을 한 번 설치하세요. npm install -g apidog-cli@latest apidog auth login --with-token <YOUR_TOKEN> npx -y skills add https://apidog.com # pick your agent when prompted 그런 다음 Claude Code, Codex 또는 Cursor에 프롬프트 하나를 주세요. Download https://www.openresponses.org/openapi/openapi.json and import it into Apidog project <id>. Create an environment "local-ollama" with base URL http://localhost:11434/v1. Add test cases for POST /responses: one that expects 200, status "completed" and an output item of type "message"; one with stream: true that expects text/event-stream ending in response.completed; one without "model" that expects a 4xx error with an error.type field. Run them and summarize any failures. 에이전트는 스키마를 읽고, 작성하기 전에 페이로드를 검증하며, 케이스를 실행합니다. curl -sLO https://www.openresponses.org/openapi/openapi.json apidog import --project <id> --format openapi --file ./openapi.json apidog environment create local-ollama --project <id> --base-url http://localhost:11434/v1 apidog cli-schema get test-case-create apidog cli-schema validate test-case-create --file case.json apidog test-case create --project <id> --file case.json apidog run --test-case <caseId> --project <id> -e <envId> -r cli,json 명세의 servers 항목은 https://api.openai.com/v1을 가리키므로, 제공자마다 환경을 하나씩 추가하고 같은 케이스를 각각에 대해 실행하세요. 그것이 이식성 주장을 테스트하는 방법입니다. apidog run ... -r junit 라인을 파이프라인에 넣어 필드를 누락시키는 런타임 업그레이드가 빌드를 실패시키도록 하세요(CI/CD 가이드). Claude Code에서의 Apidog CLI는 에이전트 설정을 자세히 다룹니다. FAQ Open Responses는 OpenAI Responses API와 같은 것인가요? 아닙니다. Open Responses는 그것에서 파생된 명세입니다. OpenAI의 Responses API는 OpenAI 전용 기능이 추가된 하나의 구현이며, Ollama, LM Studio, vLLM은 또 다른 구현입니다. 이제 Open Responses를 누가 소유하나요? 2026-10-22부터 Linux Foundation 산하 Agentic AI Foundation 프로젝트이며, 기술 운영 위원회와 함께 LF Projects 시리즈로 운영됩니다. Apache 2.0 라이선스입니다. Anthropic이 Open Responses를 지원하나요? Anthropic은 명시된 지지자에 없습니다. 같은 날 AAIF에 Agent Skills를 기증했지만, Claude의 네이티브 인터페이스는 여전히 Messages API입니다. 명세 파일은 어디에 있나요? https://www.openresponses.org/openapi/openapi.json에 있으며, 날짜가 붙은 릴리스는 GitHub 저장소에 있습니다. 다음 단계 제품이 가장 많이 호출하는 엔드포인트 하나를 골라 브라우저 인수 테스트를 실행하고, 명세를 Apidog로 가져와 에이전트가 모든 배포마다 그 검사를 계속 실행하도록 하세요. 시작하려면 Apidog를 다운로드하세요.
AAIF に加わった Open Responses を Amazon Bedrock で試す 先端技術開発グループ(WAND)の伊賀です。 2026年10月22日、Linux Foundation 傘下の Agentic AI Foundation(AAIF)に、Open Responses が新しいプロジェクトとして加わりました(Linux Foundation のプレスリリース)。 Open Responses は複数の LLM プロバイダーを同じ形で呼び出すためのオープンな仕様です。 同じ日に AWS も Open Responses への関わりと Amazon Bedrock での対応を紹介しています(Open Responses Joins AAIF with AWS Support)。 内容は 2026年10月時点のものです。 Open Responses とは Open Responses は OpenAI の Responses API をもとにした LLM API の共通仕様です(openresponses.org)。 主に次の 3 つを定めています(README)。 リクエストとレスポンスの共通スキーマ ストリーミングで流れるイベントの種類と順序 ツール呼び出しの手順 仕様は日付つきのバージョンとして公開されていて、最新は 2026-04-24 です。 GitHub リポジトリには仕様の本文と OpenAPI 定義に加えて、API が仕様に沿っているかを確かめる準拠テストが入っています。 プロジェクトは OpenAI が寄贈したもので、今後は AAIF の下で運営されます。 同じ日に Anthropic の Agent Skills、Hugging Face の OpenEnv、Alibaba の OpenSandbox も加わり、AAIF のプロジェクトは MCP や A2A、AGENTS.md などとあわせて 10 個になりました。 共通の仕様が必要な理由 LLM の API はメッセージ、関数呼び出し、ツール利用、マルチモーダル入力といった似た概念に収束してきました。 しかし OpenAI の Responses API、Anthropic の Messages API、Google の Gemini API では、同じことをするにもプロバイダーごとに書き方が異なります。 そのため、複数のモデルを比べたり切り替えたりするには、プロバイダーごとの変換コードを書いて保守する必要がありました。 Open Responses に沿ったエンドポイントであれば、クライアントのコードはそのままで、接続先とモデル名を変えるだけで済みます。 AAIF のブログではこれを「エンドポイントとモデル識別子が、コードの分岐ではなく設定値になる」と表現しています(What Open Responses Changes for AI Developers)。 この形式のエンドポイントは Bedrock のほかにもあり、AWS のブログは Ollama、vLLM、OpenRouter、Hugging Face を、AAIF のブログは Databricks Model Serving と Vercel AI Gateway を挙げています。 各社が独自の機能を出す余地も残されています。 仕様にないツールやアイテムは、openai:web_search_call のようにプロバイダー名を前に付けて定義します。 クライアントは知らない種類のアイテムやイベントを無視しても、標準の部分はそのまま処理できます。 仕様の考え方 仕様の本文は次の 4 つの考え方を軸にしています(Specification)。 エージェントループ:モデルがツール呼び出しを出力し、結果を受け取って推論を続ける流れを、共通の形で扱います アイテム:メッセージ、関数呼び出し、その実行結果、推論などを、type で区別するアイテムとして表します。アイテムは入力にも出力にも使えます 状態機械:レスポンスやアイテムは in_progress、completed、incomplete などの決まった状態を持ちます 意味のあるイベント:ストリーミングではテキストの差分をそのまま流さず、response.output_item.added や response.completed のように何が起きたかを表すイベントを流します ツールには関数や MCP サーバーのように実装がプロバイダーの外にあるものと、プロバイダーの中で実行が完結するものの 2 種類があります。 2026-04-24 バージョンでは接続を張ったまま使う WebSocket での呼び出しと、長い会話の文脈を圧縮する /responses/compact エンドポイントが追加されました(Changelog)。 AWS の関わり AWS は AAIF の Governing Board に加わっています。 Amazon Bedrock は 2025年12月から Responses API に対応していて、AWS のブログではその実装を「仕様が大規模な環境でどう動くかを示す、本番品質のリファレンス」とも紹介しています。 Bedrock で Responses API を使えるエンドポイントは 2 つあります(Responses API - Amazon Bedrock User Guide)。 エンドポイント ベース URL 位置づけ bedrock-runtime bedrock-runtime.{region}.amazonaws.com 推奨 bedrock-mantle bedrock-mantle.{region}.api.aws GPT OSS の Responses API など、mantle でしか使えないモデルや機能向け Responses API に対応しているのは、OpenAI の GPT 系と GPT OSS、xAI の Grok、Moonshot AI の Kimi K3、Google の Gemma 4、Z.AI の GLM 5.3 です(API compatibility)1。 Amazon Bedrock で動かしてみる us-east-1 の bedrock-runtime に、Open Responses の形でリクエストを送ってみます。 認証には Bedrock の API キーを使います。有効期限の短いキーは AWS の認証情報から aws-bedrock-token-generator で発行できます。 基本のリクエストとレスポンス curl で 1 回呼び出します。 store: false は会話を Bedrock 側に保存しないための指定です。 export OPENAI_BASE_URL=bedrock-runtime.us-east-1.amazonaws.com export OPENAI_API_KEY=<Bedrock の API キー> curl -sS "$OPENAI_BASE_URL/responses" \ -H "Authorization: Bearer $OPENAI_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "global.openai.gpt-5.6-sol", "input": "Open Responses を一文で説明してください。", "store": false }' レスポンスから主要な部分を抜き出すと、次のようになります。 { "id": "resp_fjc2ydhllu3zscoaqtqem3wpley2fas4u7dghhguugzipayo3pcq", "object": "response", "status": "completed", "model": "global.openai.gpt-5.6-sol", "output": [ { "type": "reasoning", "id": "rs_8c6287cb8f975b00bebcc6c9a47a5487", "encrypted_content": "(省略)", "content": [], "summary": [] }, { "type": "message", "id": "msg_4629e516851f545db7fd68af8e29b3fd", "role": "assistant", "status": "completed", "phase": "final_answer", "content": [ { "type": "output_text", "text": "Open Responsesは、異なるAIモデルやエージェントの応答APIを共通形式で扱えるようにするオープンな標準仕様です。", "annotations": [] } ] } ], "usage": { "input_tokens": 15, "output_tokens": 219, "output_tokens_details": { "reasoning_tokens": 177 }, "total_tokens": 234 } } output はアイテムの配列で、推論の reasoning アイテムと、回答の message アイテムが順に並んでいます。 回答の本文は message アイテムの content にある output_text に入ります。 phase は 2026-04-24 バージョンで追加された任意のフィールドで、最終回答(final_answer)か途中の説明(commentary)かを表します。 レスポンス全体{ "background": false, "billing": { "payer": "developer" }, "completed_at": 1792717922, "created_at": 1792717919, "error": null, "frequency_penalty": 0.0, "id": "resp_fjc2ydhllu3zscoaqtqem3wpley2fas4u7dghhguugzipayo3pcq", "incomplete_details": null, "instructions": null, "max_output_tokens": null, "max_tool_calls": null, "metadata": {}, "model": "global.openai.gpt-5.6-sol", "object": "response", "output": [ { "content": [], "encrypted_content": "(省略)", "id": "rs_8c6287cb8f975b00bebcc6c9a47a5487", "summary": [], "type": "reasoning" }, { "content": [ { "annotations": [], "logprobs": [], "text": "Open Responsesは、異なるAIモデルやエージェントの応答APIを共通形式で扱えるようにするオープンな標準仕様です。", "type": "output_text" } ], "id": "msg_4629e516851f545db7fd68af8e29b3fd", "phase": "final_answer", "role": "assistant", "status": "completed", "type": "message" } ], "parallel_tool_calls": true, "presence_penalty": 0.0, "previous_response_id": null, "prompt_cache_key": null, "prompt_cache_retention": "in_memory", "reasoning": { "summary": null, "effort": "medium", "context": "all_turns" }, "safety_identifier": null, "service_tier": "default", "status": "completed", "store": false, "temperature": 1.0, "text": { "format": { "type": "text" }, "verbosity": "medium" }, "tool_choice": "auto", "tools": [], "top_logprobs": 0, "top_p": 0.98, "truncation": "disabled", "usage": { "input_tokens": 15, "input_tokens_details": { "cache_write_tokens": 0, "cached_tokens": 0 }, "output_tokens": 219, "output_tokens_details": { "reasoning_tokens": 177 }, "total_tokens": 234 }, "user": null, "moderation": null } ストリーミングのイベント "stream": true を付けると、Server-Sent Events でイベントが順に届きます。 「Say hello in three words.」と送ったときのイベントの並びは次のとおりでした。 response.created response.in_progress response.output_item.added reasoning アイテムの開始 response.output_item.done reasoning アイテムの完了 response.output_item.added message アイテムの開始 response.content_part.added response.output_text.delta "Hello" response.output_text.delta " there" response.output_text.delta "," response.output_text.delta " friend" response.output_text.delta "!" response.output_text.done response.content_part.done response.output_item.done message アイテムの完了 response.completed レスポンス全体の状態の変化(response.created → response.in_progress → response.completed)の中に、アイテムごとの「追加 → 差分 → 完了」が入れ子になっています。 文字を順に画面へ表示したいだけなら、response.output_text.delta の delta をつなげれば足ります。 受信したイベント(一部のフィールドを省略)data: {"type": "response.created", "response": {"id": "resp_f4wjs5jc4gfuomhyckvwc2o7zlrmxx4e2ohxyyupkph7imdpjhaq", "status": "in_progress", "output": []}, "sequence_number": 0} data: {"type": "response.in_progress", "response": {"id": "resp_f4wjs5jc4gfuomhyckvwc2o7zlrmxx4e2ohxyyupkph7imdpjhaq", "status": "in_progress", "output": []}, "sequence_number": 1} data: {"type": "response.output_item.added", "item": {"content": [], "encrypted_content": "(省略)", "id": "rs_949298e3722a55969bf6fb415bcc857e", "summary": [], "type": "reasoning"}, "output_index": 0, "sequence_number": 2} data: {"type": "response.output_item.done", "item": {"content": [], "encrypted_content": "(省略)", "id": "rs_949298e3722a55969bf6fb415bcc857e", "summary": [], "type": "reasoning"}, "output_index": 0, "sequence_number": 3} data: {"type": "response.output_item.added", "item": {"content": [], "id": "msg_d2cdd7ec87f75d3bbf1bb4ae2effb0b6", "phase": "final_answer", "role": "assistant", "status": "in_progress", "type": "message"}, "output_index": 1, "sequence_number": 4} data: {"type": "response.content_part.added", "content_index": 0, "item_id": "msg_d2cdd7ec87f75d3bbf1bb4ae2effb0b6", "output_index": 1, "part": {"annotations": [], "text": "", "type": "output_text"}, "sequence_number": 5} data: {"type": "response.output_text.delta", "content_index": 0, "delta": "Hello", "item_id": "msg_d2cdd7ec87f75d3bbf1bb4ae2effb0b6", "output_index": 1, "sequence_number": 6} data: {"type": "response.output_text.delta", "content_index": 0, "delta": " there", "item_id": "msg_d2cdd7ec87f75d3bbf1bb4ae2effb0b6", "output_index": 1, "sequence_number": 7} data: {"type": "response.output_text.delta", "content_index": 0, "delta": ",", "item_id": "msg_d2cdd7ec87f75d3bbf1bb4ae2effb0b6", "output_index": 1, "sequence_number": 8} data: {"type": "response.output_text.delta", "content_index": 0, "delta": " friend", "item_id": "msg_d2cdd7ec87f75d3bbf1bb4ae2effb0b6", "output_index": 1, "sequence_number": 9} data: {"type": "response.output_text.delta", "content_index": 0, "delta": "!", "item_id": "msg_d2cdd7ec87f75d3bbf1bb4ae2effb0b6", "output_index": 1, "sequence_number": 10} data: {"type": "response.output_text.done", "content_index": 0, "item_id": "msg_d2cdd7ec87f75d3bbf1bb4ae2effb0b6", "output_index": 1, "sequence_number": 11, "text": "Hello there, friend!"} data: {"type": "response.content_part.done", "content_index": 0, "item_id": "msg_d2cdd7ec87f75d3bbf1bb4ae2effb0b6", "output_index": 1, "part": {"annotations": [], "text": "Hello there, friend!", "type": "output_text"}, "sequence_number": 12} data: {"type": "response.output_item.done", "item": {"content": [{"annotations": [], "text": "Hello there, friend!", "type": "output_text"}], "id": "msg_d2cdd7ec87f75d3bbf1bb4ae2effb0b6", "phase": "final_answer", "role": "assistant", "status": "completed", "type": "message"}, "output_index": 1, "sequence_number": 13} data: {"type": "response.completed", "response": {"id": "resp_f4wjs5jc4gfuomhyckvwc2o7zlrmxx4e2ohxyyupkph7imdpjhaq", "status": "completed", "output": "(省略)"}, "sequence_number": 14} data: [DONE] ツール呼び出しとエージェントループ 関数ツールを渡すと、モデルはツールが必要と判断したときに、回答の代わりに function_call アイテムを返します。 開発者側で関数を実行し、その結果を function_call_output アイテムとして返すと、モデルは結果を踏まえて回答します。 この流れが仕様でいうエージェントループです。 東京の天気を聞いたときのやり取りは、次のようになりました。 1 回目のリクエスト input : message(ユーザーの質問) 1 回目のレスポンス output: function_call get_weather {"city":"東京"} 2 回目のリクエスト input : message, function_call, function_call_output 2 回目のレスポンス output: message 「東京の現在の天気は晴れ、気温は18℃です。」 1 回目に出力された function_call アイテムは、そのまま 2 回目の入力に積んでいます。 アイテムが入力にも出力にも使えるので、クライアントは出力を加工せずに会話を続けられます。 今回は store: false にしているため、2 回目では 1 回目の入出力をすべて送り直しています。 store: true にすれば、previous_response_id で前のレスポンスを指定して、新しい入力だけを送る形にもできます。 Python と httpx で書いたコードは次のとおりです。 エージェントループのコード(Python)import json import os import httpx BASE_URL = os.environ["OPENAI_BASE_URL"] API_KEY = os.environ["OPENAI_API_KEY"] MODEL = os.environ.get("MODEL", "global.openai.gpt-5.6-sol") TOOLS = [ { "type": "function", "name": "get_weather", "description": "指定した都市の現在の天気を返す", "parameters": { "type": "object", "properties": {"city": {"type": "string"}}, "required": ["city"], }, } ] def get_weather(city: str) -> dict: return {"city": city, "weather": "晴れ", "temperature_c": 18} # 検証用の固定値 items = [{"type": "message", "role": "user", "content": "東京の天気を教えて"}] while True: r = httpx.post( f"{BASE_URL}/responses", headers={"Authorization": f"Bearer {API_KEY}"}, json={"model": MODEL, "input": items, "tools": TOOLS, "store": False}, timeout=120, ) r.raise_for_status() output = r.json()["output"] items += output # 出力されたアイテムを、そのまま次の入力に積む calls = [i for i in output if i["type"] == "function_call"] if not calls: break for call in calls: result = get_weather(**json.loads(call["arguments"])) items.append( { "type": "function_call_output", "call_id": call["call_id"], "output": json.dumps(result, ensure_ascii=False), } ) message = next(i for i in output if i["type"] == "message") print(message["content"][0]["text"]) ループの最後に積み上がったアイテム[ { "type": "message", "role": "user", "content": "東京の天気を教えて" }, { "arguments": "{\"city\":\"東京\"}", "call_id": "call_899965767e1351f0ad9eedeee141713c", "id": "fc_8bae4d13c8af5eeabe698af52b86aafd", "name": "get_weather", "status": "completed", "type": "function_call" }, { "type": "function_call_output", "call_id": "call_899965767e1351f0ad9eedeee141713c", "output": "{\"city\": \"東京\", \"weather\": \"晴れ\", \"temperature_c\": 18}" }, { "content": [ { "annotations": [], "logprobs": [], "text": "東京の現在の天気は晴れ、気温は18℃です。", "type": "output_text" } ], "id": "msg_67235d5875da5839bc139e6e43cdecb5", "phase": "final_answer", "role": "assistant", "status": "completed", "type": "message" } ] モデルを差し替える 上のコードの MODEL だけを変えて、ベンダーの違うモデルで同じループを動かしました。 GPT OSS は bedrock-mantle でしか Responses API を使えないため、接続先も切り替えています。 モデル ベンダー エンドポイント 1 回目の output 2 回目の output global.openai.gpt-5.6-sol OpenAI bedrock-runtime function_call message global.xai.grok-4.7 xAI bedrock-runtime reasoning, function_call reasoning, message global.moonshotai.kimi-k3 Moonshot AI bedrock-runtime reasoning, function_call reasoning, message openai.gpt-oss-120b OpenAI bedrock-mantle reasoning, function_call message 4 モデルとも、コードを変えずに get_weather を呼び、その結果から晴れで気温は 18℃ と答えました。 推論の返し方はモデルによって違いました。 Grok 4.7 は推論を暗号化した encrypted_content として返し、Kimi K3 は推論のテキストを content に入れて返しました。 基本のリクエストで GPT-5.6 Sol が返した reasoning アイテムも、Grok 4.7 と同じ暗号化した形でした。 仕様では、生の推論、暗号化した推論、推論の要約のどれを返すかはプロバイダーが選べます。 どのモデルでもアイテムの種類は reasoning なので、クライアントは中身を表示するかどうかだけを決めればよく、次の入力にはアイテムをそのまま積み直せます。 reasoning アイテムの違い(Grok 4.7 と Kimi K3) Grok 4.7 の reasoning アイテムです。 { "content": [], "encrypted_content": "(省略)", "id": "rs_ce42a11eac045f66a050ac8795cd2dee", "summary": [], "type": "reasoning" } Kimi K3 の reasoning アイテムです。 { "content": [ { "text": "The weather tool returned:\n- City: 東京 (Tokyo)\n- Weather: 晴れ (Sunny/Clear)\n- Temperature: 18°C\n\nI should respond in Japanese since the user asked in Japanese. I'll give a natural, friendly response with the weather information.", "type": "reasoning_text" } ], "id": "rs_2709a15cc20a5e899c4d2d98d2c61d68", "summary": [], "type": "reasoning" } 準拠テストを Bedrock に向けて動かす リポジトリの準拠テストは Web 版(openresponses.org)と同じもので、CLI からも実行できます。 ただし WebSocket のテストは、ブラウザから認証ヘッダーを付けられないため、CLI でしか動きません。 実行には Bun が必要で、ベース URL、API キー、モデル名を渡せば動きます。 git clone openresponses/openresponses cd openresponses bun install bun run test:compliance \ --base-url "$OPENAI_BASE_URL" \ --api-key "$OPENAI_API_KEY" \ --model global.openai.gpt-5.6-sol テストは 17 件あり、基本の応答、ストリーミング、システムプロンプト、ツール呼び出し、画像入力、複数ターンの会話に加えて、2026-04-24 バージョンで追加された WebSocket、compact、phase も対象です。 GPT-5.6 Sol では 17 件中 15 件が通り、WebSocket での応答や会話の継続も確認できました。 実行結果(GPT-5.6 Sol、途中経過の表示を省略)Running compliance tests against: bedrock-runtime.us-east-1.amazonaws.com Model: global.openai.gpt-5.6-sol ✓ Response Output Phase Schema ✓ Compaction Missing Required Model (676ms) ✗ WebSocket Missing Previous Response (992ms) [1 events] ✗ Expected previous_response_not_found but got model_not_found ✓ Basic Text Response (1139ms) ✓ Image Input (1150ms) ✓ Multi-turn Conversation (1156ms) ✓ Tool Calling (1158ms) ✓ Streaming Response (1290ms) [22 events] ✓ System Prompt (1283ms) ✓ Assistant Message Phase (1311ms) ✓ Compaction Endpoint (1435ms) ✓ WebSocket Continuation (2336ms) [19 events] ✓ WebSocket Response (2359ms) [13 events] ✓ WebSocket Sequential Responses (2397ms) [18 events] ✗ WebSocket Failed Continuation Evicts Cache (2637ms) [22 events] ✗ Expected previous_response_not_found after failed continuation eviction but got no error code ✓ WebSocket Compact New Chain (3024ms) [10 events] ✓ WebSocket Store False Reconnect Recovery (4157ms) [20 events] ================================================== Results: 15 passed, 2 failed, 0 skipped, 17 total 結果はモデルによって変わり、たとえば Grok 4.7 と Kimi K3 は compact に対応していませんでした。 準拠テストは、使いたいモデルが仕様のどこまでに対応しているかを手元で手軽に確かめる道具として使えます。 まとめ Open Responses は OpenAI の Responses API をもとにした LLM API の共通仕様で、2026年10月22日に AAIF のプロジェクトになりました。 アイテム、状態、イベントの形が決まっているので、接続先とモデル名を変えるだけで、同じクライアントのコードを使い回せます。 Amazon Bedrock では bedrock-runtime と bedrock-mantle の 2 つのエンドポイントで使え、今回は 3 ベンダー・4 モデルで同じエージェントループが動きました。 リポジトリの準拠テストを使えば、モデルごとの対応範囲も手元で確かめられます。 複数のモデルを比べたり切り替えたりする場面で、まず試してみる価値のある仕様だと感じました。 脚注 AWS のブログには Amazon、Anthropic、Meta、Mistral、DeepSeek などのモデルも Responses API で使えると書かれています。ただし Bedrock のドキュメントの対応表では、これらのモデルは Responses API に対応していません。今回の検証でも、Claude Sonnet 5.5、Llama 4 Maverick、Nova Pro、Mistral Large 3、DeepSeek V3.2 への Responses API のリクエストは受け付けられませんでした。Claude Sonnet 5.5 は Messages API で、Mistral Large 3 と DeepSeek V3.2 は Chat Completions で呼び出せます。 ↩︎