การส่งข้อมูลออกแบบสตรีมในตัวแทน 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 completeprint() เทียบกับ 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การสร้างส่วนติดต่อบรรทัดคำสั่งสำหรับตัวแทน
- ตัวแทนรูปแบบ REPL แบบโต้ตอบ
- การแยกวิเคราะห์อาร์กิวเมนต์และข้อความช่วยเหลือ
- การส่งข้อมูลออกแบบสตรีมในตัวแทน CLI