OpenAI - Response API
OpenAI - Response API
OpenAI의 Response API를 LiteLLM에서 사용하는 방법을 알아봐요. 스트리밍, 웹 검색, 이미지 생성, 컴퓨터 사용, MCP 도구, 함수 호출까지 지원해요.
출처: 문서
본문
사용법
LiteLLM Python SDK
비스트리밍
import litellm
# Non-streaming response
response = litellm.responses(
model="openai/gpt-5.6-terra",
input="Tell me a three sentence bedtime story about a unicorn.",
max_output_tokens=100
)
print(response)
스트리밍
import litellm
# Streaming response
response = litellm.responses(
model="openai/gpt-5.6-terra",
input="Tell me a three sentence bedtime story about a unicorn.",
stream=True
)
for event in response:
print(event)
웹 검색
import litellm
response = litellm.responses(
model="openai/gpt-5.6-terra",
input="What is the capital of France?",
tools=[{
"type": "web_search_preview",
"search_context_size": "medium" # Options: "low", "medium", "high"
}]
)
print(response)
자세한 내용은 웹 검색 가이드를 참고해요.
스트리밍 이미지 생성
import litellm
import base64
# Streaming image generation with partial images
stream = litellm.responses(
model="gpt-5.6-terra", # Use an actual image generation model
input="Generate a gorgeous image of a river made of white owl feathers",
stream=True,
tools=[{"type": "image_generation", "partial_images": 2}],
)
for event in stream:
if event.type == "response.image_generation_call.partial_image":
idx = event.partial_image_index
image_base64 = event.partial_image_b64
image_bytes = base64.b64decode(image_base64)
with open(f"river{idx}.png", "wb") as f:
f.write(image_bytes)
GET a Response
import litellm
# First, create a response
response = litellm.responses(
model="openai/gpt-5.6-terra",
input="Tell me a three sentence bedtime story about a unicorn.",
max_output_tokens=100
)
# Get the response ID
response_id = response.id
# Retrieve the response by ID
retrieved_response = litellm.get_responses(
response_id=response_id
)
print(retrieved_response)
# For async usage
# retrieved_response = await litellm.aget_responses(response_id=response_id)
DELETE a Response
import litellm
# First, create a response
response = litellm.responses(
model="openai/gpt-5.6-terra",
input="Tell me a three sentence bedtime story about a unicorn.",
max_output_tokens=100
)
# Get the response ID
response_id = response.id
# Delete the response by ID
delete_response = litellm.delete_responses(
response_id=response_id
)
print(delete_response)
# For async usage
# delete_response = await litellm.adelete_responses(response_id=response_id)
OpenAI SDK가 있는 LiteLLM Proxy
config.yaml:
model_list:
- model_name: openai/gpt-5.6-terra
litellm_params:
model: openai/gpt-5.6-terra
api_key: os.environ/OPENAI_API_KEY
Proxy 서버 시작:
litellm --config /path/to/config.yaml
# RUNNING on http://0.0.0.0:4000
비스트리밍
from openai import OpenAI
# Initialize client with your proxy URL
client = OpenAI(
base_url="http://localhost:4000", # Your proxy URL
api_key="your-api-key" # Your proxy API key
)
# Non-streaming response
response = client.responses.create(
model="openai/gpt-5.6-terra",
input="Tell me a three sentence bedtime story about a unicorn."
)
print(response)
스트리밍
from openai import OpenAI
# Initialize client with your proxy URL
client = OpenAI(
base_url="http://localhost:4000", # Your proxy URL
api_key="your-api-key" # Your proxy API key
)
# Streaming response
response = client.responses.create(
model="openai/gpt-5.6-terra",
input="Tell me a three sentence bedtime story about a unicorn.",
stream=True
)
for event in response:
print(event)
스트리밍 이미지 생성
from openai import OpenAI
import base64
# Initialize client with your proxy URL
client = OpenAI(api_key="sk-", base_url="http://localhost:4000")
stream = client.responses.create(
model="gpt-5.6-terra",
input="Draw a gorgeous image of a river made of white owl feathers, snaking its way through a serene winter landscape",
stream=True,
tools=[{"type": "image_generation", "partial_images": 2}],
)
for event in stream:
print(f"event: {event}")
if event.type == "response.image_generation_call.partial_image":
idx = event.partial_image_index
image_base64 = event.partial_image_b64
image_bytes = base64.b64decode(image_base64)
with open(f"river{idx}.png", "wb") as f:
f.write(image_bytes)
GET/DELETE a Response
from openai import OpenAI
# Initialize client with your proxy URL
client = OpenAI(
base_url="http://localhost:4000", # Your proxy URL
api_key="your-api-key" # Your proxy API key
)
# First, create a response
response = client.responses.create(
model="openai/gpt-5.6-terra",
input="Tell me a three sentence bedtime story about a unicorn."
)
# Get the response ID
response_id = response.id
# Retrieve the response by ID
retrieved_response = client.responses.retrieve(response_id)
print(retrieved_response)
# Delete the response by ID
delete_response = client.responses.delete(response_id)
print(delete_response)
지원되는 Responses API 파라미터
| 제공사 | 지원 파라미터 |
|---|---|
openai |
모든 Responses API 파라미터 지원 |
재사용 가능한 프롬프트
prompt 파라미터로 저장된 프롬프트 템플릿을 참조하고 선택적으로 변수를 제공해요.
import litellm
response = litellm.responses(
model="openai/gpt-5.6-terra",
prompt={
"id": "pmpt_abc123",
"version": "2",
"variables": {
"customer_name": "Jane Doe",
"product": "40oz juice box",
},
},
)
print(response)
Proxy에서도 같은 파라미터가 지원돼요:
from openai import OpenAI
client = OpenAI(base_url="http://localhost:4000", api_key="your-api-key")
response = client.responses.create(
model="openai/gpt-5.6-terra",
prompt={
"id": "pmpt_abc123",
"version": "2",
"variables": {
"customer_name": "Jane Doe",
"product": "40oz juice box",
},
},
)
print(response)
Computer Use
import litellm
# Non-streaming response
response = litellm.responses(
model="computer-use-preview",
tools=[{
"type": "computer_use_preview",
"display_width": 1024,
"display_height": 768,
"environment": "browser" # other possible values: "mac", "windows", "ubuntu"
}],
input=[
{
"role": "user",
"content": [
{
"type": "text",
"text": "Check the latest OpenAI news on bing.com."
}
# Optional: include a screenshot of the initial state of the environment
# {
# type: "input_image",
# image_url: f"data:image/png;base64,{screenshot_base64}"
# }
]
}
],
reasoning={
"summary": "concise",
},
truncation="auto"
)
print(response.output)
MCP Tools
import litellm
from typing import Optional
# Configure MCP Tools
MCP_TOOLS = [
{
"type": "mcp",
"server_label": "deepwiki",
"server_url": "https://mcp.deepwiki.com/mcp",
"allowed_tools": ["ask_question"]
}
]
# Step 1: Make initial request - OpenAI will use MCP LIST and return MCP calls for approval
response = litellm.responses(
model="openai/gpt-5.6-terra",
tools=MCP_TOOLS,
input="What transport protocols does the 2025-03-26 version of the MCP spec support?"
)
# Get the MCP approval ID
mcp_approval_id = None
for output in response.output:
if output.type == "mcp_approval_request":
mcp_approval_id = output.id
break
# Step 2: Send followup with approval for the MCP call
response_with_mcp_call = litellm.responses(
model="openai/gpt-5.6-terra",
tools=MCP_TOOLS,
input=[
{
"type": "mcp_approval_response",
"approve": True,
"approval_request_id": mcp_approval_id
}
],
previous_response_id=response.id,
)
print(response_with_mcp_call)
Proxy에서도 동일하게 동작해요. config.yaml을 설정하고 OpenAI SDK로 client.responses.create(...)를 호출하면 됩니다.
Verbosity 파라미터
respones API에 verbosity 파라미터가 지원돼요.
from litellm import responses
question = "Write a poem about a boy and his first pet dog."
for verbosity in ["low", "medium", "high"]:
response = responses(
model="gpt-5.6-luna",
input=question,
text={"verbosity": verbosity}
)
print(response)
Proxy:
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:4000", # Your proxy URL
api_key="your-api-key" # Your proxy API key
)
question = "Write a poem about a boy and his first pet dog."
for verbosity in ["low", "medium", "high"]:
response = client.responses.create(
model="gpt-5.6-luna",
input=question,
text={"verbosity": verbosity}
)
# Extract text
output_text = ""
for item in response.output:
if hasattr(item, "content"):
for content in item.content:
if hasattr(content, "text"):
output_text += content.text
usage = response.usage
print(verbosity, output_text, usage.output_tokens)
함수 호출
import litellm
import json
tools = [
{
"type": "function",
"name": "get_weather",
"description": "Get current weather for a location",
"parameters": {
"type": "object",
"properties": {
"location": {"type": "string"}
},
"required": ["location"]
}
}
]
# Step 1: Request with tools (parallel_tool_calls=True allows multiple calls)
response = litellm.responses(
model="openai/gpt-5.6-terra",
input=[{"role": "user", "content": "What's the weather in Paris and Tokyo?"}],
tools=tools,
parallel_tool_calls=True, # Defaults = True
)
# Step 2: Execute tool calls and collect results
tool_results = []
for output in response.output:
if output.type == "function_call":
result = {"temperature": 15, "condition": "sunny"} # Your function logic here
tool_results.append({
"type": "function_call_output",
"call_id": output.call_id,
"output": json.dumps(result)
})
# Step 3: Send results back
final_response = litellm.responses(
model="openai/gpt-5.6-terra",
input=tool_results,
tools=tools,
)
print(final_response.output)
parallel_tool_calls=False로 설정하면 턴당 0개 또는 1개 도구만 호출되도록 보장할 수 있어요.
도구 검색 및 네임스페이스
도구 검색은 모델이 프롬프트에 모든 도구 정의를 보내는 대신 런타임에 도구를 동적으로 로드하게 해줘요. 함수를 네임스페이스로 그룹화하고 defer_loading: true로 표시하면 모델이 실제로 필요한 스키마만 로드해서 토큰을 절약할 수 있어요.
gpt-5.4 이상이 필요해요. 자세한 내용은 OpenAI Tool Search 문서를 참고해요.
import litellm
# Define namespaces with deferred tools
tools = [
{"type": "tool_search"}, # Enable tool search
{
"type": "namespace",
"name": "crm",
"description": "CRM tools for customer management",
"tools": [
{
"type": "function",
"name": "get_customer",
"description": "Get customer details by ID",
"parameters": {
"type": "object",
"properties": {
"customer_id": {"type": "string"}
},
"required": ["customer_id"],
},
"defer_loading": True,
},
{
"type": "function",
"name": "list_customers",
"description": "List customers with optional filters",
"parameters": {
"type": "object",
"properties": {
"status": {"type": "string", "enum": ["active", "inactive"]},
},
},
"defer_loading": True,
},
],
},
{
"type": "namespace",
"name": "billing",
"description": "Billing and invoicing tools",
"tools": [
{
"type": "function",
"name": "get_invoice",
"description": "Get an invoice by ID",
"parameters": {
"type": "object",
"properties": {
"invoice_id": {"type": "string"}
},
"required": ["invoice_id"],
},
"defer_loading": True,
},
],
},
]
response = litellm.responses(
model="openai/gpt-5.6-terra",
input="Look up invoice INV-2024-001 from the billing system",
tools=tools,
)
# The response contains tool_search_call, tool_search_output, and function_call items
for item in response.output:
if isinstance(item, dict):
if item["type"] == "tool_search_call":
print(f"Searched namespaces: {item['arguments']['paths']}")
elif item["type"] == "tool_search_output":
print(f"Loaded {len(item['tools'])} tool(s)")
elif item["type"] == "function_call":
print(f"Called: {item.get('namespace', '')}.{item['name']}({item['arguments']})")
else:
if item.type == "function_call":
print(f"Called: {item.namespace}.{item.name}({item.arguments})")
채팅 완성 브리지를 통한 도구 검색
모델에 openai/responses/를 접두사로 붙여 /v1/chat/completions 엔드포인트를 통해서도 도구 검색을 사용할 수 있어요. 요청은 Responses API로 라우팅되지만 표준 채팅 완성 응답을 반환해요.
import litellm
response = litellm.completion(
model="openai/responses/gpt-5.6-terra",
messages=[{"role": "user", "content": "Look up invoice INV-2024-001"}],
tools=[
{"type": "tool_search"},
{
"type": "namespace",
"name": "billing",
"description": "Billing and invoicing tools",
"tools": [
{
"type": "function",
"name": "get_invoice",
"description": "Get an invoice by ID",
"parameters": {
"type": "object",
"properties": {"invoice_id": {"type": "string"}},
"required": ["invoice_id"],
},
"defer_loading": True,
},
],
},
],
)
# Standard chat completions response
for tool_call in response.choices[0].message.tool_calls:
print(f"Called: {tool_call.function.name}({tool_call.function.arguments})")
curl http://localhost:4000/v1/chat/completions \
-H "Authorization: Bearer ***" \
-H "Content-Type: application/json" \
-d '{
"model": "openai/responses/gpt-5.6-terra",
"messages": [{"role": "user", "content": "Look up invoice INV-2024-001"}],
"tools": [
{"type": "tool_search"},
{
"type": "namespace",
"name": "billing",
"description": "Billing and invoicing tools",
"tools": [
{
"type": "function",
"name": "get_invoice",
"description": "Get an invoice by ID",
"parameters": {
"type": "object",
"properties": {"invoice_id": {"type": "string"}},
"required": ["invoice_id"]
},
"defer_loading": true
}
]
}
]
}'
자유 형식 함수 호출
import litellm
response = litellm.responses(
model="gpt-5.6-luna",
input="Please use the code_exec tool to calculate the area of a circle with radius equal to the number of 'r's in strawberry",
text={"format": {"type": "text"}},
tools=[
{
"type": "custom",
"name": "code_exec",
"description": "Executes arbitrary python code",
}
]
)
print(response.output)
Context-Free 문법
import litellm
import textwrap
# ----------------- grammars for MS SQL dialect -----------------
mssql_grammar = textwrap.dedent(r"""
// ---------- Punctuation & operators ----------
SP: " "
COMMA: ","
GT: ">"
EQ: "="
SEMI: ";"
// ---------- Start ----------
start: "SELECT" SP "TOP" SP NUMBER SP select_list SP "FROM" SP table SP "WHERE" SP amount_filter SP "AND" SP date_filter SP "ORDER" SP "BY" SP sort_cols SEMI
// ---------- Projections ----------
select_list: column (COMMA SP column)*
column: IDENTIFIER
// ---------- Tables ----------
table: IDENTIFIER
// ---------- Filters ----------
amount_filter: "total_amount" SP GT SP NUMBER
date_filter: "order_date" SP GT SP DATE
// ---------- Sorting ----------
sort_cols: "order_date" SP "DESC"
// ---------- Terminals ----------
IDENTIFIER: /[A-Za-z_][A-Za-z0-9_]*/
NUMBER: /[0-9]+/
DATE: /'[0-9]{4}-[0-9]{2}-[0-9]{2}'/
""")
sql_prompt_mssql = (
"Call the mssql_grammar to generate a query for Microsoft SQL Server that retrieve the "
"five most recent orders per customer, showing customer_id, order_id, order_date, and total_amount, "
"where total_amount > 500 and order_date is after '2025-01-01'. "
)
response = litellm.responses(
model="gpt-5.6-terra",
input=sql_prompt_mssql,
text={"format": {"type": "text"}},
tools=[
{
"type": "custom",
"name": "mssql_grammar",
"description": "Executes read-only Microsoft SQL Server queries limited to SELECT statements with TOP and basic WHERE/ORDER BY. YOU MUST REASON HEAVILY ABOUT THE QUERY AND MAKE SURE IT OBEYS THE GRAMMAR.",
"format": {
"type": "grammar",
"syntax": "lark",
"definition": mssql_grammar
}
},
],
parallel_tool_calls=False
)
print("--- MS SQL Query ---")
print(response_mssql.output[1].input)
최소 추론 (Minimal Reasoning)
import litellm
response = litellm.responses(
model="gpt-5.6-terra",
input= [{ 'role': 'developer', 'content': prompt },
{ 'role': 'user', 'content': 'The food that the restaurant was great! I recommend it to everyone.' }],
reasoning = {
"effort": "minimal"
},
)
print(response)
Proxy에서도 동일:
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:4000", # Your proxy URL
api_key="your-api-key" # Your proxy API key
)
prompt = "Classify sentiment of the review as positive|neutral|negative. Return one word only."
response = client.responses.create(
model="gpt-5.6-terra",
input= [{ 'role': 'developer', 'content': prompt },
{ 'role': 'user', 'content': 'The food that the restaurant was great! I recommend it to everyone.' }],
reasoning = {
"effort": "minimal"
},
)
# Extract model's text output
output_text = ""
for item in response.output:
if hasattr(item, "content"):
for content in item.content:
if hasattr(content, "text"):
output_text += content.text
# Token usage details
usage = response.usage
print("--------------------------------")
print("Output:")
print(output_text)
더 알아보기 (Learn more)
- OpenAI Responses API 문서
- 웹 검색 가이드