داشبورد توسعه‌دهنده
پرسش از هوش مصنوعی
پرسش از هوش مصنوعی

گردش‌کارهای Stateful با Responses API

Responses API زمانی کاربردی است که بخواهید API وضعیت گفتگو، ابزارهای میزبانی‌شده و ورودی‌های چندوجهی را بدون بازسازی کامل تاریخچه پیام‌ها در هر نوبت مدیریت کند. این مثال الگوهای عملی ادامه دادن گفتگو، شاخه‌سازی از پاسخ قبلی و بررسی پاسخ‌ها را از طریق AvalAI نشان می‌دهد.

این راهنما با اقتباس از OpenAI Cookbook رسمی و دفترچه نمونه Responses API، همراه با تغییرات لازم برای endpoint و کلید API در AvalAI تهیه شده است.

چه زمانی از این الگو استفاده کنیم

  • می‌خواهید بدون ارسال دوباره کل تاریخچه، گفتگو را ادامه دهید.
  • لازم است از یک پاسخ قبلی شاخه جدیدی بسازید و مسیر دیگری را امتحان کنید.
  • یک سطح API واحد برای تولید متن و ابزارهایی مانند جستجوی وب می‌خواهید.
  • در حال مهاجرت از Chat Completions هستید و مدل ساده‌تری برای مدیریت state می‌خواهید.

آماده‌سازی

SDK رسمی OpenAI را نصب و کلید AvalAI را تنظیم کنید:

bash
pip install openai
export AVALAI_API_KEY="your-avalai-api-key"

برای Node.js:

bash
npm install openai
export AVALAI_API_KEY="your-avalai-api-key"

گفتگوی Stateful پایه

ابتدا یک response بسازید و سپس با previous_response_id آن را ادامه دهید.

python
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["AVALAI_API_KEY"],
    base_url="https://api.avalai.ir/v1",
)

first = client.responses.create(
    model="gpt-5.5",
    input="Give me a concise deployment checklist for a small API service.",
)

print(first.output_text)

follow_up = client.responses.create(
    model="gpt-5.5",
    input="Now turn that checklist into five acceptance criteria.",
    previous_response_id=first.id,
)

print(follow_up.output_text)
javascript
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.AVALAI_API_KEY,
  baseURL: "https://api.avalai.ir/v1",
});

const first = await client.responses.create({
  model: "gpt-5.5",
  input: "Give me a concise deployment checklist for a small API service.",
});

console.log(first.output_text);

const followUp = await client.responses.create({
  model: "gpt-5.5",
  input: "Now turn that checklist into five acceptance criteria.",
  previous_response_id: first.id,
});

console.log(followUp.output_text);
bash
FIRST_RESPONSE=$(curl https://api.avalai.ir/v1/responses \
  -H "Authorization: Bearer $AVALAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-5.5",
    "input": "Give me a concise deployment checklist for a small API service."
  }')

FIRST_ID=$(printf "%s" "$FIRST_RESPONSE" | jq -r ".id")

curl https://api.avalai.ir/v1/responses \
  -H "Authorization: Bearer $AVALAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{
    \"model\": \"gpt-5.5\",
    \"input\": \"Now turn that checklist into five acceptance criteria.\",
    \"previous_response_id\": \"$FIRST_ID\"
  }"

تصمیم‌های State، نگه‌داری و هزینه

previous_response_id ساده‌ترین راه برای ادامه دادن یک thread است، اما همچنان به state سمت سرویس تکیه دارد. انتخاب state را صریح کنید:

  • وقتی می‌خواهید AvalAI از یک response ذخیره‌شده سمت سرور ادامه دهد، از previous_response_id استفاده کنید.
  • وقتی کنترل دقیق retention، replay قطعی یا fallback برای مسیرهایی لازم است که response قبلی را resolve نمی‌کنند، تاریخچه را دستی نگه دارید.
  • برای CI، eval یا دیباگ حساس، مگر اینکه retrieval بعدی لازم دارید، store=false بگذارید.
  • اگر continuation به دلیل resolve نشدن response قبلی شکست خورد، درخواست را با context کامل و بدون previous_response_id دوباره ارسال کنید.
  • برای کل زنجیره بودجه بگذارید: input قبلی در thread همچنان می‌تواند به‌عنوان input token حساب شود و مدل‌های reasoning نیز reasoning token را داخل context window مصرف می‌کنند.
python
history = [{"role": "user", "content": "Draft a rollback checklist for a payment API."}]

first = client.responses.create(
    model="gpt-5.5",
    input=history,
    store=False,
)

# فقط output_text را نگه ندارید؛ آیتم‌های ساختاریافته خروجی را حفظ کنید.
history.extend(first.output)
history.append(
    {"role": "user", "content": "Now make it safe for a junior on-call engineer."}
)

second = client.responses.create(
    model="gpt-5.5",
    input=history,
    store=False,
)

print(second.output_text)
javascript
const history = [
  { role: "user", content: "Draft a rollback checklist for a payment API." },
];

const first = await client.responses.create({
  model: "gpt-5.5",
  input: history,
  store: false,
});

// فقط output_text را نگه ندارید؛ آیتم‌های ساختاریافته خروجی را حفظ کنید.
history.push(...first.output);
history.push({
  role: "user",
  content: "Now make it safe for a junior on-call engineer.",
});

const second = await client.responses.create({
  model: "gpt-5.5",
  input: history,
  store: false,
});

console.log(second.output_text);

شاخه‌سازی از یک پاسخ قبلی

شاخه‌سازی به شما اجازه می‌دهد از یک پاسخ قبلی مسیر جدیدی بسازید، بدون اینکه مسیر اصلی را تغییر دهید. این کار برای A/B تست پرامپت، تولید لحن‌های متفاوت یا تلاش دوباره با محدودیت جدید مفید است.

python
forked = client.responses.create(
    model="gpt-5.5",
    input=(
        "Use the same original checklist, but rewrite it for a solo developer "
        "who deploys manually once per week."
    ),
    previous_response_id=first.id,
)

print(forked.output_text)
javascript
const forked = await client.responses.create({
  model: "gpt-5.5",
  input:
    "Use the same original checklist, but rewrite it for a solo developer who deploys manually once per week.",
  previous_response_id: first.id,
});

console.log(forked.output_text);
bash
curl https://api.avalai.ir/v1/responses \
  -H "Authorization: Bearer $AVALAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{
    \"model\": \"gpt-5.5\",
    \"input\": \"Use the same original checklist, but rewrite it for a solo developer who deploys manually once per week.\",
    \"previous_response_id\": \"$FIRST_ID\"
  }"

دریافت دوباره یک Response ذخیره‌شده

برای لاگ‌گیری، دیباگ یا پردازش با تاخیر بعد از یک گردش‌کار پس‌زمینه، می‌توانید response را دوباره دریافت کنید. اگر retrieval بعدی لازم دارید، response را با store=true بسازید؛ در غیر این صورت store=false را ترجیح دهید و فقط فیلدهای مورد نیاز برنامه را نگه دارید.

python
stored = client.responses.retrieve(first.id)

print(stored.id)
print(stored.output_text)
javascript
const stored = await client.responses.retrieve(first.id);

console.log(stored.id);
console.log(stored.output_text);
bash
curl "https://api.avalai.ir/v1/responses/$FIRST_ID" \
  -H "Authorization: Bearer $AVALAI_API_KEY"

افزودن جستجوی وب

وقتی پاسخ به اطلاعات تازه نیاز دارد، ابزار web_search را اضافه کنید. اگر رابط کاربری شما به لینک منبع نیاز دارد، در پرامپت صریحا درخواست citation کنید.

python
response = client.responses.create(
    model="gpt-5.5",
    input="Find the latest AvalAI documentation updates and summarize them with sources.",
    tools=[{"type": "web_search"}],
)

print(response.output_text)

for item in response.output:
    print(item.type)
javascript
const response = await client.responses.create({
  model: "gpt-5.5",
  input:
    "Find the latest AvalAI documentation updates and summarize them with sources.",
  tools: [{ type: "web_search" }],
});

console.log(response.output_text);

for (const item of response.output) {
  console.log(item.type);
}
bash
curl https://api.avalai.ir/v1/responses \
  -H "Authorization: Bearer $AVALAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-5.5",
    "input": "Find the latest AvalAI documentation updates and summarize them with sources.",
    "tools": [{"type": "web_search"}]
  }'

نکات Production

  • فقط وقتی response ID را ذخیره کنید که واقعا به ادامه دادن یا audit گفتگو نیاز دارید.
  • اگر کنترل دقیق retention، deletion یا compliance لازم دارید، تاریخچه گفتگو را در سیستم خودتان نگه دارید.
  • هنگام replay دستی state، آیتم‌های ساختاریافته response.output را append کنید تا tool callها و reasoning itemها حفظ شوند.
  • برای گردش‌کارهای قابل پیش‌بینی، instructionهای ثابت را پایدار نگه دارید و جزئیات متغیر کاربر را در آخرین input قرار دهید.
  • هنگام استفاده از ابزارها، response.output را بررسی کنید؛ output_text برای متن نهایی ساده است، اما tool callها و annotationها در آیتم‌های ساختاریافته خروجی قرار دارند.
  • response.id، مدل، latency و usage را لاگ کنید تا بررسی هزینه و پشتیبانی ساده‌تر شود.

لینک‌های مرتبط