LLM-тусовка без зоопарку SDK: як дати моделям спілкуватись між собою
TL;DR
Model Context Protocol (MCP) — це відкритий стандарт, що уніфікує взаємодію мовних моделей із зовнішніми інструментами та даними.
У цій статті ми зберемо міні-шину між кількома моделями (OpenAI, Claude, Gemini, etc) за допомогою Python та бібліотеки ai-microcore, що є vendor-agnostic
Опублікуємо її як MCP-сервер, під’єднаємо клієнт (наприклад, Claude Desktop) і покажемо, як одна LLM може викликати інші як інструменти, порівнювати відповіді та робити «мажоритарне голосування».
Це дає змогу робити дебати моделей, cross‑check, self‑consistency, ансамблі.

Для кого ця стаття
— Інженери, які будують агентів/оркестрації на LLM і хочуть інтероперабельність без vendor‑lock‑in.
— Ті, хто експериментує з комітетами моделей (voting/critique/referee) та шукає практичний рецепт з мінімумом «важких» фреймворків.
— Команди, яким потрібно швидко підміняти моделі (GPT ⇄ Claude ⇄ Gemini ⇄ локальні) без переписування коду.
Чому взагалі MCP?
Класичний підхід: писати інтеграції з кожним вендором окремо й вручну прокидати дані між сервісами. Це боляче для підтримки, важко стандартизувати, і майже неможливо масштабувати в багатоточкові (multi‑tool/multi‑LLM) системи.
MCP уводить універсальний рівень між LLM‑клієнтом і «зовнішнім світом»: сервери MCP оголошують набори інструментів з чіткими JSON‑схемами вводу/виводу, а клієнти (ваш застосунок) реєструють їх через уніфіковану конфігурацію і викликають інструменти за потреби (при рішенні мовної моделі використати їх).
У результаті, один клієнт може працювати з безліччю різних серверів/інструментів без кастомної клейової логіки у самому застосунку.
Хоча, з власного досвіду зазначу — коли справа заходить стосовно тюнінгу production-рішення, високих вимог до якості взаємодії з фіксованим набором інструментів, кастомна пряма інтеграція ймовірно буде кращим рішенням, бо тут ми вже впираємось в обмеження і мінуси самого протоколу MCP, як-то статична природа tool definitions, складності стрімінгу, overhead через неоптимальний транспорт та додатковий рівень проксювання між LLM та цільовим API.
Тож, на мою скромну думку, MCP в першу чергу варто використовувати:
— В ролі extensibility point вашого додатку, а не як основний спосіб взаємодії LLM з функціоналом системи production-рішення
— Для швидкого прототипування та експериментів
Підготовка середовища
Prerequisites
Припускаю, що у вас вже встановлений Python 3.11+, стандартний інсталятор Python також вже містить в собі pip.
Я надалі використовуватиму команди python / pip.
В вашій системі вони можуть називатись python3 / pip3 і можливо вам потрібно буде вказувати повний шлях до них, якщо ви не додали його в змінні оточення вашої OS.
Також вам необхідні API ключі для LLM від Anthropic, Google та OpenAI
(Ви можете використовувати будь-які інші LLM, в тому числі обмежитись моделями від OpenAI, локальними моделями розгорнутими через vllm, lmstudio, ollama, etc, або навіть здійснювати інференс безпосередньо через pytorch, передавши python-функцію інференсу в конфігурацію ai-microcore)
Встановимо необхідні бібліотеки python
Виконайте наступну команду:
pip install ai-microcore anthropic google-generativeai
Note: бібліотеки anthropic та google-generativeai є опціональними, вони необхідні тільки для використання відповідних моделей бібліотекою ai-microcore, і не входять в саму дистрибуцію, адже ai-microcore слідує філософії мінімалізму для запобігання роздування залежностей у фінальному ПЗ.
Налаштуємо API ключі (будь-які доступні вам провайдери)
В принципі ніщо не заважає вам захардкодити ключі прямо в скрипт.
Але ми потренуємо ваше рефлекторне запобігання потраплянню таких речей в репозиторії, щоб уникнути сумної долі автора коміту з секретами, зображеного на ілюстрації нижче.

Тож, якщо ви не маєте цих ключів в змінних оточення OS, просто покладіть їх в .env файл і попросіть вашу систему контролю версій ігнорувати його (додайте ім’я файлу в .gitignore, якщо ви використовуєте git).
А далі, в скрипті MCP сервера ми підвантажимо ці змінні в оточення python за допомогою функції load_dotenv(".env«) з бібліотеки dotenv, що входить в дистрибуцію ai-microcore.
Приклад .env файлу:
OPENAI_API_KEY=<YOUR OPEN_AI API KEY> GOOGLE_API_KEY=<YOUR GOOGLE API KEY> ANTHROPIC_API_KEY=<YOUR ANTHROPIC API KEY> XAI_API_KEY=<YOUR X.AI API KEY (Grok)> DEEPSEEK_API_KEY=<YOUR DEEPSEEK API KEY>
Створимо скрипт MCP сервера
# file: ask_various_llms_mcp_server.py
import os, pathlib, fastmcp, dotenv, microcore as mc
# підвантажимо змінні оточення з директорії, де лежить цей скрипт
# після цього вони будуть доступні для зчитування через os.getenv(var_name: str)
dotenv.load_dotenv(pathlib.Path(__file__).parent / '.env', override=True)
# Оголосимо конфігурації LLM
#
# Ключами є імена моделей так, як ми їх будемо передавати через в MCP
# А значеннями – конфіги LLM-підключень для ai-microcore
# див. https://github.com/Nayjest/ai-microcore?tab=readme-ov-file#%EF%B8%8F-configuring
#
# Note: імена параметрів конфігурації в ai-microcore є case-insensitive,
# хоча IDE autocompletion для функції mc.configure() ймовірно пропонуватиме вам назви в UPPER_CASE
# Ці параметри можуть бути передані до функції конфігурування як словником так і окремими аргументами.
configs = {
"gpt-5": {
"model": "gpt-5",
"api_type": mc.ApiType.OPEN_AI,
"api_key": os.getenv("OPENAI_API_KEY"),
"api_base": "https://api.openai.com/v1",
},
"grok-4": {
"model": "grok-4-latest",
"api_type": mc.ApiType.OPEN_AI,
"api_key": os.getenv("XAI_API_KEY"),
"api_base": "https://api.x.ai/v1",
},
"deepseek-chat": {
"model": "deepseek-chat",
"api_type": mc.ApiType.OPEN_AI,
"api_key": os.getenv("DEEPSEEK_API_KEY"),
"api_base": "https://api.deepseek.com/v1",
},
"gemini-2.5-pro": {
"model": "gemini-2.5-pro",
"api_type": mc.ApiType.GOOGLE_AI_STUDIO,
"api_key": os.getenv("GOOGLE_API_KEY"),
"api_base": "https://generativelanguage.googleapis.com/v1alpha",
},
"claude-opus-4.1": {
"model": "claude-opus-4-1-20250805",
"api_type": mc.ApiType.ANTHROPIC,
"api_key": os.getenv("ANTHROPIC_API_KEY"),
"api_base": "",
},
}
# host і port потрібні, тому що в цьому прикладі ми використаєм
# streamable-http транспорт замість стандартного stdio
# Це дозволяє захостити MCP сервіс на окремому сервері для спільного використання.
# host=0.0.0.0 вказує сервісу реагувати на вхідні підключення з будь-яким іменем хоста, тобто 127.0.0.1 / localhost / etc.
# Номер порту – будь-який зручний для вас, що не конфліктує з інснуючими на цільовому комп’ютері сервісами
mcp = fastmcp.FastMCP("Ask LLMs via MCP", host="0.0.0.0", port=8001)
# Декоратор @mcp.tool робить вашу python-функцію MCP-інструментом, доступним для використання.
# Створимо допоміжний інструмент з іменем models без додаткових параметрів,
# що буде повертати клієнту список підтримуваних MCP сервером моделей
# відповідно до нашої конфігурації
@mcp.tool()
def models() -> list[str]: return list(configs.keys())
# Інструмент "ask” виконує запит query до цільової LLM, заданої параметром “model”
@mcp.tool()
def ask(query: str, model: str) -> str:
mc.configure(configs[model])
return mc.llm(query)
# стартуємо сервер
mcp.run(transport="streamable-http") # альтернативні транспорти: stdio, sse
Запускаємо свіжестворений сервер:
python ask_various_llms_mcp_server.py
Очікуваний результат:

Note: Якщо ви бачите DeprecationWarnings — ця проблема не фатальна, для чистоти виводу я зробив downgrade пакету websockets: pip install -U websockets==13, а в цілому, чекаємо оновлення uvicorn
Підключаємо клієнт (Claude Desktop)
— [ 1 ] Відкрийте Claude Desktop.
— [ 2 ] Зайдіть в меню File → Settings
— [ 3 ] Перейдіть в розділ «Developer» у сайдбарі зліва
— [ 4 ] Натисніть кропку «Edit Config» під заголовком «Local MCP Servers»
Це створить новий файл конфігурації (якщо він відсутній), або відкриє існуючий в навігаторі вашої OS.
Шлях до файлу:
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
— [ 5 ] Внесіть конфігурацію нашого MCP Сервера в claude_desktop_config.json:
{
"mcpServers": {
"ask-various-llms": {
"command": "npx",
"args": ["-y", "mcp-remote", "http://127.0.0.1:8001/mcp/"]
}
}
}
(Можливо вам також знадобиться встановити nodejs / npx, якщо він відсутній у вашій системі)
Збережіть файл.
— [ 6 ] Перезапустіть Claude Desktop
Note: вам потрібен саме повний перезапуск Claude Desktop, для цього скористайтесь елементом контекстного меню «Quit» іконки Claude в трайбарі.
— [ 7 ] Якщо всі кроки було виконано успішно, у вікні нового чату ви побачите іконку зі слайдерами, що викликає меню, де ви зможете ввімкнути свіжедоданий MCP сервер для поточного діалогу:

Тестуємо наш MCP сервер через Claude Desktop
Тестове запитання 1

claude.ai/...69-4870-b8ce-472f7ce9e6b3
Тестове запитання 2

Як бачите, наш MCP-сервер може бути досить зручним для міні-тестів, досліджень роботи різних мовних моделей, чи простої реалізації ансамблів з консенсусом, дозволяючи не пітонити зайве☝️.
Використання MCP-сервера за допомогою python-скрипта
import asyncio
import microcore as mc
async def main():
mc.configure(LLM_API_TYPE=mc.ApiType.NONE, MCP_SERVERS=['http://localhost:8001'])
mcp = await mc.mcp.server('localhost:8001').connect()
models = (await mcp.call('models')).parse_json()
print('Models:', models)
for model in models:
response = await mcp.call(
'ask',
query="""
What is your favorite video game character name?
Just give me the name, no explanation or details.""",
model=model,
timeout=300,
)
print(f"Response from {model}: {response}")
if __name__ == "__main__":
asyncio.run(main())
У цьому прикладі ми отримуємо список моделей і опитуємо кожну з них, безпосередньо викликаючи MCP-інструменти.
Якщо ж вам потрібно дати ці інструменти мовній моделі, пропоную до вашої уваги наступні приклади коду:
github.com/...mcp_1shot_github_stars.py
github.com/...xamples/mcp_agent_loop.py
Повний код MCP-сервера та приклади зі статті доступні тут.
Special thanks
Висловлюю подяку за ідею користувачам спільноти AI Talks VLC
Буду радий обговоренню у коментарях!
Немає коментарів
Додати коментар Підписатись на коментаріВідписатись від коментарів