AI Agents · บทเรียน

การออกแบบเครื่องมือเอเจนต์ที่แบ่งปันได้

มาตรฐานโครงร่างเครื่องมือ ข้อกำหนดด้านเอกสาร และการจัดแพ็กเกจเพื่อนำกลับมาใช้ใหม่

บทเรียน 1 จาก 413 ขั้นตอน

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

อะไรทำให้เครื่องมือสามารถแบ่งปันได้

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

มาตรฐานสคีมาของเครื่องมือ

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

TOOL_SCHEMA_TEMPLATE = {
    'name': 'get_weather',
    'description': 'Returns current weather conditions for a city. '
                   'Use when the user asks about weather or temperature.',
    'version': '1.2.0',
    'parameters': {
        'type': 'object',
        'properties': {
            'city': {
                'type': 'string',
                'description': 'City name (e.g., London, Tokyo)',
                'minLength': 1,
                'maxLength': 100
            },
            'units': {
                'type': 'string',
                'enum': ['celsius', 'fahrenheit'],
                'default': 'celsius',
                'description': 'Temperature unit'
            }
        },
        'required': ['city']
    },
    'returns': {
        'type': 'object',
        'properties': {
            'temperature': {'type': 'number'},
            'condition': {'type': 'string'},
            'humidity_pct': {'type': 'number'}
        }
    },
    'rate_limit': {'calls_per_minute': 60}
}

if __name__ == '__main__':
    print(f"Tool: {TOOL_SCHEMA_TEMPLATE['name']} (v{TOOL_SCHEMA_TEMPLATE['version']})")
    print('Description:', TOOL_SCHEMA_TEMPLATE['description'])
    print('Required params:', TOOL_SCHEMA_TEMPLATE['parameters']['required'])

รหัสข้อผิดพลาด

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

from enum import Enum

class ToolErrorCode(Enum):
    INVALID_PARAMS = 'INVALID_PARAMS'
    NOT_FOUND = 'NOT_FOUND'
    RATE_LIMITED = 'RATE_LIMITED'
    UPSTREAM_ERROR = 'UPSTREAM_ERROR'
    TIMEOUT = 'TIMEOUT'
    UNAUTHORISED = 'UNAUTHORISED'
    INTERNAL_ERROR = 'INTERNAL_ERROR'

class ToolError(Exception):
    def __init__(self, code: ToolErrorCode, message: str, details: dict = None):
        self.code = code
        self.message = message
        self.details = details or {}

    def to_dict(self) -> dict:
        return {
            'error': True,
            'code': self.code.value,
            'message': self.message,
            'details': self.details
        }

try:
    raise ToolError(
        ToolErrorCode.NOT_FOUND,
        'City not found in database',
        {'city': 'Atlantis', 'suggestion': 'Did you mean Athens?'}
    )
except ToolError as e:
    print(e.to_dict())

การตรวจสอบอินพุต

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

import jsonschema  # pip install jsonschema

def validate_tool_input(params: dict, schema: dict) -> dict:
    """
    Validate params against schema.
    Returns validated (and default-filled) params.
    Raises ToolError on validation failure.
    """
    try:
        # Fill in defaults
        filled = dict(params)
        for prop, definition in schema['properties'].items():
            if prop not in filled and 'default' in definition:
                filled[prop] = definition['default']

        # Validate against schema
        jsonschema.validate(instance=filled, schema=schema)
        return filled

    except jsonschema.ValidationError as e:
        raise ToolError(
            ToolErrorCode.INVALID_PARAMS,
            f'Validation failed: {e.message}',
            {'path': list(e.path), 'schema_path': list(e.schema_path)}
        )

# Example usage:
try:
    params = validate_tool_input({'city': 'London'}, TOOL_SCHEMA_TEMPLATE['parameters'])
    print('Valid params:', params)
except ToolError as e:
    print('Error:', e.to_dict())

ตัวอย่างการใช้งานในสคีมา

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

TOOL_WITH_EXAMPLES = {
    'name': 'search_knowledge_base',
    'description': 'Search the company knowledge base for documentation.',
    'parameters': {
        'type': 'object',
        'properties': {
            'query': {'type': 'string'},
            'top_k': {'type': 'integer', 'default': 5, 'minimum': 1, 'maximum': 20}
        },
        'required': ['query']
    },
    'examples': [
        {
            'description': 'Search for onboarding docs',
            'input': {'query': 'how to onboard new users', 'top_k': 3},
            'output': {'results': [{'title': 'User Onboarding Guide', 'score': 0.95}]}
        },
        {
            'description': 'Search with default top_k',
            'input': {'query': 'API authentication'},
            'output': {'results': [{'title': 'API Auth Docs', 'score': 0.88}]}
        }
    ]
}

if __name__ == '__main__':
    print('Tool:', TOOL_WITH_EXAMPLES['name'])
    for ex in TOOL_WITH_EXAMPLES['examples']:
        print(f" - {ex['description']}: input={ex['input']} -> output={ex['output']}")

การจำกัดอัตราในเครื่องมือ

เครื่องมือที่เรียกใช้ API ภายนอกต้องปฏิบัติตามขีดจำกัดอัตราการเรียกใช้ ให้ใช้ตัวจำกัดอัตราต่อเครื่องมือโดยใช้บักเก็ตโทเคนหรือหน้าต่างเลื่อน เมื่อเกินขีดจำกัด ให้ส่งคืนข้อผิดพลาดมาตรฐาน RATE_LIMITED พร้อมจำนวนวินาทีที่ควรรอก่อนลองใหม่

import time
from collections import deque

class SlidingWindowRateLimiter:
    def __init__(self, max_calls: int, window_seconds: int):
        self.max_calls = max_calls
        self.window = window_seconds
        self._calls = deque()  # timestamps of recent calls

    def check(self) -> tuple:
        """
        Returns (allowed: bool, retry_after_seconds: float)
        """
        now = time.time()
        # Remove calls outside the window
        while self._calls and self._calls[0] < now - self.window:
            self._calls.popleft()

        if len(self._calls) >= self.max_calls:
            oldest = self._calls[0]
            retry_after = (oldest + self.window) - now
            return False, round(retry_after, 1)

        self._calls.append(now)
        return True, 0.0

weather_limiter = SlidingWindowRateLimiter(max_calls=10, window_seconds=60)
allowed, retry = weather_limiter.check()
if not allowed:
    raise ToolError(ToolErrorCode.RATE_LIMITED,
                    f'Rate limit exceeded. Retry in {retry}s',
                    {'retry_after': retry})

การจัดแพ็กเกจเป็นแพ็กเกจ Python

จัดโครงสร้างเครื่องมือของคุณเป็นแพ็กเกจ Python ที่ติดตั้งได้ เพื่อให้นักพัฒนาคนอื่นเพิ่มเครื่องมือนี้ลงในเอเจนต์ได้ด้วยคำสั่ง pip install เพียงคำสั่งเดียว แพ็กเกจจะเปิดเผยฟังก์ชัน get_tool_definition() และฟังก์ชัน execute(params) เป็น API สาธารณะ

# Directory structure:
# agent_tool_weather/
#   __init__.py
#   tool.py
#   schema.py
#   pyproject.toml
#   README.md

# agent_tool_weather/tool.py
from .schema import SCHEMA
from .errors import ToolError, ToolErrorCode

def get_tool_definition() -> dict:
    return SCHEMA

def execute(params: dict) -> dict:
    validated = validate_tool_input(params, SCHEMA['parameters'])
    city = validated['city']
    units = validated['units']
    return _fetch_weather(city, units)

def _fetch_weather(city: str, units: str) -> dict:
    import requests
    url = f'https://api.weather.example.com/current?city={city}&units={units}'
    response = requests.get(url, headers={'X-API-Key': 'YOUR_KEY'}, timeout=5)
    if response.status_code == 404:
        raise ToolError(ToolErrorCode.NOT_FOUND, f'City not found: {city}')
    response.raise_for_status()
    return response.json()

การเขียน README ของเครื่องมือ

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

README_TEMPLATE = '''
# agent-tool-weather

Get real-time weather conditions for any city.

## Installation

pip install agent-tool-weather

## Setup

import os
os.environ["WEATHER_API_KEY"] = "your-key-here"

## Usage

from agent_tool_weather import get_tool_definition, execute

# In your agent
tool_def = get_tool_definition()

# Execute
result = execute({"city": "Tokyo", "units": "celsius"})
print(result)
# {"temperature": 22.5, "condition": "Partly cloudy", "humidity_pct": 65}

## Parameters

| Name  | Type   | Required | Default  | Description     |
|-------|--------|----------|----------|-----------------|
| city  | string | Yes      | -        | City name       |
| units | string | No       | celsius  | celsius or fahrenheit |

## Error Codes

- INVALID_PARAMS: Parameter validation failed
- NOT_FOUND: City not found
- RATE_LIMITED: 60 calls/minute limit exceeded
- UPSTREAM_ERROR: Weather API unavailable
'''

print(README_TEMPLATE[:300])

การทดสอบเครื่องมือที่สามารถแบ่งปันได้

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

import pytest

def test_valid_city_returns_weather(mock_weather_api):
    result = execute({'city': 'London'})
    assert 'temperature' in result
    assert 'condition' in result
    assert isinstance(result['temperature'], (int, float))

def test_missing_required_param_raises_error():
    with pytest.raises(ToolError) as exc_info:
        execute({})  # city is required
    assert exc_info.value.code == ToolErrorCode.INVALID_PARAMS

def test_unknown_city_raises_not_found(mock_weather_api_404):
    with pytest.raises(ToolError) as exc_info:
        execute({'city': 'Atlantis'})
    assert exc_info.value.code == ToolErrorCode.NOT_FOUND

def test_default_units_is_celsius():
    params = validate_tool_input({'city': 'Paris'}, TOOL_SCHEMA_TEMPLATE['parameters'])
    assert params['units'] == 'celsius'

def test_rate_limit_enforced():
    limiter = SlidingWindowRateLimiter(max_calls=2, window_seconds=60)
    limiter.check()  # call 1
    limiter.check()  # call 2
    allowed, _ = limiter.check()  # call 3 — should fail
    assert not allowed

รูปแบบที่เข้ากันได้กับการเรียกฟังก์ชันของ OpenAI

เพื่อให้เข้ากันได้กับ API การใช้เครื่องมือแบบเนทีฟของ OpenAI และ Claude ให้ตรวจสอบว่าสคีมาของเครื่องมืออยู่ในรูปแบบที่ API เหล่านั้นคาดไว้ทุกประการ เมธอด get_openai_schema() จะแปลงสคีมาภายในของคุณเป็นรูปแบบที่เข้ากันได้กับ OpenAI

def get_openai_schema(tool_schema: dict) -> dict:
    """Convert internal tool schema to OpenAI function-calling format."""
    return {
        'type': 'function',
        'function': {
            'name': tool_schema['name'],
            'description': tool_schema['description'],
            'parameters': tool_schema['parameters']
        }
    }

def get_anthropic_schema(tool_schema: dict) -> dict:
    """Convert to Anthropic tool format."""
    return {
        'name': tool_schema['name'],
        'description': tool_schema['description'],
        'input_schema': tool_schema['parameters']
    }

# Usage in an agent:
openai_tools = [get_openai_schema(t) for t in [TOOL_SCHEMA_TEMPLATE]]
anthropic_tools = [get_anthropic_schema(t) for t in [TOOL_SCHEMA_TEMPLATE]]
print('OpenAI format:', openai_tools[0]['function']['name'])
print('Anthropic format:', anthropic_tools[0]['name'])

การจัดการเวอร์ชันของเครื่องมือ

ใช้การกำหนดเวอร์ชันตามหลักความหมาย: MAJOR.MINOR.PATCH เพิ่มค่า MAJOR เมื่อมีการเปลี่ยนแปลงสคีมาที่ทำให้เข้ากันไม่ได้ เพิ่มค่า MINOR เมื่อเพิ่มพารามิเตอร์ที่ไม่จำเป็น และเพิ่มค่า PATCH สำหรับการแก้ไขข้อบกพร่อง เก็บเวอร์ชันไว้ในสคีมาและเปิดเผยผ่าน get_tool_definition()

VERSION = '1.2.0'

def bump_version(current: str, change_type: str) -> str:
    parts = list(map(int, current.split('.')))
    if change_type == 'major':
        return f'{parts[0]+1}.0.0'
    if change_type == 'minor':
        return f'{parts[0]}.{parts[1]+1}.0'
    if change_type == 'patch':
        return f'{parts[0]}.{parts[1]}.{parts[2]+1}'
    raise ValueError(f'Unknown change_type: {change_type}')

# Breaking change (removed required param) -> major
print(bump_version('1.2.0', 'major'))  # 2.0.0
# Added optional param -> minor
print(bump_version('1.2.0', 'minor'))  # 1.3.0
# Bug fix -> patch
print(bump_version('1.2.0', 'patch'))  # 1.2.1

ตรวจสอบความรู้

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

ทบทวน: การออกแบบเครื่องมือเอเจนต์ที่สามารถแบ่งปันได้

ประเด็นสำคัญจากบทเรียนนี้:

  • สคีมา: ชื่อ คำอธิบาย เวอร์ชัน พารามิเตอร์ (JSON Schema) ค่าที่ส่งคืน และขีดจำกัดอัตรา
  • รหัสข้อผิดพลาด: ToolError มาตรฐานที่มีรหัส ข้อความ และรายละเอียด
  • การตรวจสอบอินพุต: jsonschema ตรวจสอบตามสคีมาพารามิเตอร์ก่อนการดำเนินการ
  • ตัวอย่าง: รวมอยู่ในสคีมาเป็นบริบทจากตัวอย่างจำนวนน้อย
  • การจำกัดอัตรา: หน้าต่างเลื่อนพร้อมข้อผิดพลาด RATE_LIMITED และเวลาที่ควรรอก่อนลองใหม่
  • การจัดแพ็กเกจ: แพ็กเกจที่ติดตั้งด้วย pip ได้ พร้อม README การทดสอบ และการจัดการเวอร์ชัน

ถัดไป: การค้นหาปลั๊กอินและการโหลดเครื่องมือแบบไดนามิก

เริ่มต้นได้ฟรี

เรียนรู้ AI Agents ด้วย AI tutor — ฟรี

เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป

คอร์ส
60
บทเรียน
239

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

บทเรียน “การออกแบบเครื่องมือเอเจนต์ที่แบ่งปันได้” ฟรีหรือไม่

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

คุณจะเรียนรู้อะไรในบทเรียน “การออกแบบเครื่องมือเอเจนต์ที่แบ่งปันได้”

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

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

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

บทเรียน “การออกแบบเครื่องมือเอเจนต์ที่แบ่งปันได้” ใช้เวลานานแค่ไหน

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

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

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

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

  1. การออกแบบเครื่องมือเอเจนต์ที่แบ่งปันได้
  2. การค้นพบและลงทะเบียนปลั๊กอิน
  3. การกำหนดรุ่นและความเข้ากันได้ของเครื่องมือ
  4. การสร้างตลาดปลั๊กอินเอเจนต์
← กลับไปที่ AI Agents