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

เฟรมเวิร์กเอเจนต์แบบอะซิงโครนัส: LangChain และอื่น ๆ

ainvoke(), astream() และสายงานแบบอะซิงโครนัสใน LangChain และ LangGraph

เฟรมเวิร์กเอเจนต์แบบอะซิงโครนัส: LangChain และอื่น ๆ เป็นบทเรียน AI Agents ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน AI Agents และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส AI Agents มีบทเรียนทั้งหมด 4 บทเรียน

การดำเนินการแบบอะซิงโครนัสใน LangChain

LangChain มีรุ่นแบบอะซิงโครนัสสำหรับอินเทอร์เฟซทั้งหมด ทุกองค์ประกอบที่มี invoke() จะมี ainvoke() ด้วย และทุกองค์ประกอบที่มี stream() จะมี astream() การทำงานแบบอะซิงโครนัสเป็นแนวทางที่แนะนำสำหรับเอเจนต์ในระบบจริง

ainvoke() สำหรับการเรียก LLM แบบอะซิงโครนัส

ainvoke() เป็นรูปแบบแบบอะซิงโครนัสที่เทียบเท่ากับ invoke() ใช้ภายในฟังก์ชันแบบอะซิงโครนัสเพื่อเรียก LLM โดยไม่บล็อกการทำงาน วิธีนี้ทำให้เอเจนต์หรือคำขอหลายรายการใช้ลูปเหตุการณ์ร่วมกันได้

import asyncio
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage

llm = ChatOpenAI(model='gpt-4o-mini', api_key='sk-...')

async def async_agent_call(question: str) -> str:
    # ainvoke: non-blocking, releases event loop while waiting for OpenAI
    response = await llm.ainvoke([HumanMessage(content=question)])
    return response.content

async def handle_multiple_users(questions: list) -> list:
    # All three LLM calls run concurrently
    results = await asyncio.gather(*[async_agent_call(q) for q in questions])
    return results

questions = [
    'What is Python?',
    'What is TypeScript?',
    'What is Rust?'
]

results = asyncio.run(handle_multiple_users(questions))
for q, a in zip(questions, results):
    print(f'Q: {q[:30]}... A: {a[:50]}...')

astream() สำหรับการสตรีมโทเค็น

astream() จะส่งคืนโทเค็นทันทีที่มาถึงจาก LLM วิธีนี้ช่วยให้คุณสตรีมคำตอบแก่ผู้ใช้แบบเรียลไทม์ โดยไม่ต้องรอให้ผลลัพธ์ทั้งหมดมาถึง

import asyncio
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage

llm = ChatOpenAI(model='gpt-4o-mini', api_key='sk-...')

async def stream_response(question: str):
    print(f'Streaming answer to: {question}\n')
    full_response = ''
    
    async for chunk in llm.astream([HumanMessage(content=question)]):
        token = chunk.content
        if token:
            print(token, end='', flush=True)  # Print each token as it arrives
            full_response += token
    
    print()  # New line after streaming
    return full_response

async def main():
    await stream_response('List 3 benefits of async programming in Python')

asyncio.run(main())

AsyncCallbackHandler

การเรียกกลับของ LangChain จะทำงานเมื่อเกิดเหตุการณ์เฉพาะ เช่น การเริ่มต้น LLM การสิ้นสุด LLM การเริ่มต้นเครื่องมือ และข้อผิดพลาดของสายงาน AsyncCallbackHandler จัดการเหตุการณ์เหล่านี้แบบอะซิงโครนัสโดยไม่บล็อกลูปของเอเจนต์

from langchain_core.callbacks import AsyncCallbackHandler
from typing import Any, Dict, List
import time

class LatencyCallbackHandler(AsyncCallbackHandler):
    def __init__(self):
        self.step_times = {}
        self.step_counts = {}
    
    async def on_llm_start(self, serialized: Dict, prompts: List[str], **kwargs):
        run_id = str(kwargs.get('run_id', ''))
        self.step_times[run_id] = time.perf_counter()
    
    async def on_llm_end(self, response, **kwargs):
        run_id = str(kwargs.get('run_id', ''))
        if run_id in self.step_times:
            elapsed_ms = (time.perf_counter() - self.step_times[run_id]) * 1000
            print(f'LLM call completed in {elapsed_ms:.0f}ms')
    
    async def on_tool_start(self, serialized: Dict, input_str: str, **kwargs):
        tool_name = serialized.get('name', 'unknown')
        print(f'Tool starting: {tool_name}')
    
    async def on_tool_error(self, error: Exception, **kwargs):
        print(f'Tool error: {error}')

handler = LatencyCallbackHandler()
print('Async callback handler created')
# Use: llm.ainvoke([...], config={'callbacks': [handler]})

ฟังก์ชันโหนดแบบอะซิงโครนัสของ LangGraph

โหนดของ LangGraph สามารถเป็นฟังก์ชันแบบอะซิงโครนัสได้ เมื่อคุณกำหนดโหนดด้วย async def LangGraph จะรอผลลัพธ์ระหว่างการดำเนินการกราฟ นี่คือรูปแบบที่แนะนำสำหรับกราฟในระบบจริง

import asyncio
from langgraph.graph import StateGraph, END
from typing import TypedDict, List

class AgentState(TypedDict):
    question: str
    entities: List[str]
    context: str
    answer: str

async def extract_entities_node(state: AgentState) -> AgentState:
    await asyncio.sleep(0.1)  # Simulate async NLP call
    entities = state['question'].split()[:3]  # Simplified
    return {'entities': entities}

async def retrieve_context_node(state: AgentState) -> AgentState:
    await asyncio.sleep(0.2)  # Simulate async vector search
    context = f'Context for entities: {state["entities"]}'
    return {'context': context}

async def generate_answer_node(state: AgentState) -> AgentState:
    await asyncio.sleep(0.3)  # Simulate async LLM call
    answer = f'Answer based on: {state["context"]}'
    return {'answer': answer}

# Build async graph
graph = StateGraph(AgentState)
graph.add_node('extract', extract_entities_node)
graph.add_node('retrieve', retrieve_context_node)
graph.add_node('generate', generate_answer_node)

graph.set_entry_point('extract')
graph.add_edge('extract', 'retrieve')
graph.add_edge('retrieve', 'generate')
graph.add_edge('generate', END)

app = graph.compile()
print('Async LangGraph compiled')

การสตรีมแบบอะซิงโครนัสจาก LangGraph

LangGraph รองรับการสตรีมสถานะระหว่างทางแบบอะซิงโครนัสขณะที่กราฟทำงาน ใช้ astream() เพื่อดูผลลัพธ์ของแต่ละโหนดทันทีที่เสร็จสิ้น แทนที่จะรอให้การทำงานทั้งหมดเสร็จ

import asyncio

async def stream_graph_execution(graph_app, initial_state: dict):
    print('Graph execution streaming:')
    async for step_output in graph_app.astream(initial_state):
        for node_name, state_delta in step_output.items():
            print(f'  Node [{node_name}] completed:')
            for key, value in state_delta.items():
                print(f'    {key}: {value}')

# Run the async graph
initial = {
    'question': 'What is machine learning?',
    'entities': [],
    'context': '',
    'answer': ''
}

asyncio.run(stream_graph_execution(app, initial))

การจำกัดอัตราการเรียกด้วยเซมาฟอร์

OpenAI และบริการ LLM อื่น ๆ มีขีดจำกัดอัตราการเรียกคำขอต่อนาที ใช้ Semaphore แบบอะซิงโครนัสเพื่อให้มั่นใจว่าคุณจะไม่เกินขีดจำกัด แม้จะเรียกใช้งานเอเจนต์หลายรายการพร้อมกัน

import asyncio
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage

llm = ChatOpenAI(model='gpt-4o-mini', api_key='sk-...')

# Limit to 10 concurrent LLM calls
LLM_SEMAPHORE = asyncio.Semaphore(10)

async def rate_limited_llm_call(question: str) -> str:
    async with LLM_SEMAPHORE:
        response = await llm.ainvoke([HumanMessage(content=question)])
        return response.content

async def process_large_batch(questions: list) -> list:
    print(f'Processing {len(questions)} questions with max 10 concurrent LLM calls')
    tasks = [rate_limited_llm_call(q) for q in questions]
    results = await asyncio.gather(*tasks, return_exceptions=True)
    
    successes = [r for r in results if not isinstance(r, Exception)]
    failures = [r for r in results if isinstance(r, Exception)]
    print(f'Success: {len(successes)}, Failed: {len(failures)}')
    return results

# Process 50 questions with max 10 concurrent calls
questions = [f'Question {i}: What is concept number {i}?' for i in range(20)]
asyncio.run(process_large_batch(questions))

การกำหนดเครื่องมือแบบอะซิงโครนัส

ใน LangChain ฟังก์ชันเครื่องมือสามารถทำงานแบบอะซิงโครนัสได้ เครื่องมือแบบอะซิงโครนัสจะถูกรอผลลัพธ์ระหว่างการทำงานของเอเจนต์ ทำให้การเรียกส่วนเชื่อมต่อโปรแกรมประยุกต์ภายในเครื่องมือไม่บล็อกการทำงาน

import asyncio
import httpx
from langchain.tools import tool

@tool
async def async_web_search(query: str) -> str:
    '''Search the web for information about the query.'''
    async with httpx.AsyncClient() as client:
        # Real implementation would use a search API
        response = await client.get(
            'https://api.search.example.com/search',
            params={'q': query, 'api_key': 'your-key'},
            timeout=10.0
        )
        response.raise_for_status()
        results = response.json()
        return '\n'.join([r['snippet'] for r in results.get('items', [])[:3]])

@tool
async def async_fetch_document(url: str) -> str:
    '''Fetch and return the text content of a URL.'''
    async with httpx.AsyncClient() as client:
        response = await client.get(url, timeout=15.0)
        return response.text[:3000]  # Limit content size

print('Async tools defined')
print('Use with: agent.ainvoke({"input": "your question"})')

เอเจนต์แบบอะซิงโครนัสด้วย OpenAI โดยตรง

คุณสามารถสร้างลูปเอเจนต์แบบอะซิงโครนัสเต็มรูปแบบโดยใช้ OpenAI SDK โดยตรงโดยไม่ต้องใช้ LangChain วิธีนี้ให้การควบคุมสูงสุดและมีค่าใช้จ่ายในการทำงานน้อยที่สุด

import asyncio
import openai
import json

client = openai.AsyncOpenAI(api_key='sk-...')

TOOLS = [
    {'type': 'function', 'function': {
        'name': 'web_search',
        'description': 'Search the web',
        'parameters': {'type': 'object', 'properties': {'query': {'type': 'string'}}, 'required': ['query']}
    }}
]

async def async_tool_call(tool_name: str, args: dict) -> str:
    if tool_name == 'web_search':
        await asyncio.sleep(0.3)  # Simulate search
        return f'Search results for: {args["query"]}'
    return 'Unknown tool'

async def async_agent_loop(question: str, max_turns: int = 5) -> str:
    messages = [{'role': 'user', 'content': question}]
    
    for turn in range(max_turns):
        response = await client.chat.completions.create(
            model='gpt-4o-mini', messages=messages, tools=TOOLS
        )
        msg = response.choices[0].message
        messages.append(msg)
        
        if not msg.tool_calls:
            return msg.content
        
        # Execute tool calls in parallel
        tool_results = await asyncio.gather(*[
            async_tool_call(tc.function.name, json.loads(tc.function.arguments))
            for tc in msg.tool_calls
        ])
        
        for tc, result in zip(msg.tool_calls, tool_results):
            messages.append({'role': 'tool', 'tool_call_id': tc.id, 'content': result})
    
    return 'Max turns reached'

result = asyncio.run(async_agent_loop('What is the latest news on AI?'))
print(result)

การยกเลิกและการคืนทรัพยากร

งานแบบอะซิงโครนัสสามารถถูกยกเลิกได้ จัดการ asyncio.CancelledError อย่างถูกต้อง เพื่อให้มั่นใจว่าทรัพยากรจะได้รับการคืนเมื่อการทำงานของเอเจนต์ถูกยกเลิก (เช่นจากคำขอของผู้ใช้หรือเวลาหมด)

import asyncio

async def cancellable_agent(question: str):
    try:
        print('Agent starting')
        await asyncio.sleep(0.5)  # Step 1
        print('Step 1 done')
        await asyncio.sleep(0.5)  # Step 2 - may be cancelled here
        print('Step 2 done')
        return 'Completed'
    except asyncio.CancelledError:
        print('Agent was cancelled - cleaning up')
        # Clean up resources: close connections, log cancellation
        raise  # Always re-raise CancelledError
    finally:
        print('Cleanup always runs')

async def run_with_timeout(question: str, timeout: float):
    task = asyncio.create_task(cancellable_agent(question))
    try:
        result = await asyncio.wait_for(task, timeout=timeout)
        return result
    except asyncio.TimeoutError:
        print(f'Agent exceeded {timeout}s timeout')
        task.cancel()
        return None

# Run with 0.7s timeout (not enough for both steps)
result = asyncio.run(run_with_timeout('test', timeout=0.7))
print('Final result:', result)

การทดสอบโค้ดเอเจนต์แบบอะซิงโครนัส

ทดสอบฟังก์ชันเอเจนต์แบบอะซิงโครนัสด้วย pytest-asyncio ทำเครื่องหมายฟังก์ชันทดสอบด้วย @pytest.mark.asyncio เพื่อให้ทำงานในลูปเหตุการณ์

import pytest
import asyncio
from unittest.mock import AsyncMock, patch

# Install: pip install pytest-asyncio
# pytest.ini: [pytest] asyncio_mode = auto

@pytest.mark.asyncio
async def test_async_agent_call():
    with patch('openai.AsyncOpenAI') as mock_openai:
        mock_client = AsyncMock()
        mock_openai.return_value = mock_client
        
        mock_response = AsyncMock()
        mock_response.choices[0].message.content = 'Mocked answer'
        mock_response.choices[0].message.tool_calls = None
        mock_client.chat.completions.create.return_value = mock_response
        
        # Test the async function
        result = await async_agent_call('What is Python?')
        assert isinstance(result, str)
        print('Async test passed')

@pytest.mark.asyncio
async def test_parallel_execution():
    start = asyncio.get_event_loop().time()
    results = await asyncio.gather(
        asyncio.sleep(0.1),
        asyncio.sleep(0.1),
        asyncio.sleep(0.1)
    )
    elapsed = asyncio.get_event_loop().time() - start
    assert elapsed < 0.3, 'Should complete in parallel'
    print(f'Parallel test passed: {elapsed:.2f}s')

แบบทดสอบความเข้าใจ: เฟรมเวิร์กแบบอะซิงโครนัส

ทดสอบความเข้าใจของคุณเกี่ยวกับเฟรมเวิร์กเอเจนต์แบบอะซิงโครนัส

สรุปเฟรมเวิร์กแบบอะซิงโครนัส

LangChain แบบอะซิงโครนัสมี ainvoke(), astream() และ AsyncCallbackHandler สำหรับเอเจนต์แบบอะซิงโครนัสที่พร้อมใช้งานในระบบจริง LangGraph รองรับฟังก์ชันโหนดแบบอะซิงโครนัสโดยกำเนิด ใช้เซมาฟอร์เพื่อจำกัดอัตราการเรียก ใช้ไคลเอ็นต์ AsyncOpenAI สำหรับการเรียกโดยตรง และใช้ pytest-asyncio สำหรับการทดสอบ การจัดการการยกเลิกอย่างถูกต้องช่วยให้คืนทรัพยากรได้อย่างเรียบร้อยเมื่อเอเจนต์ถูกรบกวนหรือหยุดทำงาน

คำถามที่พบบ่อย

บทเรียน “เฟรมเวิร์กเอเจนต์แบบอะซิงโครนัส: LangChain และอื่น ๆ” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “เฟรมเวิร์กเอเจนต์แบบอะซิงโครนัส: LangChain และอื่น ๆ” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส AI Agents ให้อัปเกรดเป็น CoddyKit PRO คอร์ส AI Agents มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “เฟรมเวิร์กเอเจนต์แบบอะซิงโครนัส: LangChain และอื่น ๆ”

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

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

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

บทเรียน “เฟรมเวิร์กเอเจนต์แบบอะซิงโครนัส: LangChain และอื่น ๆ” ใช้เวลานานแค่ไหน

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

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

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

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

  1. Python แบบอะซิงโครนัสสำหรับนักพัฒนาเอเจนต์
  2. คิวเหตุการณ์และตัวกลางรับส่งข้อความ
  3. การทำงานของเครื่องมือแบบขนานโดยไม่บล็อก
  4. เฟรมเวิร์กเอเจนต์แบบอะซิงโครนัส: LangChain และอื่น ๆ
← กลับไปที่ AI Agents