Адаптаванне паверхносцей інструментаў з эфективным викорыстаннем токенаў для сервераў MCP з агентамі
Выучыце, як спячваць дзесяткі ваклапанняў інструментаў MCP у калькі інструментаў, спрямаваных на адпаведны домэн і маючых чыстае праблематычнае супакоўванне, не адмахваючы ніякой базовай функцыйнасці.
Крыніцы: **From 30 Tools to 3: Designing a Token-Efficient MCP Tool Surface**
Тыповая проблема з сучаснымі системамі-агентамі — не нехватка інструментаў.
Це наявнасць занадта большай колькасці інструментаў.
Калі можлівасці агента расширваюцца, стаўкаецца з’яўляецца практыка підключэння яго да Jira, GitLab, Confluence, Sentry, Elasticsearch, Jaeger, разных баз дадзенаў, панелей монітарынгу, внутрашняых API, пайплайнаў развяртання і безлічы іншых систем.
Кожна з гэтых інтеграцый зазвычай адкрывае довгі список операцый:
Jira
├── searchIssues
├── getIssue
├── createIssue
├── updateIssue
├── addComment
├── transitionIssue
├── getTransitions
├── assignIssue
└── ...
GitLab
├── listProjects
├── getProject
├── listIssues
├── createIssue
├── updateIssue
├── listMergeRequests
├── getMergeRequest
├── createComment
└── ...
Confluence
├── searchPages
├── getPage
├── createPage
├── updatePage
└── ...
Не прыходзіць дуго, як трэба стала берагчы 30, 50 або нават сотні ваказаў інструментаў.
На першы погляд, гэта выглядае як проблема чыстых можлівасцей.
На самай працэ, гэта ўсё-такі проблема колькасці інструментаў.
Агенту не трэба менш можлівасцяў для выканання задач.
Ёму трэба менш верхніх-рэвяў інструментаў, з якіх можна выбраць.
У этым матэрыяле расказваецца пра падход да скарчвання занадта вялікага спектру можнасцей MCP або інструментаў да колькісці інструментаў, спрямаваных на конкрэтны домен, не втрачаючы пры гэму жадных асновных функцыйнасцей.
Центральная ідея простая:
Скарчвайце спектар можнасцей інструмента, а не самы набор можнасцей.
У змену таму, каб адкрываць ўсё такое:
30 MCP tools
можна адкрываць:
3–5 domain tools
і павергацца на поле action, каб внутршняя частка кожнага вызову была направлена правільна.
Так што набор у такім выглядзе:
jira_search
jira_get_issue
jira_create_issue
jira_update_issue
jira_add_comment
jira_transition_issue
...
ператвараецца ў нешто такое:
jira({
action: "search",
...
})
jira({
action: "getIssue",
...
})
jira({
action: "createIssue",
...
})
Бэкенд захоўвае ўсія первісныя можнасці.
Аднак з точкі зору модэлю спектар можнасцей інструмента стае значна меньшым.
1. Проблема вялікага спектру можнасцей інструментаў
Сервер MCP — гэта не проста механізм выконання.
Гэта таксама становіцца часткай таго, што модэль павінна зберагчыць у контексте.
Кожны раз, калі агент падключаецца да сервера MCP, модэль зазвычай павінна обрабоцваць:
- назвы інструментаў
- опісы
- шэмы вхідных дадзеных
- параметры
- канстанты
- обмежэння
- іноды дадатковыя мета-даны
Уявіце сабе агента, які падключены да 40 разных інструментаў.
Нават калі кожны окремы шэма є компактным, ўсьго ў суме гэта можа быць вельмі вялікім об’ёмам дадзеных.
Крэм таго, модэль тепер сталкаецца з большым колам можлівых рашэнняў:
User request
│
▼
Which tool?
│
┌───┼────┬────┬────┬────┐
▼ ▼ ▼ ▼ ▼ ▼
T1 T2 T3 T4 T5 ...
Їй павінна быць можлівасць разлічваць многа операцыяў, якія є концэптуальна суседзькімі.
Возьмім такі прыклад:
jira_search_issues
jira_search_projects
jira_get_issue
jira_get_issue_comments
jira_get_issue_transitions
jira_get_issue_worklogs
Усе гэтыя элементы належаць да аднаго і таго ж концэптуальнага домэна.
Расследжванне кожнага з іх як абсалютна незалежной верхніяй спроможнасці даўае мало корысті.
2. Асновная ідея: мультіплексаванне інструментаў
Секрэт заключаецца у дадзенні сяродньага шару – поля для адзначэння:
{
"action": "search",
"query": "authentication bug"
}
У замяну на ваказанне:
jira_search
вы выклікаеце толькі:
jira
Самы инструмент стае лёгкім маршрутизаторам.
З структурнага точка зору ён выглядае так:
jira
│
action field
│
┌──────────────┼──────────────┐
▼ ▼ ▼
search getIssue createIssue
│ │ │
▼ ▼ ▼
searchHandler issueHandler createHandler
Ключовая ідея заключаецца у тым, што інструмент – гэта не тое ж сама рошчынь, калі і можлівасць.
Інструмент – это проста вухерунскі інтэрфейс.
Поле дзеяння – гэта тое, што насправды несе можлівасць.
Рэзультат:
30 capabilities
↓
3 domain-oriented tools
без якіх-леба втраты функцыйнальнасці.
3. Ожывайце межы домэна, а не будзь-якое групаванне
Паўзловым моментам є такое мышленне:
"У мяне ёсць 30 інструментоў, таму я збіраю 10 операцый у кожны з іх."
Гэта не тое, што трэба.
Групаванне павінна выконвачыцца на адзеўце семантычных домэнаў, а не на прызначаных розмерах груп.
Напрыклад:
jira
├── search
├── issue
├── comment
├── transition
└── project
gitlab
├── project
├── issue
├── mergeRequest
└── pipeline
observability
├── search
├── trace
├── log
└── error
Правильнае групаванне будзе разным залежна ад інтэграцыі.
Для базы дадзенаў, напрыклад:
db_tables
db_query
db_advanced
можа працаваць добра.
Для Jira можна выбраць:
jira_issues
jira_projects
jira_search
Для GitLab падобныя структуры:
gitlab_repository
gitlab_issues
gitlab_mergeRequests
можа падходзіць лепей.
Не існуе фіксаванага числа, якае падходзіць у всіх случаях.
Мэтай є знаходзіць самую маленькую плошчыну інструмента, якая ўсё ж такі саблюдае чыстыя, значымыя семантычныя межы.
4. Прыклад базы дадзенаў
Канектар да базы дадзенаў ёсць хорашым прыкладам, адтолькі калі API базы дадзенаў зазвычай адкрываюць дужо длігі список окремых операцый.
Уместа таго, каб задаваць окремыя элементы, напрыклад:
listTables
getTableSchema
getSampleData
getTableSize
executeQuery
getDatabaseInfo
listRelationships
getIndexes
profileColumn
searchSchema
listProcedures
getTriggers
compareSchemas
можна ўзяць іх усе разам:
db_tables
db_query
db_advanced
Першы з эых адзінакоў можа спакоювацца на такой схеме:
const tablesSchema = z.discriminatedUnion("action", [
z.object({
action: z.literal("list"),
schema: schemaField,
}),
z.object({
action: z.literal("schema"),
tableName: z.string(),
schema: schemaField,
}),
z.object({
action: z.literal("sampleData"),
tableName: z.string(),
schema: schemaField,
rowCount: z.number().optional().default(10),
}),
z.object({
action: z.literal("size"),
tableName: z.string(),
schema: schemaField,
}),
]);
З точкі зору модэлю існуе толькі адзіны адзінак:
db_tables
які падтрымвае чыста адзначаная сукупнасць можлівых дзеянняў:
list
schema
sampleData
size
Пад час выканання працэс все равно перадае задачы чатыром разным адпрацоўвальнікам:
switch (args.action) {
case "list":
return handleListTables(args.schema);
case "schema":
return handleGetTableSchema(
args.tableName,
args.schema
);
case "sampleData":
return handleGetSampleData(
args.tableName,
args.schema,
args.rowCount
);
case "size":
return handleGetTableSize(
args.tableName,
args.schema
);
}
Гэта раздзеленне мае значэнне:
З’едынэнне адбываецца на роўні інтэрфейсу MCP, а не ўнутры базовай бізнес-логікі.
Кожны внутршній адпрацоўвальнік застаецца незалежным для тэставання і прыемным для адтрымкі.
5. Zod Discriminated Unions — гэта ідеальны выбар
У кодавых базах TypeScript функцыя z.discriminatedUnion() апраносяе чысты спосаб моделювання гэтага шаблону.
Напрыклад:
const querySchema = z.discriminatedUnion("action", [
z.object({
action: z.literal("execute"),
query: z.string(),
params: z.record(z.string()).optional(),
limit: z.number().optional().default(100),
}),
z.object({
action: z.literal("info"),
}),
]);
З таго моменту тип можна вывести безпосередня:
type QueryInput = z.infer<typeof querySchema>;
Этый падчынак дае вам тры практычныя перавагі:
- Адзін інструмент MCP.
- Явна маршрутазацыя на адказе поле.
- Строгая верыфікацыя, якая выканана пад час работы.
Загальныя рысі архітектуры выглядаюць так:
MCP Tool
│
▼
Discriminated Union
│
┌─────┴─────┐
│ action │
└─────┬─────┘
│
┌────────┼────────┐
▼ ▼ ▼
Handler A Handler B Handler C
│ │ │
└────────┼────────┘
▼
Backend
Для модэлі гораздка працаваць з такім падчынкам, чым з дзесяткамі несувязаных інструментоў вышэйшага рангу.
6. Колькість інструментоў — гэта не колькість можацтваў
Гэта, мабыць, найважнейшая ідея ў гэтым падчынку.
Спачатку вы маглі маты:
3 tools
13 actions
Гэта не значыць, што дзесять можацтваў зніклі. Насамперад, у вас є:
3 external interfaces
13 internal capabilities
Корача кажучы:
Tool count ≠ capability count
Гэта разлік становіцься ўсё важлівейшым, калі системы агентаў растуць. Набор інструментоў вялікай організацыі можа выглядаць так:
Jira 20 operations
GitLab 25 operations
Confluence 15 operations
Sentry 8 operations
ELK 10 operations
Jaeger 6 operations
Database 20 operations
гэта можа легкая прынесці больш чым 100 адзінарых операцый. Адкрыць кожную з іх безпосередня для модэлі стварае непатрэбна перадмольную паверхню інструменту. У замене можна адгрупаваць іх у ўтварэнне на кшталт:
jira
gitlab
confluence
sentry
observability
database
заўсёды залічываючы загальную колькасць адпаведных операцый незменнай.
7. Чаму гэта можа зменшыць викорыстоўванне токенаў
Галоўная выгода тут крыецца ў зменшэнні об’ёму метаданых інструменту, якія модэль павінна аналізаваць. У замене на перыяквіст:
Tool 1
Tool 2
Tool 3
Tool 4
...
Tool 30
вы праказваеце:
Tool A
Tool B
Tool C
Гэта можа зменшыць:
- апісанні інструменту
- павтараючыяся метаданы параметраў
- дуплікаваныя семантычныя адказы
- складнасць выбору між інструментамі вышэйшага рангу
- працоўны прастор, займаны апісаннямі інструменту
Пры тым, гэта не павінна спрыймалася як гарантаваная прапорцыйная еконамія. Пераходзячы з:
30 tools → 3 tools
гэта не перакладваецца аўтаматычна на:
90% lower token cost
так какя з’едыненыя схемы самі можу стаць большымі. Болей точны спосаб праставлення гэтага пытання:
Аб’еднаванне калькольных операцый у адны інструмент зазвычай спрабоўвае зменшыць габарыты метаданых, якія агент павінен прачытаць, хоча ступень заўсёды эконаміі токенав або часу адповедзі залежыць ад такіх фактароў, як габарыты з’едыненай схемы, ступень деталізавання апісаў поль, особлівасцяў у обробцы визначэнняў інструментоў з боку прадаўцы модэля, а таксама конкретнаг спосабу, яким фрамворк вашаг агента керуе вызовамі інструментоў.
Этую нюансу варта мець у выйдзе.
8. Аб’еднаванне всього разам не ўсега лепш
Є калібрацыйны факт, які варта выявіць.
Уявіце сабе адны інструмент, які выканаёў 40 разных дзеяння:
enterprise({
action: ...
})
з такімі дзеяннямі, як:
createCustomer
deleteCustomer
searchInvoice
rotateCredentials
deployService
createRepository
getTrace
searchLogs
...
Гэта тэхнічна ўзможная задача.
Але гэта таксама спячвае паслаблены дизайн.
Модель зараз затрымалася на аналізе однаго велікага схематызму.
Вы не расьлівалі первоначальную проблему, вы проста перанеслі яе з:
30 tools
на:
1 giant tool
Лепшы падход — кансалідацыя па направленнях домэнаў.
Напрыклад:
customer
billing
repository
observability
deployment
Пяць інструментоў можа быць правым цілям, а не аднаго.
Гэта ведае да галоўнага прынцыпа:
Зменшыце колькасць інструментоў, але не робіце гэта бездумна.
9. Схематызм служыць часткай інтэрфейсу агента
Калі адзін інструмент падтрымлеяе калькі функцыяй, параметр action становіць важылы элемент.
Слабая версія:
action: z.string()
Удосконаленне:
action: z.enum([
"search",
"get",
"create",
"update"
])
Самы выгодны выбор, калі кожная дзеянне патрабуе адзінаковыя параметры:
z.discriminatedUnion("action", [
searchSchema,
getSchema,
createSchema,
updateSchema,
])
Тут выбрана дзеянне і яе неабяжлівыя аргументы з’ўязаны за дапамогою справжней безпекі типаў.
Напрыклад:
action = "search"
→ query required
action = "get"
→ issueId requiredaction = "create"
→ title + description required
Это значна тэчней, чым адзіны схематы з слабай канкрэтнасцю, заполненыя неабяжлівымі поламі для кожнай можлівай дзеянні.
10. Ускладнення JSON Schema пад MCP
У практыцы існуе дадатковая проблема.
Схематы інструментаў MCP ў канечнасці перакладаюцца у JSON Schema.
Залежна ад таго, які канвертар вы вжываеце, Zod discriminated union можа створыць:
{
"anyOf": [...]
}
альбо:
{
"oneOf": [...]
}
Дзеянні частак паўтары слупчыка схемы MCP прыпускаюць, што корань схемы — это звычайны об’ект.
Гэты прыпуск не завжды справядлівы.
У прынаймней адной рэальнаяй реалізацыі шарг Zod для сумаспраўлення ўнутрь MCP SDK быў створаны на адной з форм об’ектаў і не мог чыста пераклаць дзерыгіраную унію.
Рашэнняя — адключыць крок нормалізацыі для створанага шэмы.
Канцэптуальна, гэта выглядае так:
Zod discriminated union
│
▼
JSON Schema
│
▼
MCP normalization
│
▼
MCP-compatible object schema
Архітэктурны вывад з гэтага ёсць:
Перакроіце шэму, якую вы показваете модэлю, не чынячы змян у строгасці вашага фактычнага верыфікатора.
Ваша первоначальная шэма Zod павінна застацца ўжоўсёды адным істочнікам правды для верыфікацыі.
11. Две разныя шэмы: адна для модэлю, адна для часу выканання
Гэта паказвае на шырэйшую разліку, якую варта чытальна выявіць.
Тут насправды ёсць два адналежнічыя заведамення:
LLM-facing representation
│
▼
Tool selection and argument generation
Runtime representation
│
▼
Validation and execution
Шэма, якая показвается LLM, павінна быць:
- лёгкая да чытання
Схема, якая выкорыстоўваецца пад час адработкі, должна быць:
- строгая
- безпечная
- перадбачальная
- остатння
Этыя два варыянты представлення не павінны абоўсумова збігацца. Упроставаны, спрощаны формат об’екта можа дапамогчы модэлю лёгкая выбраць правыя дзеяння, тады калі асновная схема далей забезпечвае перакананне данных у тле.
Этае правіло можа быць распрастравана на шырэйшыя правіла для систем агентаў:
Настроюйце схемы па таму, як іх чытаюць модэлі, але ніколі не пакладайцеся на схему, якая выкорыстоўваецца модэламі, як на ўжоўтольны захоп.
12. Апісанні маюць большую значымасць пасля з’еднання інструментаў
Калі є 30 адзінаковых інструментаў, кожны з іх можа практыкуваць вузкі, конкрэтны апіс.
За дапамою 3 інструментаў апісанне должна перадаваць весь спектр можлівых дзеянняў.
Напрыклад:
Unified tool for advanced database analysis.
ACTIONS:
relationships
List foreign key relationships.
indexes
Get indexes for a table.
profileColumn
Analyze nullability, cardinality and top values.
searchSchema
Search tables and columns.
listProcedures
List stored procedures.
triggers
Get triggers.
compareSchemas
Compare two table definitions.
Гэта не проста дакументацыя для людзей.
Ёй служыць частка механізму, па якому модель керуе своіма запытамі.
Корыстны спосаб разумець гэта:
Tool name
+
Description
+
Action enum
+
Parameter schema
↓
Agent routing signal
Таму адналічэнне інструментаў должна падштовхнуць вас да напісання болей рэтельных апісанняў, а не меншых.
13. Гэты шаблон не абмежваецца толькі базамі дадзеных
Той самы падход даўа ўсё большыя рэзультаты, калі яго застосаваць у шырэйшай групе інжынерных систем.
Jira
Замест таго, каб адкрываць:
searchIssues
getIssue
createIssue
updateIssue
addComment
transitionIssue
assignIssue
getTransitions
адкрываць:
jira_issues
з наборам дзеянняў на кшталт:
search
get
create
update
comment
transition
assign
GitLab
Замест таго, каб выклікваць наяўнасць окремых інструментаў для рэпозітарыяў, проблем, запросаў аб’еднання і пайплайнаў:
gitlab_repository
gitlab_issues
gitlab_mergeRequests
gitlab_pipelines
Можна з’еднаты іх у адзін пункт входу, пры чым кожны з іх будзе мяць свой саблок дзейснаў.
Confluence / Wiki
У замен на розпыленне операцый у калькольных інструментах:
searchPages
getPage
createPage
updatePage
deletePage
getChildren
З’еднайце іх у адзіны:
wiki
Це рэгулюецца спісам дзейснаў, напрыклад:
search
get
create
update
children
Sentry
Падобная структура працуе і тут:
sentry
Падтрымвана:
searchIssues
getIssue
events
releases
projects
ELK
Тая ж ідея прызначана для пошуку логаў:
logs
З:
search
aggregate
fields
indices
Jaeger
А для распраўляючага трэйсінгу:
tracing
З:
search
getTrace
services
operations
Ніякі з гэтых прыкладаў не залежыць ад конкрэтнага выбору назв. Важнае — глыбокая архітэктурная падход, а не точныя атрыбуты, якія викорыстоўваюцца для кожнай дзеяння.
14. Можна абгорнуць існуючыя серверы MCP заместо таго, каб перабудаваць іх
Адзін з наіболей практычных прыяносцей такога дзеяння — гэта тое, што рэдкасцю патрабуецца пераскладваць інтэграцыю з нуля. Для баго распашчых платформ вялікі чыннік MCP-серверы. Але ў іх стандартным інструментальным интерфейсе часта няма належнага падходу да патрэбаў конкретнага агента.
У замест на тое, каб падключыць агента безпосередна да вялікага набору інструментоў:
Agent
│
├── 20 Jira tools
├── 20 GitLab tools
└── 15 Confluence tools
магчыма вставіць тонкі, спецыяльна створаны шар межу:
Agent
│
Custom MCP Layer
│
┌──────────┼──────────┐
▼ ▼ ▼
Jira GitLab Confluence
│ │ │
existing existing existing
APIs MCP MCP
Этот самастоялы шар выступае як фасад для агента. Ён ўсё бол ценны, калі базовая інтэграцыя функцыйна справная, але выкладвае значна больш дзейства, чым агенту патрэбна для безпосередньага разумеўця.
15. Вывядзанне MCP як шара адаптэра
Гэта ведае да болей загальнай архітектурнай ідеі. Традыцыйныя наладжэнні выглядаюць так:
Agent → MCP → Service
Індывідуальна наладка выглядае так:
Agent
↓
Agent-oriented MCP facade
↓
Service-specific MCP/API
↓
Service
Фасад, які знаходзится межы, можа браты на сябе такія завадзеныя, як:
- кансалідаванне інструментаў
- забезпечэнне пераканальняў прав
- нормалізаванне вхідных дадзеных
- нормалізаванне выхідных дадзеных
- логаванне
- тракарынг
- кашаванне
- обмежэнне частоты запытоў
- застосаванне правіл, спецыфічных для арганізацыі
Па такам падходзе шар MCP перестае быть проста механізамам транспортування і стае практычна шаром інтэрфейсу для агента.
16. Контроль даступу яшчэ залишаецца на рэвэлі дзеяння
Є аспект безпекі, які варта выявіць. Якщо вы з’едынаеце:
jira_create
jira_update
jira_delete
у ўнічны формат запыту, напрыклад:
jira({
action: ...
})
вы не можете проста выдаваць загальнае права, такія як:
permission: jira
І заўважыце, што кожная аперацыя несе роўны рызык. Перакананні ў правах павінны выконваліцца на рэжыме кожнай окремай дзеянні, напрыклад:
jira.search → allowed
jira.get → allowed
jira.create → allowed
jira.update → approval required
jira.delete → denied
Кансалідаваны інструмент — гэта проста спрощэнне на рэжыме інтарфейса; ён ніколі не павінен стаць шляхавай, якая таямна надае шырэйшы доступ, чым планавалося.
17. Логі павінны фіксаваць дзеянне, а не толькі інструмент
Калі інструменты з’едынаюцца, фіксацыя толькі назвы інструмента ў логах становіцца беспрактычной. Слабы запис у логах выглядае так:
tool = jira
Кращы запис включае сама дзеянне:
{
"tool": "jira",
"action": "search",
"duration_ms": 142
}
А ўсё болей деталізаваны запис додае дапаможныя відомасці пра выконанне:
{
"tool": "jira",
"action": "search",
"status": "success",
"duration_ms": 142,
"request_id": "...",
"agent_id": "...",
"user_id": "..."
}
Настоямы елемент выконання тепер — гэта пара:
tool + action
а не толькі інструмент сам по сабе:
tool
Гэта разліка мае вялікое значэнне, калі вы намагаецеся з’ясавіць, што насправды зрабіў агент.
18. Храніце базовыя працоўнікі окрема
Кансалідацыя павинна выконвачвацца на межы, якая є доступной для агента, а не внутрь вашай реалізацыі. Утрымайцеся ад злучэння ўсього ў одного вялікага працоўніка:
async function jira(args) {
// everything
}
У замен перадавайце задачы на аднальныя функцыі:
async function jira(args: JiraInput) {
switch (args.action) {
case "search":
return searchIssues(args);
case "get":
return getIssue(args);
case "create":
return createIssue(args);
case "update":
return updateIssue(args);
}
}
Кожны працоўнік залишаецца незалежным для тэставання:
jira()
│
├── searchIssues()
├── getIssue()
├── createIssue()
└── updateIssue()
Гэта дапамагае падтрымваць ваш кодовы базі, нават калі колькасць зовнішніх інструментаў зменшваецца.
19. Практычная правіла для выбору таго, што злучыць
Хорашая гістэрычная метода для вярнага адпаведання на пытанне, чыры две операцыі належаць да аднаго інструмента, ёсць:
Чы інжынер па свайбе агрупаваў бы гэтыя операцыі пад адной можлівасцю?
Напрыклад, гэтыя операцыі явна належаць разам:
Jira search
Jira get issue
Jira update issue
Але гэтыя не:
Jira update issue
Elasticsearch search logs
Create AWS infrastructure
Іншая корыстная перакантовка:
Чы рэшэнак па гэтыя аперацыі зазвычай выклікае патрэбу ў тых сабе контекстовых даных?
Якщо адказ «так», то злучэнне іх зазвычай є карыстным. Якщо няма, то краща заставіць іх як окалечныя засобы.
20. Калі злучэнне засобаў — глупая ідея
Інодзе заставіць засобы окалечная — гэта проста правильны выбар.
Некалякуюцыя домены
database
payments
infrastructure
email
не трэба прыемліваць у ўзеўрошаны формат на кшталт:
enterprise({
action: ...
})
Злучэнне некалякуючых доменаў у адны дыспэтчар толькі таму, што можна, не робіць інтэрфейс более цяплым.
Наборы дзеянняў, якія занадта великі
Якщо адзін аб’еднаны інструмент будзе включаць пяцдзiesць розных дзеянняў, створаная схема можа стаць занадта масівной і складнаючайся для розумення модэллю, чым будзе паспраўдана неадказнасць аб’еднавання.
Дзеяння з падвышанымі правамі
Дзеяння такія, як:
deleteProductionData
rotateCredentials
deployProduction
можаць патрабаваць своіх сабэйных меж дазволаў, нават калі тэхнічна яны знаходзяцца ў там самым домэне, што і дзеяння з меншым рызыкам.
Дзеяння з разнымі гарантіямі жыцёвага циклу
Вызовы толькі для чытання і разрушальныя вызовы інодзе краща выкананы як адзеленыя інтэрфейсы:
jira_read
jira_write
замест таго, каб яны былі аб’еднаны ў адзін занадта вялікі інструмент.
Як і ранейш, няма фіксаванага формулы — гэта залежыць ад системы.
21. Менш інструментоў — гэта не справжняя мета
Мета не ў тым, каб усё скорачыць да:
30 → 1
Справжняя мета ў тым:
30 → smallest useful semantic surface
У адзінай системе правыя цифры можа выглядаць так:
30 → 3
У іншай:
30 → 7
А ў ўсёй іншай:
30 → 12
Тое, за шта вы на самай працо оптымізаваеце, — гэта:
minimize unnecessary tool metadata
без жадных паслабленняў:
semantic clarity
validation
security
maintainability
22. Форма архітектуры, якая можа быть викорыстаная знову
Масштабавальная структура зазвычай выглядае так:
Agent
│
▼
┌──────────────────┐
│ Agent MCP Layer │
└────────┬─────────┘
│
┌──────────────┼──────────────┐
▼ ▼ ▼
jira gitlab wiki
│ │ │
┌────┼────┐ ┌────┼────┐ ┌────┼────┐
▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼
search get create issues MR pipeline search get update
│ │ │
└──────────────┼──────────────┘
▼
Existing APIs/MCPs
Модель взаімаецца з маленькай, чыстой суперфісом. Пад ёю шар інтэграцыі все ж мае доступ да всіх можлівых операцый.
23. Перэскалкаванне таго, для чаго прагначаецца MCP
Пашыраныя уявленні пра MCP такія:
"Ператварыць кожны вызов API на самастоятельны інструмент."
Гэта хорашы пачатак.
Але для систем, якія працуюць у прымэтным режыме, болей корыстным стае такой пытанне:
Што на самай працо должна бачыць модель?
Этыя два падчыры не завжоды прыводзяць да аднаковага дизайна.
Разглядзім РЕСТ API, які абярне:
GET /issues
GET /issues/:id
POST /issues
PATCH /issues/:id
POST /issues/:id/comments
POST /issues/:id/transition
Нэт такога трэбавання, каб кожны HTTP-маршрут быў перадаў як адна самастоятная засоб для работы з модэлем. Слой MCP можа выступаць як семантычны абгорт навакола гэтых канцэнтраў — прыгожа так, як вы бы дизайнавалі API на адповеднасць патрэбам конкретнага корыстувальніка, а не проста абярнаючы базовую службу чы схему базы дадзеных безпосередня.
24. Рассмотрэнне дизайна засоба як проблемы UX агента
Класычны дизайн API запытае:
Калісць канцэнтры?
Дизайн для агента ставі іншы запит:
Какое рашэнне на самай працы намагаецца прыняць модэль?
Інжынер, які інтэгруе працу з API, можа скорыцца:
getIssue
getIssueComments
getIssueTransitions
getIssueWorklogs
акулькі кожны вызов чыста адпавядае адной операцыі.
З іншай баку, агент можа краща працаваць з:
jira_issue({
action: "get",
...
})
у паре з:
jira_issue({
action: "comments",
...
})
так как спачатку выбіраецца домэн, а пасля — звужваецца выбор да конкрэтнай дзеянні — цэў дваэтапны процес маршрутызацыі:
Domain
↓
Action
↓
Arguments
замест таго, каб прымусіць модэль рашыць:
One large global tool-selection problem
25. Мінімальны шаблон, які можна перысваіць
Гэты падход легка перакладаецца на TypeScript:
const toolSchema = z.discriminatedUnion("action", [
searchSchema,
getSchema,
createSchema,
updateSchema,
]);
server.registerTool(
"jira",
{
description: "...",
inputSchema: toolSchema,
},
async (args) => {
switch (args.action) {
case "search":
return search(args);
case "get":
return get(args);
case "create":
return create(args);
case "update":
return update(args);
}
}
);
Сам код застаецца даскладна простым. Настоямая частка проектавання — у адпаведзеннях на:
- Калія операцыі логічна агрупаваюцца разам?
- Якую схему называння павінны следаваць дзеянні?
- Што павінна быць у описе інструмента?
- Калія параметры ўсё жаданыя для кожнага дзеяння?
- Калія дзеянні патрабуюць дадатковых пераканаў у правах?
- Як павінны быць структураваныя адпаведзі?
- Як павінны быць логаваныя та відстэйваныя кожныя дзеянні?
26. Следзіце за адказамі за дапомогай рэальных цифраў
Адзінаванне інструментаў не павінна быць простаю веры — трэба пераканацца ў цым за дапамогай дадзеных.
Да змяны можна было б запісаць кашто-та такое:
Tools: 32
Tool schema tokens: X
Average tool-selection latency: Y
Tool-selection errors: Z
Пасля введэння мультіплексаванага дизайна зноў фіксуецца тыя ж паказнікі:
Tools: 5
Tool schema tokens: X'
Average tool-selection latency: Y'
Tool-selection errors: Z'
Сярод найболей інформатыўных сігналаў, якія трэба стежыць, ёсць:
- скількі інструментаў є доступныях
- абсалютны розмер схем
- скількі токенаў спрашчанне або контэкст выкарыстоўвае
- насколькі точна агент выбирае правы інструмент
- як часта ён выканае некоректныя вызовы інструментаў
- як часта адбываюцца бракі ў перакананні аргументаў
- вытрэчка на адказ
- як часта выкананні насправды маюць успех
- чы рэалізавае агент загальную задачу
Мета не ў тым, проста старацца:
fewer tools
а ў тым, каб оптымаізаваць:
better agent performance per unit of context
27. Шырэйшы шаблон для API, якія выкарыстоўваюць агенты
Гэя ідея выходзіць за межы самага MCP.
Вы пабачыце, што той жа прынцып ўжываецца для:
- выклікання функцый
- вызначэння інструментаў у стылі OpenAI
- SDK-ў
- спецыяльных средаваў выканання агентаў
- механізмаў работы з потокамі задач
- архітектураў плагінаў
- адаптараў REST да агентаў
- мостоў GraphQL да агентаў
У сваій основе шаблон выглядае так:
Traditional API
↓
Many low-level operations
↓
Agent-oriented facade
↓
Small semantic tool surface
↓
Action routing
↓
Strict execution layer
Гэта не ўскладнены трюк, спецыфічны для баз дадзенаў.
Это загальны шаблон для проектавання інтерфейсаў, якія выкарыстоўваюць агенты.
28. Основны прынцып
Ментальная модель, яку трэба прымець, ёсць простая:
┌──────────────────────┐
│ 30 APIs │
│ capabilities │
└──────────┬───────────┘
│
Consolidation
│
▼
┌──────────────────────┐
│ 3–5 tools │
│ semantic domains │
└──────────┬───────────┘
│
Action routing
│
▼
┌──────────────────────┐
│ 30 handlers │
│ original abilities │
└──────────────────────┘
Значыцьныя змены не ў гэтым:
30 capabilities → 3 capabilities
Усё-такі, змены ў гэтым:
30 exposed tools → 3 exposed interfaces
Нічога не змяніцца ў тым, што можа робіць система.
Змінюецца тое, якую частку гэтай паверхні модэлю трэба аналізаваць безпосередня.
Заключанне
Калі агентныя системы будуць інтеграваны ў большую частку вашай інфраструктуры, колькісць інструментаў, якія ў ўплыве, будзе толькі зростаць.
Системы на кшталт Jira, GitLab, Confluence, Sentry, ELK, Jaeger, разныя базы дадзеных, прадаўцы хмарных сервісаў і внутршнія службы можу кожная ствараць дзесяткі або сотні окремых операцый.
Перадача кожнай з гэтых операцый модэлю як окремага інструмента рэдка калі ёсць правильная архітектура.
Болей эфектыўная стратэгія — стварыць шар інструментаў для агентаў на ўзбочку яных:
Many low-level operations
↓
Semantic domain grouping
↓
Discriminated action schemas
↓
Small MCP tool surface
↓
Strict runtime validation
↓
Original capabilities
Кансэрватыўны правіла ёсць:
Скорачыце колькісць інструментаў, пра якія мусi аналізаваць модэль — а не колькісць можлівасцяў, якія насправды прысутны ў вашай системе.
Інтэграцыя з трыдзцятьма аперацыямі не павінна прыводзіць да наявнасці трыдзцяці інструментоў, видных для модэля.
Можа знадобіцца толькі тры рэштрыкована разрабатаныя інтерфейсы, кожны з якіх мае чытка абмежаную прастор дзейства.
Гэта стае ўсё бол цінным, калі вы перестанете спрыятаць існуючыя серверы MCP як фіксаваныя, недаступныя для змены контракты, а будзеце спрыятаць іх як елементы, якія можна абгорнуць, перакашталетаць і налаштараваць так, каб яны падходзілі таму, чыям праптанню патрэбны ваші агенты.
У будучыні хорашая дизайнарская практыка MCP можа меньш стосавацца адкрыцья кожной аперацыі, яку падтрымвае API, а больш — стварэння самага маленькага, найболей прыдатнага інтерфейсу, які агенту патрэбен, каб выкарыстаць своія функцыі.