Skip to main content

بناء وكلاء ذكاء اصطناعي باستخدام OpenAI Agents SDK: دورة مكثفة في 90 دقيقة

16 مفهوماً، 80% من الاستخدام الحقيقي · قراءة مفاهيمية في 90 دقيقة · بناء كامل خلال 4 إلى 6 ساعات

هذه دورة عملية. ستبني ثلاثة أشياء:

  • وكيل محادثة محلي يشغّل أدوات فعلية.
  • طبقة أمان وملاحظة: guardrails، tracing، وموافقة بشرية.
  • نشر sandbox يستطيع تشغيل عمل حقيقي مع حفظ الملفات عبر R2.

الفكرة الأساسية: الوكيل ليس نموذجاً فقط. الوكيل حلقة تشغيل: نموذج + أدوات + حالة + سياسة + ملاحظة. إذا فهمت هذه الحلقة، تستطيع استبدال النموذج أو compute أو الواجهة من دون أن تضيع.

تريد عمقاً في الحالة والثقة قبل المفهوم الأول؟

تذكر مثلث الثقة: النموذج يقرر، الأدوات تفعل، والسجل يثبت ما حدث. لا تشحن وكيلاً إنتاجياً بلا طريقة لمعرفة ماذا قرر، أي أداة استدعى، وماذا أعادت الأداة.

مسارات القراءة
  • القارئ: اقرأ المفاهيم والقرارات فقط.
  • الباني المحلي: نفذ الجزءين 1 و2.
  • باني الإنتاج: أكمل sandbox وR2 والموافقة البشرية.

Setup (دقيقة واحدة)

افتح مجلد مشروع جديد، وأنشئ بيئة Python مع uv، ثم ضع مفاتيحك في .env. لا تحفظ أسراراً في الكود ولا في git.

uv init chat-agent
cd chat-agent
uv add openai-agents python-dotenv
لديك مفتاح DeepSeek فقط؟

يمكنك استخدام موفر متوافق مع OpenAI API، لكن اضبط OPENAI_BASE_URL والنموذج بوضوح. لا تجعل SDK يرسل مفتاحاً غير OpenAI إلى api.openai.com بالخطأ.

الجزء 1: الأساسيات

Concept 1: ما الوكيل فعلاً

الوكيل برنامج يستطيع، عند إعطائه مهمة بلغة طبيعية، أن يقرر الخطوة التالية: يرد، يستدعي أداة، يسأل أداة أخرى، يسلّم إلى وكيل متخصص، أو يطلب موافقة. الفرق بينه وبين chatbot أن الوكيل يفعل، لا يتكلم فقط.

Concept 2: SDK في ثلاث بدائيات

  1. Agent: التعليمات والنموذج والأدوات.
  2. Tool: دالة يستطيع النموذج استدعاءها.
  3. Runner: الحلقة التي تشغل الوكيل وتحفظ المسار.
# hello_agent.py
from agents import Agent, Runner

agent = Agent(
name="hello",
instructions="You are a concise assistant.",
)

result = Runner.run_sync(agent, "Say hello in one sentence.")
print(result.final_output)

الأدوات تجعل الوكيل مفيداً:

# src/chat_agent/hello_currency.py
from agents import Agent, Runner, function_tool

@function_tool
def convert_usd_to_eur(amount: float) -> float:
return round(amount * 0.92, 2)

agent = Agent(
name="currency",
instructions="Use tools when calculation is needed.",
tools=[convert_usd_to_eur],
)

Concept 3: حلقة الوكيل بصورة ملموسة

الحلقة: prompt -> model -> tool call -> tool result -> model -> final answer. عندما تفشل الوكلاء، فغالباً لأن إحدى هذه الحدود غير واضحة: أداة غامضة، نتيجة غير منظمة، أو سياسة لا تقول متى يتوقف.

الجزء 2: بناء تطبيق محادثة محلي

Concept 4: إعداد المشروع بـ uv

استخدم uv لأن بيئات Python المكسورة تستهلك وقت المبتدئ. احفظ الاعتماديات في pyproject.toml، والأسرار في .env، وأوامر التشغيل في README أو AGENTS.md.

# tools/verify_install.py
import os

print("OPENAI_API_KEY present:", bool(os.getenv("OPENAI_API_KEY")))

Concept 5: حلقة المحادثة وخطؤها

الإصدار الأول يقرأ رسالة، يشغل الوكيل، ويطبع الرد. خطؤه أنه لا يتذكر المحادثة السابقة.

# src/chat_agent/cli_v1.py
while True:
user = input("> ")
result = Runner.run_sync(agent, user)
print(result.final_output)

هذا جيد للتجربة، سيئ للمحادثة. كل turn جديد يبدأ بلا تاريخ.

Concept 6: الجلسات، إصلاح الخطأ

أضف session حتى يعرف الوكيل ما قيل سابقاً. SQLiteSession خيار محلي بسيط.

# src/chat_agent/cli_v2.py
from agents.memory import SQLiteSession

session = SQLiteSession("chat.db")
result = Runner.run_sync(agent, user, session=session)

Concept 7: Streaming responses

التدفق ليس جمالياً فقط. في التطبيقات الحقيقية يعطي المستخدم علامة حياة ويكشف التأخير. استخدم streaming عندما يكون الرد طويلاً أو عندما تعمل الأدوات ببطء.

Concept 8: Function tools بعد المثال الوهمي

الأداة الجيدة صغيرة، typed، واسمها واضح. لا تجعل الأداة "do_everything". أعط النموذج دوالاً تمثل أفعال العمل: lookup، create، refund، summarize، search.

# src/chat_agent/tools.py
@function_tool
def lookup_invoice(invoice_id: str) -> dict:
return {"invoice_id": invoice_id, "amount": 29, "status": "paid"}

Concept 9: Handoffs إلى وكلاء متخصصين

handoff جيد عندما تختلف السياسة أو الخبرة، لا عندما تريد تنظيم الكود فقط. وكيل الفواتير، وكيل الدعم، ووكيل التصعيد قد يملكون تعليمات وأدوات مختلفة.

# src/chat_agent/agents.py
billing_agent = Agent(name="billing", instructions="Handle invoice questions.")
triage_agent = Agent(
name="triage",
instructions="Route requests to the right specialist.",
handoffs=[billing_agent],
)

مثال عكسي: عندما يكون handoff شكلاً خاطئاً

إذا كانت المهمة مجرد خطوة داخل workflow واحد، فاستخدم أداة أو دالة. لا تصنع وكيلين لأنك تستطيع. كل handoff يزيد سطح التتبع والتقييم.

الجزء 3: السلامة والملاحظة وتوجيه النماذج

Concept 10: Guardrails

guardrail يفحص المدخل أو المخرج أو مسار الأداة. استخدمه للسياسات الواضحة: منع طلبات خارج النطاق، حظر بيانات حساسة، أو طلب موافقة قبل refund.

Guardrails متوازية مقابل حاجزة

التوازي أرخص زمنياً عندما يكون الفحص مستقلاً. الفحص الحاجز مطلوب عندما لا يجوز أن يرى الوكيل الأساسي المدخل قبل التصنيف.

# src/chat_agent/guardrails.py
def is_refund_request(text: str) -> bool:
return "refund" in text.lower()

Concept 11: Tracing

التتبع هو سجل تشغيل الوكيل: model calls، tool calls، handoffs، guardrails. من دونه لا تعرف لماذا اتخذ الوكيل القرار.

# src/chat_agent/run.py
result = Runner.run_sync(agent, user, run_config=run_config)
تتبعات الخطوات وبيانات العملاء

لا تسجل بيانات حساسة بلا سياسة. trace مفيد للملاحظة، لكنه قد يصبح مخزناً لبيانات يجب حمايتها.

Concept 12: تبديل النماذج مع DeepSeek V4 Flash

النموذج القوي ليس مطلوباً لكل خطوة. استخدم نموذجاً أرخص للتصنيف أو التلخيص البسيط، ونموذجاً أقوى للقرارات التي تحتاج استدلالاً عالياً.

# src/chat_agent/models.py
flash_model = "deepseek-chat"
strong_model = "gpt-5.5"

المهم أن يكون توجيه النماذج قراراً واعياً، لا أثراً جانبياً للإعداد.

Concept 13: موافقة الإنسان للأدوات الخطرة

الأدوات التي تغيّر مالاً، حساباً، أو بيانات عميل تحتاج موافقة. اجعل الأداة نفسها تعلن حاجتها للموافقة، ولا تعتمد على أن النموذج "سيتذكر".

# src/chat_agent/risky_tools.py
@function_tool
def refund_invoice(invoice_id: str, amount: float) -> str:
return f"refund queued: {invoice_id} {amount}"

حلقة الثقة

كل موافقة يجب أن تظهر في trace: ماذا طلب الوكيل، ماذا وافق الإنسان، وماذا حدث بعد ذلك. الثقة ليست شعوراً؛ هي سجل.

الجزء 4: نشر sandbox للوكيل

Concept 14: لماذا sandbox، وما SandboxAgent

sandbox يفصل العمل غير الموثوق عن جهازك أو إنتاجك. الوكيل يستطيع إنشاء ملفات وتشغيل أوامر داخل مساحة محدودة. SandboxAgent هو نمط: وكيل + harness + compute + ملف manifest.

# src/chat_agent/sandbox_agent.py
class SandboxAgent:
def __init__(self, client, manifest):
self.client = client
self.manifest = manifest

Harness مقابل compute

harness يقرر كيف يتكلم الوكيل مع الأدوات. compute يقرر أين تعمل الملفات والأوامر. لا تخلطهما: يمكنك تبديل Cloudflare بـ Docker أو E2B مع بقاء منطق الوكيل.

Manifest: شكل الجلسة الجديدة

manifest يحدد الملفات الأولية، الأسرار المسموحة، mounts، وحدود العمل. كل جلسة يجب أن تبدأ من حالة قابلة للتفسير.

Concept 15: Cloudflare Sandbox bridge وR2 mounts

Cloudflare يعطي مساراً عملياً لتشغيل sandbox. R2 يجعل الملفات تعيش بعد انتهاء الجلسة. الدرس ليس Cloudflare وحده؛ الدرس أن agent runtime يحتاج تخزيناً وسياسة وحدوداً.

import { bridge } from "@cloudflare/sandbox/bridge";

export default bridge({
// shape only
});

Concept 16: اجعل العمل ينجو عبر R2

  1. أنشئ R2 bucket.
  2. أنشئ API token.
  3. ضع القيم في .env.
  4. ابن Manifest ومرره إلى client.create(...).

Compaction: إبقاء تشغيل sandbox الطويل محدوداً

الجلسات الطويلة تحتاج تلخيصاً دورياً للحالة: ما تم، ما بقي، أين الملفات، وما المخاطر. لا تجعل المحادثة هي المصدر الوحيد للحقيقة.

Memory() في sandbox ليست Session في SDK

ذاكرة sandbox للملفات والحالة التشغيلية. Session في SDK لسياق المحادثة. كلاهما مهم، ولا يغني أحدهما عن الآخر.

الجزء 5: المثال العملي

ابدأ نظيفاً

افتح مشروعاً جديداً، واطلب من وكيل البرمجة قراءة القواعد قبل التنفيذ. لا تبدأ بإصلاحات عشوائية.

Stage A: ابنِه محلياً

Decision 1: أضف قواعد المشروع إلى AGENTS.md

## Project rules

### Stack
- Python
- OpenAI Agents SDK
- uv

### Critical rules
- Keep secrets in `.env`.
- Run the CLI after each meaningful change.

Decision 2: أضف قسم البنية

اكتب أين تعيش agents، tools، guardrails، sessions، وtracing. البنية المكتوبة تمنع الوكيل من توزيع الملفات عشوائياً.

Decision 2.5: افحص SDK

# tools/verify_sdk.py
import agents
print("agents sdk import ok")

Decision 3: Scaffold الكود

أنشئ src/chat_agent/، ثم ملفات agents/tools/cli. لا تكتب كل شيء في ملف واحد.

Decision 4: اربط streaming والجلسات والCLI

هذا هو الحد الأدنى لتجربة حقيقية: محادثة تستمر، ورد يتدفق، وأمر تشغيل واحد.

Decision 5: أضف guardrail

ابدأ بتصنيف بسيط لطلبات refund أو بيانات حساسة. لا تعقد guardrails قبل أن ترى السلوك.

Decision 6: اربط tracing

اجعل كل تشغيل يترك أثراً. trace هو ما ستستخدمه لاحقاً في evals.

Stage B: تحدي SandboxAgent

المتطلبات

مفتاح API، حساب Cloudflare/R2 عند التنفيذ الكامل، وفهم واضح لما يستطيع sandbox قراءته وكتابته.

الموجز الذي تلصقه لوكيل البرمجة

Build the SandboxAgent layer as a small vertical slice.
Keep local CLI behavior unchanged.
Add one sandbox run path, one persistence check, and one verification command.
Stop before any destructive cloud action.

ما الذي تغيّر بين الأداتين

Claude Code وOpenCode يختلفان في keybindings والإعدادات. القرارات لم تتغير: rules file، plan، verification، small slice، approval.

الجزء 6: انضباط الكلفة

لماذا يهم هذا

كل turn يعيد فوترة العالم: prompt، history، tools، traces، وربما storage. الوكلاء الذين يعملون بلا حدود يصنعون فواتير غير مرئية.

# src/chat_agent/usage_log.py
def record_usage(run_id: str, model: str, tokens: int) -> None:
pass

قرار النموذج ذي الطبقتين

استخدم طبقة رخيصة للفرز والتصنيف، وطبقة قوية للحكم النهائي أو التخطيط العميق. لا تضع أقوى نموذج في كل guardrail.

أنماط فشل الكلفة الخمسة

  1. سياق طويل بلا /clear.
  2. نموذج قوي لكل خطوة.
  3. أدوات تعيد payload ضخماً.
  4. retries بلا حدود.
  5. tracing يحفظ بيانات أكثر من اللازم.

توقع كلفة واقعي

المختبر المحلي رخيص. الإنتاج يتبع عدد الأحداث، وطول السياق، وعدد استدعاءات الأدوات، ونموذج التوجيه. قِس مبكراً.

كيف تتحسن فعلاً

ابنِ وكيلاً صغيراً، ثم اسأل بعد كل تشغيل: هل كان القرار مرئياً؟ هل الأداة صغيرة؟ هل الحالة محفوظة؟ هل يمكن تقييم السلوك؟ التحسن يأتي من تضييق الحلقة، لا من إضافة أدوات أكثر.

ملحق: تذكير بالمتطلبات

A.1 أجزاء Python typed المستخدمة هنا

ستحتاج types للدوال والأدوات، dataclasses أو Pydantic عند الحاجة، وasync عند streaming أو أدوات I/O.

A.2 Plan mode وملفات القواعد

اكتب قواعد قصيرة:

## Stack
- Python 3.12
- uv

## Conventions
- One agent per file when behavior differs.
- Tools must be typed.

## Hard rules
- Never commit `.env`.
- Verify with the CLI before claiming done.

في Claude Code يمكن حفظ workflow في .claude/commands/plan-feature.md. في OpenCode استخدم الآلية المكافئة. المهم أن تصبح الخطة عادة لا رجاءً.