0Pricing
AI Agents · درس

تدفق المخرجات في وكلاء CLI

طباعة الرموز المتدفقة حرفًا حرفًا في واجهات الطرفية

تدفق المخرجات في وكلاء CLI درس مجاني في AI Agents على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في AI Agents، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة AI Agents 4 دروس في المجموع.

أهمية البث لوكلاء CLI

من دون البث، لا يطبع وكيل CLI شيئًا حتى تصبح استجابة LLM الكاملة جاهزة، وقد يستغرق ذلك من 5 إلى 30 ثانية. ويحدّق المستخدمون في طرفية فارغة متسائلين عما إذا كان البرنامج قد تعطل.

أما مع البث، فتظهر الرموز أثناء توليدها، ما يوفر استجابة فورية وتجربة أفضل بكثير.

تفعيل البث في OpenAI SDK

مرّروا stream=True إلى chat.completions.create(). يعيد الاستدعاء مولّدًا بدلًا من كائن استجابة كامل. تكرّروا عليه لمعالجة الأجزاء عند وصولها.

import openai

client = openai.OpenAI(api_key='YOUR_API_KEY')

stream = client.chat.completions.create(
    model='gpt-4o-mini',
    messages=[{'role': 'user', 'content': 'Explain Python generators in 3 sentences.'}],
    stream=True  # <-- enable streaming
)

# Each chunk arrives as it is generated
for chunk in stream:
    delta = chunk.choices[0].delta
    if delta.content:
        print(delta.content, end='', flush=True)

print()  # newline after the response is complete

print() مقابل sys.stdout.write()

عند استخدام البث، استخدموا print(text, end='', flush=True) أو sys.stdout.write(text) متبوعًا بـ sys.stdout.flush(). من دون flush=True، قد تخزّن Python المخرجات مؤقتًا وتطبعها دفعة واحدة، ما يلغي الغرض من البث.

import sys
import openai

client = openai.OpenAI(api_key='YOUR_API_KEY')

def stream_to_terminal(messages: list):
    stream = client.chat.completions.create(
        model='gpt-4o-mini',
        messages=messages,
        stream=True
    )

    full_response = ''
    for chunk in stream:
        token = chunk.choices[0].delta.content or ''
        full_response += token

        # Option 1: print with flush
        print(token, end='', flush=True)

        # Option 2: sys.stdout.write + flush
        # sys.stdout.write(token)
        # sys.stdout.flush()

    print()  # final newline
    return full_response

جمع الاستجابة الكاملة أثناء البث

غالبًا ما تحتاجون إلى نص الاستجابة الكامل بعد اكتمال البث، سواء لتخزينه أو لمعالجته لاحقًا أو لعرضه. اجمعوا الرموز في سلسلة نصية أثناء طباعتها.

import openai

client = openai.OpenAI(api_key='YOUR_API_KEY')

def stream_and_collect(messages: list) -> str:
    full_text = ''

    print('Agent: ', end='', flush=True)

    stream = client.chat.completions.create(
        model='gpt-4o-mini',
        messages=messages,
        stream=True
    )

    for chunk in stream:
        token = chunk.choices[0].delta.content or ''
        full_text += token
        print(token, end='', flush=True)

    print()  # newline
    return full_text

# The return value contains the complete response for storage
# response_text = stream_and_collect(history)
# history.append({'role': 'assistant', 'content': response_text})

البث غير المتزامن باستخدام AsyncOpenAI

في بنى الوكلاء غير المتزامنة، استخدموا AsyncOpenAI وasync for للتكرار على أجزاء البث دون حظر حلقة الأحداث.

import asyncio
import openai

async def async_stream_agent(query: str) -> str:
    client = openai.AsyncOpenAI(api_key='YOUR_API_KEY')

    stream = await client.chat.completions.create(
        model='gpt-4o-mini',
        messages=[{'role': 'user', 'content': query}],
        stream=True
    )

    full_text = ''
    print('Agent: ', end='', flush=True)

    async for chunk in stream:
        token = chunk.choices[0].delta.content or ''
        full_text += token
        print(token, end='', flush=True)

    print()
    return full_text

# asyncio.run(async_stream_agent('What is asyncio?'))

اكتشاف نهاية البث باستخدام finish_reason

يحتوي الجزء الأخير من البث على قيمة غير فارغة في finish_reason. تحقّقوا منها لمعرفة سبب انتهاء البث: 'stop' = اكتمال عادي، 'length' = اقتطاع، 'tool_calls' = الحاجة إلى استدعاء دالة.

import openai

client = openai.OpenAI(api_key='YOUR_API_KEY')

def stream_with_finish_detection(messages: list):
    stream = client.chat.completions.create(
        model='gpt-4o-mini',
        messages=messages,
        stream=True
    )

    finish_reason = None
    for chunk in stream:
        delta = chunk.choices[0].delta
        if delta.content:
            print(delta.content, end='', flush=True)
        if chunk.choices[0].finish_reason:
            finish_reason = chunk.choices[0].finish_reason

    print()

    if finish_reason == 'length':
        print('[WARNING: Response was truncated. Try increasing max_tokens.]')
    elif finish_reason == 'stop':
        pass  # normal completion

    return finish_reason

ألوان ANSI في مخرجات الطرفية

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

# pip install colorama
from colorama import Fore, Style, init
init(autoreset=True)  # reset color after each print

def print_colored_stream(messages: list, client):
    # Print agent prefix in cyan
    print(Fore.CYAN + 'Agent: ' + Style.RESET_ALL, end='', flush=True)

    stream = client.chat.completions.create(
        model='gpt-4o-mini',
        messages=messages,
        stream=True
    )

    for chunk in stream:
        token = chunk.choices[0].delta.content or ''
        print(token, end='', flush=True)

    print()

# Also useful:
# print(Fore.GREEN + 'Success!') — green
# print(Fore.RED + 'Error!') — red
# print(Fore.YELLOW + 'Warning') — yellow

مكتبة Rich لمخرجات طرفية أكثر ثراءً

توفر مكتبة rich عرض Markdown وكتل التعليمات البرمجية المميّزة بناءً على الصياغة والجداول ومؤشرات الانتظار في الطرفية. وهي تتكامل جيدًا مع مخرجات الوكيل المتدفقة.

# pip install rich
from rich.console import Console
from rich.live import Live
from rich.markdown import Markdown

console = Console()

def stream_with_rich(messages: list, client):
    full_text = ''

    with Live(console=console, refresh_per_second=10) as live:
        stream = client.chat.completions.create(
            model='gpt-4o-mini',
            messages=messages,
            stream=True
        )

        for chunk in stream:
            token = chunk.choices[0].delta.content or ''
            full_text += token
            # Render accumulated text as Markdown in real time
            live.update(Markdown(full_text))

    return full_text

البث مع استدعاءات الأدوات

عند الجمع بين البث واستدعاء الدوال، يتم أيضًا بث الحقل tool_calls على أجزاء. اجمعوا سلسلة JSON عبر الأجزاء قبل تحليلها.

import json
import openai

client = openai.OpenAI(api_key='YOUR_API_KEY')

def stream_with_tools(messages: list, tools: list) -> dict:
    stream = client.chat.completions.create(
        model='gpt-4o-mini',
        messages=messages,
        tools=tools,
        stream=True
    )

    tool_call_chunks = {}
    for chunk in stream:
        delta = chunk.choices[0].delta
        if delta.tool_calls:
            for tc in delta.tool_calls:
                idx = tc.index
                if idx not in tool_call_chunks:
                    tool_call_chunks[idx] = {'name': '', 'args': ''}
                if tc.function.name:
                    tool_call_chunks[idx]['name'] += tc.function.name
                if tc.function.arguments:
                    tool_call_chunks[idx]['args'] += tc.function.arguments

    # Parse accumulated tool calls
    return {v['name']: json.loads(v['args']) for v in tool_call_chunks.values()}

عرض عدّاد الرموز

اعرضوا عدّادًا مباشرًا للرموز أثناء البث لمساعدة المستخدمين على مراقبة الاستخدام وفهم التكاليف. يتضمن بث OpenAI بيانات الاستخدام في الجزء الأخير عند تعيين stream_options={'include_usage': True}.

import openai

client = openai.OpenAI(api_key='YOUR_API_KEY')

def stream_with_token_count(messages: list):
    stream = client.chat.completions.create(
        model='gpt-4o-mini',
        messages=messages,
        stream=True,
        stream_options={'include_usage': True}
    )

    for chunk in stream:
        delta = chunk.choices[0].delta
        if delta.content:
            print(delta.content, end='', flush=True)

        # Last chunk includes usage
        if chunk.usage:
            print(f'\n[Tokens: prompt={chunk.usage.prompt_tokens}, '
                  f'completion={chunk.usage.completion_tokens}, '
                  f'total={chunk.usage.total_tokens}]')

أفضل ممارسات البث

ملخص لأفضل ممارسات بث المخرجات لوكلاء CLI:

  • استخدموا دائمًا flush=True أو sys.stdout.flush() لمنع التخزين المؤقت
  • اجمعوا الرموز في سلسلة نصية لتخزينها بعد البث
  • تحقّقوا من finish_reason لاكتشاف الاقتطاع
  • استخدموا ألوان ANSI أو rich لتحسين الوضوح البصري
  • عالجوا بث استدعاءات الأدوات بجمع أجزاء وسائط JSON

اختبار المعرفة: بث المخرجات

اختبروا مدى فهمكم لبث المخرجات في وكلاء CLI.

مراجعة: بث المخرجات في وكلاء CLI

يمكنكم الآن إنشاء وكلاء CLI للبث يتسمون بالاستجابة وسهولة الاستخدام:

  • مرروا stream=True لتمكين البث من OpenAI SDK
  • استخدموا print(token, end='', flush=True) لعرض الرموز المميزة فورًا
  • اجمعوا الرموز المميزة في سلسلة نصية لمعالجتها بعد انتهاء البث
  • تحققوا من finish_reason في الجزء الأخير لاكتشاف الاقتطاع
  • استخدموا async for مع AsyncOpenAI للوكلاء غير المتزامنين
  • أضيفوا ألوان ANSI أو rich للحصول على تجربة طرفية متقنة

الأسئلة الشائعة

هل درس «تدفق المخرجات في وكلاء CLI» مجاني؟

نعم — نص درس «تدفق المخرجات في وكلاء CLI» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة AI Agents، انتقل إلى CoddyKit PRO. تتضمن دورة AI Agents 4 دروس في المجموع.

ماذا ستتعلم في «تدفق المخرجات في وكلاء CLI»؟

طباعة الرموز المتدفقة حرفًا حرفًا في واجهات الطرفية تتمرن على AI Agents مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ AI Agents؟

لا تُشترط خبرة سابقة. AI Agents على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 4 من أصل 4.

كم من الوقت يستغرق درس «تدفق المخرجات في وكلاء CLI»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس AI Agents هذا؟

نعم. كل درس في AI Agents يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. بناء واجهات وكلاء لسطر الأوامر
  2. وكلاء تفاعليون بنمط REPL
  3. تحليل الوسائط ونص التعليمات
  4. تدفق المخرجات في وكلاء CLI
← العودة إلى AI Agents