0Pricing
AI Agents · บทเรียน

การส่งข้อมูลออกแบบสตรีมในตัวแทน CLI

พิมพ์โทเค็นที่ส่งมาแบบสตรีมทีละอักขระในส่วนติดต่อเทอร์มินัล

การส่งข้อมูลออกแบบสตรีมในตัวแทน CLI เป็นบทเรียน AI Agents ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 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 มีความสามารถในการแสดงผลมาร์กดาวน์ บล็อกโค้ดที่เน้นไวยากรณ์ ตาราง และวงล้อหมุนในเทอร์มินัล ไลบรารีนี้ทำงานร่วมกับเอาต์พุตของเอเจนต์ที่ส่งข้อมูลแบบต่อเนื่องได้เป็นอย่างดี

# 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” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส AI Agents ให้อัปเกรดเป็น CoddyKit PRO คอร์ส AI Agents มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การส่งข้อมูลออกแบบสตรีมในตัวแทน CLI”

พิมพ์โทเค็นที่ส่งมาแบบสตรีมทีละอักขระในส่วนติดต่อเทอร์มินัล คุณปฏิบัติ AI Agents ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน AI Agents หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน AI Agents บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน

บทเรียน “การส่งข้อมูลออกแบบสตรีมในตัวแทน CLI” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน AI Agents นี้ได้ไหม

ได้ บทเรียน AI Agents ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การสร้างส่วนติดต่อบรรทัดคำสั่งสำหรับตัวแทน
  2. ตัวแทนรูปแบบ REPL แบบโต้ตอบ
  3. การแยกวิเคราะห์อาร์กิวเมนต์และข้อความช่วยเหลือ
  4. การส่งข้อมูลออกแบบสตรีมในตัวแทน CLI
← กลับไปที่ AI Agents