AI-agenten · Les

Een marketplace voor agentplugins bouwen

Gecentraliseerde toolstore: agentplugins publiceren, beoordelen en verspreiden.

Les 4 van 413 stappen

Een marketplace voor agentplugins bouwen is een gratis AI-agenten-les op CoddyKit. Dit is les 4 van 4. Je kunt de volledige les hieronder gratis lezen en daarna in de browser praktisch oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject AI-agenten. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus AI-agenten bevat in totaal 4 lessen.

Wat is een marktplaats voor agent-plug-ins?

Een marktplaats voor plug-ins is een centraal register waar ontwikkelaars deelbare hulpmiddelen publiceren, andere ontwikkelaars ze via zoekopdrachten ontdekken en agentsystemen ze automatisch installeren. Zie het als npm voor hulpmiddelen van agents: één keer publiceren, overal gebruiken.

Architectuur van de marktplaats

De marktplaats heeft vier belangrijke diensten: Register (slaat metagegevens van plug-ins op in een database), Opslag (slaat plug-inarchieven op in objectopslag), Zoeken (index voor volledige tekst) en Beveiliging (ondertekent en verifieert pakketten). Alles wordt beschikbaar gesteld via een REST API.

# 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}')

Een plug-in publiceren

Het publicatie-eindpunt valideert het plug-inarchief, controleert het manifest, verifieert de identiteit van de uitgever (via een API-sleutel), scant op bekende schadelijke patronen, ondertekent het pakket en slaat het op. Publiceren gebeurt atomair: óf de volledige bestandsoverdracht slaagt, óf er wordt niets opgeslagen.

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()

Validatie aan de serverzijde bij publicatie

De registerserver valideert elke inzending: het manifest is parseerbaar en volledig, de versie bestaat nog niet, het archief overschrijdt de maximale grootte niet en een eenvoudige beveiligingsscan slaagt. Pas nadat alle controles zijn geslaagd, accepteert de server de bestandsoverdracht.

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))

Ondertekening en verificatie van pakketten

Onderteken elk gepubliceerd pakket met de sleutel van de uitgever. Clients verifiëren de handtekening vóór de installatie om te controleren of er tijdens de overdracht of in de opslag niet met het pakket is geknoeid.

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)}')

Plug-ins zoeken

De zoek-API accepteert vrije-tekstzoekopdrachten en labelfilters. De API retourneert gerangschikte resultaten op basis van een gewogen score: een exacte overeenkomst met de naam staat bovenaan, gevolgd door overeenkomsten met labels en daarna overeenkomsten met trefwoorden uit de beschrijving.

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)}')

Een plug-in installeren

Het installatieproces bestaat uit: het archief downloaden, de handtekening verifiëren, uitpakken naar de map met plug-ins, het manifest valideren, afhankelijkheden controleren en registreren bij het lokale register van hulpmiddelen. Alle stappen moeten slagen, anders wordt de installatie teruggedraaid.

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

Beoordelings- en recensiesysteem

Een beoordelingssysteem helpt ontwikkelaars om plug-ins van hoge kwaliteit te kiezen. Implementeer beoordelingen van 1 tot en met 5 sterren met optionele tekstrecensies. Geaggregeerde beoordelingsgegevens (gemiddelde, aantal) worden in het register opgeslagen en in zoekresultaten geretourneerd.

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')

Een versie intrekken (uitfaseren)

Als een gepubliceerde versie een kritieke fout of beveiligingskwetsbaarheid bevat, kun je deze intrekken: markeer de versie als verborgen in het register, zodat nieuwe installaties deze niet kunnen gebruiken, terwijl bestaande installaties blijven werken. Dit is veiliger dan verwijderen, omdat je daarmee bestaande agents zou laten vastlopen.

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-hulpmiddel voor de marktplaats

Een opdrachtregelinterface maakt de marktplaats eenvoudig te gebruiken vanuit de terminal of CI-pijplijnen. Implementeer de opdrachten marketplace install, marketplace search, marketplace publish en 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)

Beleid en beheer van de marktplaats

Een openbare marktplaats heeft beheerregels nodig: naamruimten (om naamkaping te voorkomen), inhoudsmoderatie (geen schadelijke code), beveiligingsscans (statische analyse tijdens het uploaden) en een verwijderingsprocedure (bij juridische of beveiligingsincidenten). Dit zijn zowel organisatorische als technische aandachtspunten.

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}')

Kennistoets

Wat is het verschil tussen het intrekken van een plug-inversie en het verwijderen ervan?

Samenvatting: een marktplaats voor agent-plug-ins bouwen

Gefeliciteerd met het voltooien van deze les! De belangrijkste punten:

  • Publicatiepijplijn: archief valideren → handtekening verifiëren → scannen → opslaan en indexeren
  • Pakketten ondertekenen: een HMAC-handtekening waarborgt de integriteit; clients verifiëren deze vóór de installatie
  • Zoeken: zoeken in volledige tekst met labelfiltering en rangschikking op relevantie
  • Installeren: downloaden → verifiëren → uitpakken → valideren → registreren (terugdraaien bij een fout)
  • Beoordelingen: 1 tot en met 5 sterren en tekstrecensies, samengevoegd in het register
  • Intrekken: verbergen voor nieuwe installaties zonder bestaande installaties te verstoren

Laatste cursusonderdeel: de weg naar autonome systemen.

Gratis beginnen

Leer AI-agenten met een AI-tutor — gratis

Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.

Cursussen
60
Lessen
239

Veelgestelde vragen

Is de les “Een marketplace voor agentplugins bouwen” gratis?

Ja — de volledige tekst van “Een marketplace voor agentplugins bouwen” kun je hier gratis op het web lezen. Als je interactief wilt oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is, en de rest van de cursus AI-agenten wilt ontgrendelen, kun je upgraden naar CoddyKit PRO. De cursus AI-agenten bevat in totaal 4 lessen.

Wat leer ik in “Een marketplace voor agentplugins bouwen”?

Gecentraliseerde toolstore: agentplugins publiceren, beoordelen en verspreiden. Je oefent met AI-agenten door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.

Heb ik ervaring nodig om met AI-agenten te beginnen?

Ervaring vooraf is niet nodig. AI-agenten op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 4 van 4.

Hoe lang duurt de les “Een marketplace voor agentplugins bouwen”?

De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.

Kan ik code schrijven en uitvoeren in deze les over AI-agenten?

Ja. Elke les over AI-agenten bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.

Alle lessen in deze cursus

  1. Deelbare agenttools ontwerpen
  2. Plugins ontdekken en registreren
  3. Toolversiebeheer en compatibiliteit
  4. Een marketplace voor agentplugins bouwen
← Terug naar AI-agenten