AI Agents · บทเรียน

การสร้างตลาดปลั๊กอินเอเจนต์

คลังเครื่องมือส่วนกลาง: เผยแพร่ ให้คะแนน และแจกจ่ายปลั๊กอินเอเจนต์

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

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

ตลาดกลางปลั๊กอินของเอเจนต์คืออะไร

ตลาดกลางปลั๊กอินคือทะเบียนส่วนกลางที่นักพัฒนาใช้เผยแพร่เครื่องมือที่แบ่งปันได้ นักพัฒนาคนอื่นใช้ค้นหาเครื่องมือเหล่านั้น และระบบเอเจนต์ใช้ติดตั้งโดยอัตโนมัติ ลองนึกถึง npm สำหรับเครื่องมือเอเจนต์: เผยแพร่ครั้งเดียว ใช้ได้ทุกที่

สถาปัตยกรรมตลาดกลาง

ตลาดกลางมีบริการหลักสี่ส่วน: ทะเบียน (จัดเก็บข้อมูลเมตาของปลั๊กอินในฐานข้อมูล), พื้นที่จัดเก็บ (จัดเก็บไฟล์เก็บถาวรของปลั๊กอินในพื้นที่จัดเก็บแบบออบเจ็กต์), การค้นหา (ดัชนีข้อความเต็ม) และ ความปลอดภัย (ลงลายเซ็นและตรวจสอบแพ็กเกจ) โดยทั้งหมดเปิดให้ใช้งานผ่าน API แบบ REST

# Marketplace REST API endpoints:
API_ROUTES = {
    'POST /plugins': 'Publish a new plugin version',
    'GET /plugins': 'List all plugins (paginated)',
    'GET /plugins/search?q=weather': 'Search by keyword',
    'GET /plugins/{name}': 'Get plugin metadata',
    'GET /plugins/{name}/{version}': 'Get specific version metadata',
    'GET /plugins/{name}/{version}/download': 'Download plugin archive',
    'POST /plugins/{name}/{version}/reviews': 'Submit a rating/review',
    'GET /plugins/{name}/reviews': 'Get all reviews',
    'DELETE /plugins/{name}/{version}': 'Yank (hide) a version',
}

for route, description in API_ROUTES.items():
    print(f'{route}: {description}')

การเผยแพร่ปลั๊กอิน

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

import hashlib
import hmac
import os

def publish_plugin(
    archive_path: str,
    api_key: str,
    registry_url: str = 'https://registry.agenttools.io'
) -> dict:
    import requests

    # Compute checksum for integrity
    with open(archive_path, 'rb') as f:
        data = f.read()
    sha256 = hashlib.sha256(data).hexdigest()

    # Sign the archive with the developer's API key
    signature = hmac.new(
        api_key.encode(), data, hashlib.sha256
    ).hexdigest()

    response = requests.post(
        f'{registry_url}/plugins',
        files={'archive': (os.path.basename(archive_path), data, 'application/zip')},
        headers={
            'X-API-Key': api_key,
            'X-Signature': signature,
            'X-Checksum-SHA256': sha256
        },
        timeout=60
    )
    response.raise_for_status()
    return response.json()

การตรวจสอบฝั่งเซิร์ฟเวอร์ขณะเผยแพร่

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

import zipfile
import io
import json

MAX_ARCHIVE_SIZE_MB = 50

def validate_plugin_archive(archive_bytes: bytes) -> dict:
    errors = []

    # Size check
    size_mb = len(archive_bytes) / 1024 / 1024
    if size_mb > MAX_ARCHIVE_SIZE_MB:
        errors.append(f'Archive too large: {size_mb:.1f}MB (max {MAX_ARCHIVE_SIZE_MB}MB)')
        return {'valid': False, 'errors': errors}

    # Must be a valid zip
    try:
        zf = zipfile.ZipFile(io.BytesIO(archive_bytes))
    except zipfile.BadZipFile:
        errors.append('Not a valid zip archive')
        return {'valid': False, 'errors': errors}

    file_list = zf.namelist()

    # Must contain plugin.json
    if 'plugin.json' not in file_list:
        errors.append('Missing plugin.json in archive root')

    # Basic security scan: no .pyc files, no hidden dirs
    suspicious = [f for f in file_list if f.startswith('.') or '__pycache__' in f]
    if suspicious:
        errors.append(f'Suspicious files: {suspicious[:3]}')

    return {'valid': len(errors) == 0, 'errors': errors, 'files': len(file_list)}

if __name__ == '__main__':
    buf = io.BytesIO()
    with zipfile.ZipFile(buf, 'w') as zf:
        zf.writestr('plugin.json', '{"name": "demo-plugin"}')
    archive_bytes = buf.getvalue()
    print('Validation result:', validate_plugin_archive(archive_bytes))

การลงลายเซ็นและการตรวจสอบแพ็กเกจ

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

import hashlib
import hmac

def sign_package(archive_bytes: bytes, secret_key: str) -> str:
    return hmac.new(
        secret_key.encode(), archive_bytes, hashlib.sha256
    ).hexdigest()

def verify_package(
    archive_bytes: bytes,
    signature: str,
    secret_key: str
) -> bool:
    expected = sign_package(archive_bytes, secret_key)
    return hmac.compare_digest(expected, signature)

# Example:
package_data = b'fake plugin archive bytes'
developer_key = 'developer_secret_key_abc123'

sig = sign_package(package_data, developer_key)
print(f'Signature: {sig[:20]}...')

# Verify (registry or installer):
valid = verify_package(package_data, sig, developer_key)
print(f'Signature valid: {valid}')

# Tampered data:
tampered = b'tampered bytes'
print(f'Tampered valid: {verify_package(tampered, sig, developer_key)}')

การค้นพบปลั๊กอินผ่านการค้นหา

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

import requests

def search_marketplace(
    query: str,
    tags: list = None,
    page: int = 0,
    per_page: int = 20,
    registry_url: str = 'https://registry.agenttools.io'
) -> dict:
    params = {
        'q': query,
        'page': page,
        'per_page': per_page
    }
    if tags:
        params['tags'] = ','.join(tags)

    response = requests.get(
        f'{registry_url}/plugins/search',
        params=params,
        timeout=10
    )
    response.raise_for_status()
    return response.json()

# Usage:
results = search_marketplace('weather forecast', tags=['iot', 'weather'])
# {
#   'total': 12,
#   'results': [
#     {'name': 'weather-tools', 'version': '2.1.0', 'score': 0.98, ...},
#     ...
#   ]
# }
print(f'Total results: {results.get("total", 0)}')

การติดตั้งปลั๊กอิน

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

import requests
import zipfile
import io
import shutil
import os

def install_plugin(
    plugin_name: str,
    version: str = 'latest',
    plugins_dir: str = 'plugins',
    registry_url: str = 'https://registry.agenttools.io'
) -> bool:
    # Step 1: Get metadata including expected signature
    meta = requests.get(
        f'{registry_url}/plugins/{plugin_name}/{version}',
        timeout=10
    ).json()

    # Step 2: Download archive
    archive_resp = requests.get(
        meta['download_url'], timeout=60
    )
    archive_bytes = archive_resp.content

    # Step 3: Verify signature
    if not verify_package(archive_bytes, meta['signature'], meta['public_key']):
        print('Signature verification FAILED — aborting install')
        return False

    # Step 4: Extract
    install_path = os.path.join(plugins_dir, plugin_name)
    if os.path.exists(install_path):
        shutil.rmtree(install_path)  # remove old version
    with zipfile.ZipFile(io.BytesIO(archive_bytes)) as zf:
        zf.extractall(install_path)

    print(f'Installed {plugin_name} v{version} to {install_path}')
    return True

ระบบการให้คะแนนและบทวิจารณ์

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

import requests

def submit_review(
    plugin_name: str,
    stars: int,
    review_text: str = '',
    api_key: str = '',
    registry_url: str = 'https://registry.agenttools.io'
) -> dict:
    if not 1 <= stars <= 5:
        raise ValueError('Stars must be 1-5')
    payload = {
        'stars': stars,
        'review': review_text[:500]  # truncate to max length
    }
    response = requests.post(
        f'{registry_url}/plugins/{plugin_name}/reviews',
        json=payload,
        headers={'X-API-Key': api_key},
        timeout=10
    )
    response.raise_for_status()
    return response.json()

def get_reviews(plugin_name: str, registry_url: str = 'https://registry.agenttools.io') -> dict:
    response = requests.get(
        f'{registry_url}/plugins/{plugin_name}/reviews',
        timeout=10
    )
    return response.json()

# Example response structure:
# {'average_stars': 4.3, 'total_reviews': 47,
#  'reviews': [{'stars': 5, 'review': 'Works great!', 'date': '...'}]}
print('Review system ready')

การถอนรุ่น (การเลิกใช้งาน)

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

import requests

def yank_version(
    plugin_name: str,
    version: str,
    reason: str,
    api_key: str,
    registry_url: str = 'https://registry.agenttools.io'
) -> dict:
    response = requests.delete(
        f'{registry_url}/plugins/{plugin_name}/{version}',
        json={'reason': reason},
        headers={'X-API-Key': api_key},
        timeout=10
    )
    response.raise_for_status()
    return response.json()

# Yanked versions:
# - Still downloadable by users who have them pinned
# - Not returned in 'latest' queries
# - Search results show a 'yanked' badge with reason
# - Install of yanked version requires explicit --allow-yanked flag

print('Yanking removes a version from new installs without breaking existing ones.')
print('Always provide a reason: "Security vulnerability in API key handling"')

เครื่องมือ CLI ของตลาดกลาง

ส่วนติดต่อบรรทัดคำสั่งช่วยให้ใช้งานตลาดกลางจากเทอร์มินัลหรือกระบวนการ CI ได้สะดวก ให้สร้างคำสั่ง marketplace install, marketplace search, marketplace publish และ marketplace list

import argparse
import sys

def main():
    parser = argparse.ArgumentParser(description='Agent Tool Marketplace CLI')
    subparsers = parser.add_subparsers(dest='command')

    # Search
    search_parser = subparsers.add_parser('search', help='Search plugins')
    search_parser.add_argument('query', help='Search query')
    search_parser.add_argument('--tag', action='append', dest='tags')

    # Install
    install_parser = subparsers.add_parser('install', help='Install a plugin')
    install_parser.add_argument('plugin', help='Plugin name')
    install_parser.add_argument('--version', default='latest')
    install_parser.add_argument('--plugins-dir', default='plugins')

    # Publish
    publish_parser = subparsers.add_parser('publish', help='Publish plugin')
    publish_parser.add_argument('archive', help='Path to .zip archive')
    publish_parser.add_argument('--api-key', required=True)

    args = parser.parse_args()
    if args.command == 'search':
        results = search_marketplace(args.query, tags=args.tags or [])
        for r in results.get('results', []):
            print(f'{r["name"]} v{r["version"]} ({r.get("average_stars", "?")} stars)')
    elif args.command == 'install':
        install_plugin(args.plugin, args.version, args.plugins_dir)
    elif args.command == 'publish':
        result = publish_plugin(args.archive, args.api_key)
        print('Published:', result)

การกำกับดูแลตลาดกลาง

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

MARKETPLACE_POLICIES = {
    'namespace_policy': (
        'Plugin names must be unique across the registry. '
        'Names are claimed on first publish. '
        'Transfers require proof of original authorship.'
    ),
    'security_scanning': (
        'All uploads are scanned with bandit (Python security linter). '
        'Critical vulnerabilities block publish. '
        'High vulnerabilities generate a warning visible to installers.'
    ),
    'rate_limits': {
        'publish_per_hour': 10,
        'search_per_minute': 60,
        'install_per_minute': 30
    },
    'takedown_process': (
        'Maintainers can yank versions at any time. '
        'Legal/security takedowns processed within 48 hours. '
        'Appeals via security@agenttools.io'
    )
}

for policy, detail in MARKETPLACE_POLICIES.items():
    if isinstance(detail, str):
        print(f'{policy}: {detail[:80]}...')
    else:
        print(f'{policy}: {detail}')

ตรวจสอบความเข้าใจ

การถอนรุ่นปลั๊กอินแตกต่างจากการลบปลั๊กอินอย่างไร

สรุป: การสร้างตลาดกลางปลั๊กอินของเอเจนต์

ยินดีด้วยที่เรียนบทเรียนนี้จบแล้ว! ประเด็นสำคัญมีดังนี้:

  • กระบวนการเผยแพร่: ตรวจสอบไฟล์เก็บถาวร → ตรวจสอบลายเซ็น → สแกน → จัดเก็บและทำดัชนี
  • การลงลายเซ็นแพ็กเกจ: ลายเซ็น HMAC ช่วยรับรองความถูกต้องครบถ้วน ไคลเอนต์จะตรวจสอบก่อนติดตั้ง
  • การค้นหา: การค้นหาข้อความเต็มพร้อมการกรองด้วยป้ายกำกับและการจัดอันดับตามความเกี่ยวข้อง
  • การติดตั้ง: ดาวน์โหลด → ตรวจสอบ → แตกไฟล์ → ตรวจสอบ → ลงทะเบียน (ย้อนกลับเมื่อเกิดความล้มเหลว)
  • การให้คะแนน: คะแนน 1–5 ดาวและบทวิจารณ์ข้อความที่รวมไว้ในทะเบียน
  • การถอนรุ่น: ซ่อนรุ่นจากการติดตั้งใหม่โดยไม่ทำให้การติดตั้งเดิมหยุดทำงาน

บทเรียนสุดท้าย: เส้นทางสู่ระบบที่ทำงานได้อย่างอิสระ

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

เรียนรู้ 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 ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน

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

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

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

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

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

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