Olet rakentanut MCP-palvelimen ja työkalut toimivat. Yhdistät LLM-agentin ja huomaat sen sivuuttavan työkaluja, kutsuvan niitä oudoilla parametreilla, sekoittavan sopivat työkalut ja ketjuttavan niitä kummallisesti.
Tämä on ero olemassa olevien työkalujen ja LLM:n oikein käyttämien työkalujen välillä. Siihen tuhlautuu suuri osa MCP-palvelimiin tehdystä työstä. Yritykset rakentavat tehokkaita kyvykkyyksiä, tarjoavat ne työkaluina ja näkevät LLM:ien käyttävän niitä tehottomasti.
Hyödyllinen näkökulma on käsitellä työkalusuunnittelua UX-suunnitteluna, jossa LLM on käyttäjä. Työkalukuvaus on käyttöliittymä, skeema lomake ja virheilmoitukset palaute. Kun ne ovat kunnossa, LLM toimii tehokkaasti. Muuten kehittynyt taustajärjestelmäsi jää agentille näkymättömäksi. Anthropicin ohje työkalujen kirjoittamisesta agenteille tekee tuotantoarviointien perusteella saman johtopäätöksen: pienet tarkennukset nimiin, kuvauksiin ja virheilmoituksiin voivat muuttaa agentin toimintaa huomattavasti.
Tämä artikkeli käsittelee periaatteet toimivien ja toimimattomien ratkaisujen konkreettisilla esimerkeillä.
Periaate 1: työkalun nimi välittää tarkoituksen
Työkalun nimi on ensimmäinen asia, jonka LLM näkee. Sen pitäisi kuvata toimintaverbillä, mitä työkalu tekee.
Huono:
customers(substantiivi, ei toimintoa)process_customer(epämääräinen)do_x(merkityksetön)
Parempi:
search_customers(selkeä toiminto)get_customer_by_id(täsmällinen toiminto)update_customer_email(täsmällinen muutos)
Miksi tällä on merkitystä: LLM etsii työkaluluettelosta olennaista työkalua. Kuvaava nimi auttaa löytämään sen nopeasti. Epämääräinen nimi pakottaa lukemaan kuvauksen tarkasti, mitä malli ei aina tee.
Hyödyllinen malli on käyttää vakiintuneita verbietuliitteitä.
list_*,search_*jaget_*lukemiseen.create_*,update_*jadelete_*kirjoittamiseen.analyze_*jasummarize_*laskentaan.
Palvelimen yhdenmukaisuus auttaa mallia valitsemaan työkalut luotettavammin.
Periaate 2: kuvaukset ovat kehotteita
Työkalukuvaus on palvelimen tärkein teksti. MCP-määrittelyssä työkalu määritellään pääosin nimellä, kuvauksella ja syötteiden JSON-skeemalla. Kuvauksen avulla LLM päättää, käytetäänkö työkalua ja miten.
Huono kuvaus:
search_customers: Hae asiakastietokannasta.
Parempi kuvaus:
search_customers: Etsi asiakkaita nimen, sähköpostiosoitteen tai yrityksen perusteella. Palauttaa enintään 10 osuvaa asiakasta perustietoineen. Käytä tätä, kun sinun täytyy tunnistaa asiakas, johon käyttäjä viittaa. Käytä tarkkoihin tunnistehakuihin sen sijaan get_customer_by_id-työkalua.
Parempi versio:
- Kuvaa syötteet eli nimen, sähköpostin tai yrityksen.
- Kuvaa tuotoksen eli enintään 10 osuvaa asiakasta perustietoineen.
- Kertoo käyttötilanteen eli käyttäjän tarkoittaman asiakkaan tunnistamisen.
- Kertoo, milloin sitä ei käytetä, vaan valitaan tarkkaan tunnistehakuun get_customer_by_id.
”Milloin ei käytetä” on kriittinen tieto. Muuten LLM saattaa valita search_customers-työkalun, vaikka get_customer_by_id sopisi paremmin.
Periaate 3: parametrikuvauksilla on merkitystä
Jokainen parametri tarvitsee kuvauksen. Pelkkä nimi ei riitä.
Huono:
{
customer_id: string,
fields: string[]
}
Parempi:
{
customer_id: string, // "The customer's unique identifier. Get this from search_customers or from explicit user input."
fields: string[] // "Specific fields to return. Available: name, email, phone, tier, created_at, last_active. If not specified, returns name and email."
}
Kuvaukset:
- Kertovat LLM:lle, miten arvo hankitaan.
- Määrittävät tarvittaessa sallitut arvot.
- Ilmoittavat oletusarvot.
Periaate 4: virheet ohjaavat palautumista
Virheilmoitus ohjaa LLM:n seuraavaa toimintoa. Epämääräiset virheet johtavat agentin sekaannukseen.
Huono virhe:
{ "error": "Virheellinen syöte" }
Parempi virhe:
{
"error": "validation_error",
"message": "Sähköpostiosoite '...' ei ole kelvollisessa muodossa. Sen on oltava muotoa 'name@example.com'.",
"field": "email",
"suggestion": "Pyydä käyttäjältä kelvollinen sähköpostiosoite."
}
LLM tietää nyt:
- Mikä epäonnistui eli sähköpostikentän validointi.
- Miten se korjataan eli käyttämällä kelvollista sähköpostimuotoa.
- Mitä tehdään seuraavaksi eli pyydetään käyttäjältä kelvollinen osoite.
Ensimmäisen virheen jälkeen agentti voi toistaa saman kutsun, luovuttaa tai keksiä kelvollisen syötteen. Toinen johtaa hallittuun käyttäjävuorovaikutukseen.
Periaate 5: tuotos ohjaa seuraavaa toimintoa
Työkalun tuotos määrittää LLM:n seuraavan toiminnon. Tuotossuunnittelu vaikuttaa agentin toimintaan.
Huono hakutuotos:
[
{"id": "c1", "n": "John", "e": "john@..."},
{"id": "c2", "n": "Jane", "e": "jane@..."}
]
Parempi tuotos:
{
"customers": [
{"id": "c1", "name": "John Smith", "email": "john@example.com", "tier": "pro"},
{"id": "c2", "name": "Jane Doe", "email": "jane@example.com", "tier": "free"}
],
"total_found": 2,
"summary": "Found 2 customers matching 'john'. Note that one is named 'Jane Doe' but has 'john' in their email."
}
Parempi tuotos:
- Käyttää luettavia kenttänimiä.
- Sisältää metakontekstin (
total_found). - Sisältää luonnollisen kielen
summary-kentän, joka auttaa LLM:ää muotoilemaan seuraavan vastauksen.
Yhteenvetokenttä antaa LLM:lle lisävihjeen tuloksen tulkinnasta.
Periaate 6: yksi työkalu, yksi asia
Useita asioita tekevät työkalut hämmentävät LLM:ää. Sen täytyy päättää sekä työkalun käytöstä että toimintatilasta.
Hämmentävä:
manage_customer:
- mode: "search" | "get" | "update" | "delete"
- params: riippuu mode-arvosta
LLM valitsee usein väärän tilan. Myös parametriskeema monimutkaistuu, koska se vaihtelee tilan mukaan.
Parempi: erilliset työkalut.
search_customers: hae nimen/sähköpostiosoitteen/yrityksen perusteella
get_customer: hae tiedot tunnisteella
update_customer: päivitä tietyt kentät
delete_customer: arkistoi asiakas
Jokainen työkalu on yksiselitteinen ja skeema yksinkertainen. LLM valitsee tarkoitukseen sopivan työkalun.
Työkaluja tulee enemmän, mutta kunkin sopimus on selkeämpi. Älä oleta kymmenen rajatun työkalun voittavan kolme monitoimityökalua jokaisella mallilla. Rakenna valinta-arviointi, jossa on epäselviä, epäolennaisia ja vihamielisiä pyyntöjä, ja valitse tarkkuustaso, jolla seurauksellisten virheiden määrä on pienin.
Periaate 7: rajoita syötteitä
Rajaa syötevaihtoehdot mahdollisuuksien mukaan. Enum-arvot ja validointi ehkäisevät hallusinaatioita.
Väljä:
{
status: string // could be anything
}
Rajoitettu:
{
status: "active" | "trial" | "churned" | "suspended"
}
Skeematason rajoite toteutuu, kun valittu palveluntarjoaja ja malli tukevat tiukkoja tai kielioppirajoitettuja työkalusyötteitä. Muussa tapauksessa skeema dokumentoi sopimuksen, mutta isännän on hylättävä virheelliset arvot ja palautettava rakenteinen virhe. Tiukkakin dekoodaus validoi muodon, ei tosiasiaperustaa tai valtuutusta.
Sama koskee toimintojen, vakavuuksien, tyyppien ja muiden tunnettujen arvojoukkojen enum-arvoja.
Käytä päivämäärille ISO 8601 -muotoa ja ilmoita se kuvauksessa (”Päivämäärä ISO 8601 -muodossa, esimerkiksi 2026-05-15”). Muuten LLM tuottaa satunnaisia muotoja.
Periaate 8: oletusarvot vähentävät hallusinaatioita
Tee järkevällä oletusarvolla varustetuista parametreista valinnaisia ja sovella oletus palvelimella.
Huono:
{
query: string,
limit: number, // LLM has to provide some value
include_archived: boolean,
sort_by: string
}
LLM joutuu valitsemaan kaikki arvot ja voi valita väärin.
Parempi:
{
query: string,
limit: number = 10, // sensible default
include_archived: boolean = false, // safe default
sort_by: "relevance" | "name" | "created_at" = "relevance" // most common
}
LLM määrittää vain kyselyn kannalta merkitykselliset parametrit. Vähemmän parametreja jättää vähemmän tilaa sekaannukselle.
Dokumentoi oletukset: ”Limit: palautettavien tulosten määrä. Oletus 10, enintään 50.”
Periaate 9: yhdisteltävyydellä on merkitystä
Työkalujen pitäisi yhdistyä työnkuluiksi, joita LLM voi rakentaa. Oikea tarkkuustaso helpottaa monimutkaisia tehtäviä.
Esimerkkitehtävä: ”Kerro 3 arvokkaimman asiakkaamme kaikista avoimista ongelmista.”
Huono työkalujoukko:
get_customer_summary(customer_id): palauttaa asiakkaan, tukipyynnöt ja aktiivisuuden yhdellä kertaa
Työkalu palauttaa yhden asiakkaan kaiken tiedon, joten ”top 3” -suodatus ei onnistu helposti. LLM:n pitää ensin tunnistaa tärkeimmät asiakkaat ja kutsua työkalua 3 kertaa.
Parempi työkalujoukko:
list_customers(sort_by="value", limit=N): palauttaa asiakastiivistelmät prioriteettitietoineen
list_tickets(customer_id, status): palauttaa asiakkaan tukipyynnöt
LLM voi listata tärkeimmät asiakkaat ja sitten kunkin avoimet tukipyynnöt. Yhdistelmä on luonteva.
Ajattele usean työkalun työnkulkuja. Hyvin yhdistyviä työkaluja käytetään; huonosti yhdistyviä ei usein käytetä.
Periaate 10: idempotenssista viestitään
Mainitse kirjoitustyökalun kuvauksessa idempotenssivaatimukset:
create_invoice: Luo asiakkaalle uusi lasku.
TÄRKEÄÄ: Anna mukaan idempotency_key (itse luomasi UUID). Jos yrität toimintoa uudelleen, käytä samaa UUID:ta, jotta laskuja ei synny kahteen kertaan.
Parametrit:
- amount: ...
- customer_id: ...
- idempotency_key: UUID, joka estää kaksoiskappaleen luonnin uudelleenyrityksessä. Luo yksi kutakin loogista toimintoa kohti.
LLM tietää luoda UUID:n ja käyttää samaa uudelleenyrityksessä.
Ilman ohjetta se voi jättää avaimen pois tai luoda jokaiseen yritykseen uuden UUID:n, mikä kumoaa tarkoituksen.
Periaate 11: mainitse esi- ja jälkiehdot
Kerro työkalun ennakkoehdoista ja merkittävistä sivuvaikutuksista:
delete_customer: Arkistoi asiakastietue. Toiminnon voi peruuttaa 30 päivän kuluessa; sen jälkeen tiedot poistetaan pysyvästi.
ESIEHDOT:
- Asiakkaalla ei saa olla voimassa olevia tilauksia.
- Asiakkaalla ei saa olla avoimia tukipyyntöjä.
Jos esiehdot eivät täyty, työkalu palauttaa virheen, joka kertoo, mikä on ratkaistava ensin.
SIVUVAIKUTUKSET:
- Myös kaikki asiakkaan yhteyshenkilöt arkistoidaan.
- Asiakas poistetaan aktiivisista raporteista.
- Auditlokiin kirjataan merkintä.
LLM tietää, mitä tarkistaa ennen kutsua ja mitä odottaa sen jälkeen. Se voi suunnitella monivaiheisen työnkulun oikein, esimerkiksi sulkea ensin tukipyynnöt ja poistaa vasta sitten.
Periaate 12: käytä epäselvissä tapauksissa esimerkkejä
Monimutkaisen työkalun kuvaukseen lisätty esimerkki auttaa:
analyze_funnel: Analysoi konversiosuppilo tapahtumadatasta.
Parametrit:
- start_date: ISO 8601 -päivämäärä
- end_date: ISO 8601 -päivämäärä
- steps: taulukko vaihemäärittelyjä, kukin muotoa {event_name: string, filters?: object}
Esimerkki:
{
"start_date": "2026-01-01",
"end_date": "2026-01-31",
"steps": [
{"event_name": "signup"},
{"event_name": "first_login"},
{"event_name": "first_action", "filters": {"action_type": "create_project"}},
{"event_name": "subscription_started"}
]
}
Esimerkit opettavat LLM:lle rakenteen skeemaa tehokkaammin.
Periaate 13: älä paljasta sisäistä toteutusta
LLM:n ei tarvitse tuntea tietokantarakennetta tai sisäisiä tunnisteita. Tarjoa selkeä käsitemalli.
Huono:
get_user_by_pk(pk: number)
LLM:n pitäisi tuntea tietokannan pääavaimen käsite.
Parempi:
get_user(user_id: string)
Piilota tietokantakäsite. LLM käyttää merkityksellistä user_id-tunnistetta.
Älä tarjoa vanhentuneita kenttiä, sisäisiä lippuja, virheenselvitysparametreja tai muita toteutukseen käyttäjäkäsitteen sijaan liittyviä asioita.
Periaate 14: vältä maagisia merkkijonoja
Komentojen tai koodien kaltaiset merkkijonot ovat virhealttiita.
Huono:
modify_record(record_id: string, change_string: string)
// jossa change_string on muotoa "field1=value1;field2=value2"
LLM joutuu koodaamaan muutokset tiettyyn merkkijonomuotoon ja tekee virheitä.
Parempi:
update_record(record_id: string, updates: { field1?: any; field2?: any; ... })
Objektina annettavissa rakenteisissa päivityksissä LLM voi käyttää kenttiä suoraan.
Periaate 15: testaa todellisilla LLM-malleilla
Ihmisen mielestä selkeä työkalukuvaus voi hämmentää LLM:ää. Vain testaamalla saat tietää.
Hyödyllinen työnkulku:
- Rakenna työkalu.
- Anna LLM-agentin yrittää useita realistisia tehtäviä vain työkaluillasi.
- Tarkkaile epäonnistumisia.
- Muokkaa kuvauksia havaintojen perusteella.
- Toista.
Havaittavia malleja:
- LLM käyttää väärää työkalua → nimi tai kuvaus on epäselvä.
- LLM antaa vääriä parametriarvoja → parametrikuvaus tai skeema kaipaa korjausta.
- LLM luovuttaa virheen jälkeen → virheilmoitusta pitää parantaa.
- LLM ei kokeile hyödyllistä työkalua → työkalun esilletuonti tai nimi on huono.
Jokainen ongelma viittaa täsmälliseen korjaukseen.
Diagnostiikka: huonosti suunniteltujen työkalujen merkit
Seuraavat mallit kertovat suunnitteluongelmista:
LLM käyttää usein väärää työkalua. Se kutsuu search_customers, vaikka oikea olisi get_customer_by_id. Korjaus: selvennä työkalujen käyttötilanteet.
LLM kutsuu monta työkalua yhtä asiaa varten. Se käyttää 5 kutsua asiaan, jonka pitäisi vaatia 1. Korjaus: harkitse korkeamman tason yhdistelmätyökalua tai karkeampaa tarkkuustasoa.
LLM luovuttaa virheen jälkeen. Se yrittää kerran ja kertoo käyttäjälle, ettei voi auttaa. Korjaus: lisää seuraavaa vaihetta ehdottava virheilmoitus.
LLM hallusinoi parametriarvoja. Se keksii user_id-tunnisteita, päivämääriä tai muita tunnisteita. Korjaus: kerro arvojen hankintatapa, lisää rajoitteita sekä havaitseva ja selittävä virheenkäsittely.
LLM toistaa saman epäonnistuneen kutsun. Sama virhe toistuu. Korjaus: kerro virheilmoituksessa täsmällisesti, mikä on väärin.
LLM ei käytä tehokasta työkalua. Erinomaista työkalua ei koskaan kutsuta. Korjaus: paranna löydettävyyttä selkeällä nimellä, kuvauksella ja ”käytä tätä, kun…” -ohjeella.
Työkalutaksonomia
Hyödyllinen harjoitus on järjestää työkalut taksonomiaan.
Lukutyökalut (turvallisia, idempotentteja):
- search_customers
- get_customer_by_id
- list_tickets
- list_orders
Laskentatyökalut (ei tilamuutoksia):
- summarize_account_activity
- analyze_funnel
- calculate_lifetime_value
Kirjoitustyökalut (tilamuutoksia, edellyttävät idempotenssia):
- create_customer
- update_customer_email
- create_ticket
- send_email
Tuhoavat työkalut (edellyttävät huolellista valtuutusta):
- delete_customer
- cancel_subscription
- archive_record
Taksonomia auttaa:
- Soveltamaan oikeita suojauksia, kuten idempotenssia ja tuhoavien toimien vahvistusta.
- Dokumentoimaan luokat LLM:n järjestelmäkehotteessa.
- Havaitsemaan puuttuvat työkalut.
Hyödyllinen lisä järjestelmäkehotteeseen:
Käytettävissä olevat työkaluluokat:
- READ-työkalut (turvallisia kutsua): search_customers, get_customer_by_id, ...
- COMPUTE-työkalut (ei sivuvaikutuksia): summarize_account_activity, ...
- WRITE-työkalut (sivuvaikutuksia, sisällytä idempotency_key): create_customer, ...
- DESTRUCTIVE-työkalut (edellyttävät ihmisen vahvistuksen): delete_customer, ...
Vahvista käyttäjältä ennen kuin kutsut WRITE- tai DESTRUCTIVE-työkalua.
Tämä ohjaa LLM:n työkalukäyttöä koko työnkulun tasolla, ei vain yksittäisissä kutsuissa.
Esimerkkejä tavallisista parannuksista
Ennen- ja jälkeen-esimerkit konkretisoivat periaatteet:
Esimerkki 1: hakutyökalu
Ennen:
// search documents
{
name: "documents",
description: "Search documents",
inputSchema: { query: "string" }
}
Jälkeen:
{
name: "search_documents",
description: `Search internal documents (knowledge base, wiki pages, policies).
Returns matching documents with title, excerpt, and link. Use when the user asks about company policies, procedures, or internal documentation. Returns up to 10 most relevant matches by semantic similarity.`,
inputSchema: {
query: {
type: "string",
description: "Search query. Be specific. Good: 'remote work policy 2026'. Bad: 'documents about work'."
},
document_type: {
type: "string",
enum: ["policy", "procedure", "guide", "faq", "any"],
default: "any",
description: "Filter to a specific type of document."
},
limit: {
type: "number",
default: 5,
maximum: 10,
description: "Number of results."
}
}
}
Esimerkki 2: toimintotyökalu
Ennen:
{
name: "send_email",
description: "Send an email",
inputSchema: {
to: "string",
subject: "string",
body: "string"
}
}
Jälkeen:
{
name: "draft_email_to_customer",
description: `Draft an email to a customer based on a recent interaction. The email is saved as a draft for human review before sending — it is NOT sent automatically. The user must approve drafts in their inbox.
Use when:
- You've identified an action requiring follow-up with the customer.
- You have a specific reason and content for the email.
Do NOT use:
- To send marketing or promotional content.
- Without explicit user request.
- To respond to refund or cancellation requests (escalate to human instead).`,
inputSchema: {
customer_id: {
type: "string",
description: "Customer ID from search_customers or get_customer."
},
subject: {
type: "string",
description: "Email subject, 4-8 words, specific. Avoid generic subjects like 'Following up'."
},
body: {
type: "string",
description: "Email body, plain text. 3-5 sentences. Personal, specific, not template-y."
},
tone: {
type: "string",
enum: ["professional", "friendly", "apologetic", "urgent"],
default: "professional",
description: "Tone of the email."
},
idempotency_key: {
type: "string",
description: "UUID for this draft. Use the same UUID if retrying to avoid duplicates."
}
}
}
Jälkeen-versiot ohjaavat LLM:ää paljon tehokkaammin. Ne vaikuttavat monisanaisilta mutta ovat sen arvoisia.
Suunnittele malli käyttäjänä
LLM-työkalujen suunnittelu on oma tieteenalansa. Käsittele mallia käyttäjänä ja suunnittele käyttöliittymä sen mukaisesti.
Olennaiset mallit:
- Toimintaverbeihin perustuvat nimet.
- Monipuoliset kuvaukset siitä, mitä, milloin ja milloin ei.
- Parametrikohtaiset kuvaukset esimerkkeineen ja rajoitteineen.
- Rakenteiset, toimintakelpoiset virheilmoitukset.
- Seuraavaa toimintoa ohjaavat tuotokset.
- Yksi käsite työkalua kohti.
- Järkevät oletusarvot.
- Yhdisteltävä tarkkuustaso.
- Selkeästi kuvattu idempotenssi.
- Dokumentoidut esi- ja jälkiehdot.
- Esimerkit monimutkaisille työkaluille.
- Piilotettu sisäinen toteutus.
- Testaus todellisilla LLM-malleilla.
Useimmat MCP-palvelimet eivät epäonnistu vaikean protokollan vaan mallien valinta- ja kutsutapaa sivuuttavan työkalusuunnittelun vuoksi. Oikein suunniteltu palvelin on käyttökelpoinen. Väärin suunnitellussa taustajärjestelmä jää käyttämättä.



