0Pricing
AI Engineering Academy · บทเรียน

การประมวลผลการเรียกใช้เครื่องมือในแอปพลิเคชัน

ตรวจจับ finish_reason tool_calls ในการตอบกลับจาก API แยกชื่อฟังก์ชันและอาร์กิวเมนต์ เรียกใช้ฟังก์ชัน Python ที่เกี่ยวข้อง และส่งผลลัพธ์กลับไปยังโมเดล

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

ออบเจ็กต์การตอบกลับการเรียกเครื่องมือ

เมื่อโมเดลตัดสินใจเรียกฟังก์ชัน การตอบกลับจาก API จะมีรายการ tool_calls อยู่ในออบเจ็กต์ข้อความ การเรียกเครื่องมือแต่ละครั้งมี id ที่ไม่ซ้ำกัน ชื่อฟังก์ชัน function.name ที่จะเรียก และ function.arguments ซึ่งเป็นสตริง JSON ของอาร์กิวเมนต์ที่โมเดลต้องการส่ง โค้ดของแอปพลิเคชันของคุณมีหน้าที่แยกวิเคราะห์ข้อมูลนี้และเรียกใช้ฟังก์ชัน

from openai import OpenAI
import json

client = OpenAI()

response = client.chat.completions.create(
    model='gpt-4o',
    messages=[{'role': 'user', 'content': 'What is the weather in Paris?'}],
    tools=tools  # defined previously
)

message = response.choices[0].message

if response.choices[0].finish_reason == 'tool_calls':
    for tool_call in message.tool_calls:
        print('Call ID:', tool_call.id)
        print('Function name:', tool_call.function.name)
        print('Arguments (JSON string):', tool_call.function.arguments)

การแยกวิเคราะห์อาร์กิวเมนต์ของฟังก์ชัน

ฟิลด์ function.arguments เป็นสตริงที่เข้ารหัสเป็น JSON ไม่ใช่ dict ของ Python คุณต้องแยกวิเคราะห์ด้วย json.loads() ควรครอบการทำงานนี้ด้วย try/except เสมอ — บางครั้งโมเดลสร้าง JSON ที่มีรูปแบบไม่ถูกต้องแม้จะมีคำแนะนำจากสคีมา และคุณต้องจัดการกรณีนี้อย่างเหมาะสม

import json

def parse_tool_call(tool_call) -> dict:
    '''Parse a tool call's arguments from JSON string to dict.'''
    try:
        args = json.loads(tool_call.function.arguments)
        return args
    except json.JSONDecodeError as e:
        print(f'Failed to parse arguments for {tool_call.function.name}: {e}')
        print(f'Raw arguments: {tool_call.function.arguments}')
        return {}

# Usage
tool_call = message.tool_calls[0]
args = parse_tool_call(tool_call)
print('Parsed args:', args)  # {'location': 'Paris', 'unit': 'celsius'}

การส่งต่อไปยังฟังก์ชันที่ถูกต้อง

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

def get_current_weather(location: str, unit: str = 'celsius') -> str:
    # Real implementation calls a weather API
    return f'{location}: 18{chr(176)}C, partly cloudy'

def create_calendar_event(title: str, start_time: str, duration_minutes: int, **kwargs) -> str:
    return f'Event created: {title} at {start_time} for {duration_minutes} minutes'

# Tool registry: maps function names to callables
TOOL_REGISTRY = {
    'get_current_weather': get_current_weather,
    'create_calendar_event': create_calendar_event
}

def execute_tool_call(tool_call) -> str:
    name = tool_call.function.name
    args = parse_tool_call(tool_call)

    if name not in TOOL_REGISTRY:
        return f'Unknown function: {name}'

    try:
        result = TOOL_REGISTRY[name](**args)
        return str(result)
    except Exception as e:
        return f'Function {name} raised an error: {str(e)}'

การส่งผลลัพธ์กลับไปยังโมเดล

หลังจากเรียกใช้ฟังก์ชันแล้ว คุณต้องส่งผลลัพธ์กลับไปยังโมเดลด้วยการเรียก API ติดตามผล เพิ่มข้อความของผู้ช่วย ซึ่งมี tool_calls อยู่ในบทสนทนา จากนั้นเพิ่มข้อความใหม่ที่มี role='tool' ค่า tool_call_id และผลลัพธ์ของฟังก์ชันเป็นเนื้อหา แล้วจึงเรียก API อีกครั้ง

def run_tool_call_loop(messages: list, tools: list) -> str:
    response = client.chat.completions.create(
        model='gpt-4o',
        messages=messages,
        tools=tools
    )
    message = response.choices[0].message
    messages.append(message)  # Add assistant's tool_calls message

    # Execute all tool calls and collect results
    for tool_call in (message.tool_calls or []):
        result = execute_tool_call(tool_call)
        # Add each tool result as a 'tool' role message
        messages.append({
            'role': 'tool',
            'tool_call_id': tool_call.id,
            'content': result
        })

    # Second API call with results appended
    final_response = client.chat.completions.create(
        model='gpt-4o',
        messages=messages,
        tools=tools
    )
    return final_response.choices[0].message.content

รอบการสนทนาแบบสมบูรณ์

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

# The full message history for a tool-calling conversation:
conversation = [
    {'role': 'user', 'content': 'What is the weather in Tokyo?'},

    # Model requests a tool call (added by run_tool_call_loop)
    # {'role': 'assistant', 'content': None, 'tool_calls': [...]},

    # Application sends tool result back
    # {'role': 'tool', 'tool_call_id': 'call_abc123', 'content': 'Tokyo: 22C, sunny'},

    # Model produces final human-readable response
    # {'role': 'assistant', 'content': 'The weather in Tokyo is 22 degrees Celsius and sunny.'}
]

final_answer = run_tool_call_loop(
    [{'role': 'user', 'content': 'What is the weather in Tokyo?'}],
    tools
)
print(final_answer)

การจัดการกรณีที่ไม่มีการเรียกเครื่องมือ

บางครั้งโมเดลตอบโดยตรงโดยไม่เรียกเครื่องมือใด ๆ — finish_reason จะเป็น 'stop' แทนที่จะเป็น 'tool_calls' ตรวจสอบกรณีนี้เสมอก่อนพยายามประมวลผลการเรียกเครื่องมือ การใช้งานที่มีความทนทานควรจัดการทั้งสองเส้นทางได้อย่างเป็นระเบียบ

def smart_complete(user_message: str) -> str:
    messages = [{'role': 'user', 'content': user_message}]
    response = client.chat.completions.create(
        model='gpt-4o',
        messages=messages,
        tools=tools
    )
    choice = response.choices[0]

    if choice.finish_reason == 'stop':
        # Model answered directly without calling a tool
        return choice.message.content

    elif choice.finish_reason == 'tool_calls':
        # Process tool calls
        messages.append(choice.message)
        for tc in choice.message.tool_calls:
            result = execute_tool_call(tc)
            messages.append({'role': 'tool', 'tool_call_id': tc.id, 'content': result})
        # Get final answer
        final = client.chat.completions.create(model='gpt-4o', messages=messages)
        return final.choices[0].message.content

    return 'Unexpected finish reason: ' + choice.finish_reason

การตรวจสอบอาร์กิวเมนต์ก่อนเรียกใช้

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

from pydantic import BaseModel, ValidationError
from datetime import datetime

class CreateEventArgs(BaseModel):
    title: str
    start_time: str  # ISO 8601
    duration_minutes: int

def safe_create_event(tool_call) -> str:
    try:
        raw_args = json.loads(tool_call.function.arguments)
        validated = CreateEventArgs(**raw_args)
        # Additional business rule
        event_time = datetime.fromisoformat(validated.start_time)
        if event_time < datetime.now():
            return 'Error: start_time must be in the future.'
        return create_calendar_event(**validated.dict())
    except ValidationError as e:
        return f'Invalid arguments: {e}'

การบันทึกการโต้ตอบจากการเรียกเครื่องมือ

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

import time
import logging

logger = logging.getLogger('tool_calls')

def logged_execute(tool_call) -> str:
    name = tool_call.function.name
    args_str = tool_call.function.arguments
    start = time.time()
    result = execute_tool_call(tool_call)
    elapsed = time.time() - start

    logger.info(
        'Tool call executed',
        extra={
            'function': name,
            'arguments': args_str,
            'result_length': len(result),
            'elapsed_ms': round(elapsed * 1000)
        }
    )
    return result

ข้อควรพิจารณาด้านความปลอดภัยของการเรียกเครื่องมือ

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

  • อนุญาตเฉพาะฟังก์ชันที่ระบุไว้อย่างชัดเจนในทะเบียนเครื่องมือ
  • ตรวจสอบอินพุตด้วย Pydantic ก่อนเรียกใช้
  • กำหนดให้ต้องมีสิทธิ์สำหรับการดำเนินการเขียนหรือลบ

การส่งคืนผลลัพธ์ที่มีโครงสร้างและรายละเอียด

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

def get_order_status(order_id: str) -> str:
    # Fetch from real database
    order = {'id': order_id, 'status': 'shipped', 'estimated_delivery': '2024-03-15', 'carrier': 'FedEx', 'tracking': 'FX123456'}
    # Return concise summary, not raw DB record
    return (
        f'Order {order_id}: Status={order["status"]}, '
        f'Estimated delivery: {order["estimated_delivery"]}, '
        f'Carrier: {order["carrier"]}, Tracking: {order["tracking"]}'
    )

บทสนทนาหลายรอบที่ใช้เครื่องมือ

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

ตรวจสอบความเข้าใจอย่างรวดเร็ว

ทดสอบความเข้าใจของคุณเกี่ยวกับการประมวลผลการเรียกเครื่องมือในแอปพลิเคชันของคุณ

สรุปบทเรียน

ในบทเรียนนี้ คุณได้เรียนรู้ว่า อาร์กิวเมนต์ของการเรียกเครื่องมือมาในรูปสตริง JSON ที่ต้องแยกวิเคราะห์ด้วย json.loads() พจนานุกรม TOOL_REGISTRY แมปชื่อฟังก์ชันกับฟังก์ชันที่เรียกใช้ได้เพื่อการส่งต่อที่เป็นระเบียบ และ ผลลัพธ์จะถูกส่งกลับไปยังโมเดลเป็นข้อความที่มี role='tool' พร้อม tool_call_id ที่ตรงกัน บทถัดไป เราจะจัดการกรณีที่โมเดลเรียกใช้หลายฟังก์ชันพร้อมกันด้วยการเรียกฟังก์ชันแบบขนาน

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

บทเรียน “การประมวลผลการเรียกใช้เครื่องมือในแอปพลิเคชัน” ฟรีหรือไม่

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

คุณจะเรียนรู้อะไรในบทเรียน “การประมวลผลการเรียกใช้เครื่องมือในแอปพลิเคชัน”

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

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

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

บทเรียน “การประมวลผลการเรียกใช้เครื่องมือในแอปพลิเคชัน” ใช้เวลานานแค่ไหน

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

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

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

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

  1. การกำหนดโครงสร้างฟังก์ชันสำหรับ API
  2. การประมวลผลการเรียกใช้เครื่องมือในแอปพลิเคชัน
  3. การเรียกใช้ฟังก์ชันแบบขนาน
  4. การสร้างส่วนติดต่อฐานข้อมูลด้วยภาษาธรรมชาติ
← กลับไปที่ AI Engineering Academy