Стек для швидкої розробки AI-агентів: Aspire, Agent Framework, CopilotKit, AG-UI і DevUI

Ще рік тому «зробити агента» означало приблизно таке: написати цикл виклику LLM, приліпити до нього парсинг тул-колів, підняти власний WebSocket, вигадати формат подій для фронтенду, зверху накрутити логування — і після двох тижнів роботи отримати демо, яке падає при першому ж паралельному користувачі.
Зараз ситуація інша. Зʼявився цілком зрозумілий набір інструментів, де кожен закриває свій шар, і вони чесно стикуються між собою. Якщо коротко:
- Aspire — оркеструє всю систему: моделі, сервіси, бази, черги, фронтенд.
- Microsoft Agent Framework — власне мізки агента: інструменти, памʼять, воркфлоу.
- DevUI — «постман для агентів»: подивитися, як агент думає, ще до того, як зʼявився UI.
- AG-UI — протокол, яким агент розмовляє з інтерфейсом.
- CopilotKit — готовий фронтенд, який цей протокол розуміє.
Далі — по одному, з прикладами. Технічних подробиць мінімум, ідея важливіша за синтаксис.
Aspire: спочатку система, потім агент
Головна помилка, яку роблять команди на старті — починають з агента. Пишуть промпт, підключають модель, все працює локально в консолі. А потім виявляється, що агенту потрібен Redis для кешу, Postgres для стану, окремий Python-сервіс для ембедингів, і фронтенд, який має все це знайти. І починається - файл docker-compose.yml на 200 рядків та README з інструкцією «спочатку запусти оце, потім зачекай, потім оце».
Aspire знімає цей біль. Ви описуєте систему кодом — і вона запускається однією командою:
var builder = DistributedApplication.CreateBuilder(args);
var cache = builder.AddRedis("cache");
var db = builder.AddPostgres("db").AddDatabase("agentdb");
var backend = builder.AddProject<Projects.AgentApi>("agent-api")
.WithReference(cache)
.WithReference(db)
.WithExternalHttpEndpoints();
builder.Build().Run();
Ніяких рядків підключення в конфігах — Aspire сам роздає їх сервісам, сам вигадує порти, сам чекає, поки база підніметься.
Для AI-частини є окремі інтеграції. Наприклад, модель у Foundry і агент поруч із нею — інтеграція ставиться командою aspire add azure-ai-foundry (пакет Aspire.Hosting.Foundry, поки в preview):
var foundry = builder.AddFoundry("ai");
var project = foundry.AddProject("project");
var chat = project.AddModelDeployment("chat", FoundryModel.OpenAI.Gpt5Mini);
var supportAgent = builder.AddProject<Projects.SupportAgent>("support-agent")
.WithReference(chat).WaitFor(chat);
А якщо частина системи написана на Python — це теж просто ще один ресурс у тому самому графі:
var weather = builder.AddUvicornApp("weather-agent", "./weather-agent", "main:app")
.WithReference(chat).WaitFor(chat);
Практична цінність тут не в красі коду. Вона в тому, що новий розробник робить git clone, пише aspire run і за хвилину бачить дашборд, де живі всі сервіси, логи й трейси. Не «а що в тебе в .env?», а працююча система.
І ще одна деталь, яка стала актуальною саме у 2026: Aspire навчився дружити з кодовими агентами. У CLI зʼявився режим aspire run --detach (підняти систему у фоні), --isolated (окреме середовище з власними портами, щоб два агенти паралельно не билися за один порт 5432), команди aspire doctor для перевірки оточення і aspire docs для програмного доступу до документації, а aspire new та aspire init тепер кладуть у проєкт MCP-сервер, через який Copilot чи Claude може сам подивитися статус ресурсів і почитати логи замість того, щоб просити у вас скріншот.
До речі, про назву: з тринадцятої версії проєкт офіційно називається просто Aspire, без префікса «.NET» — саме тому, що він давно вміє не тільки в C#. Актуальна гілка на серпень 2026 — 13.4.x.
Тобто Aspire — це не тільки для вас. Це ще й для вашого AI-помічника.
Microsoft Agent Framework: мізки
Про сам фреймворк я вже писав детальніше, тому тут коротко і по суті — що саме прискорює роботу.
Агент створюється в кілька рядків, а інструмент для нього — це звичайна функція:
pip install agent-framework
from agent_framework import Agent
from agent_framework.openai import OpenAIChatClient
from typing import Annotated
from pydantic import Field
def get_order_status(
order_id: Annotated[str, Field(description="Номер замовлення")],
) -> str:
"""Повертає статус замовлення."""
return f"Замовлення {order_id}: у дорозі, доставка завтра."
agent = Agent(
client=OpenAIChatClient(),
name="SupportAgent",
instructions="Ти підтримка інтернет-магазину. Відповідай коротко і по ділу.",
tools=[get_order_status],
)
Ніяких схем JSON вручну — фреймворк читає сигнатуру функції й опис із Annotated. Це та частина, де раніше зникав день роботи.
Другий момент — композиція. Агент може бути інструментом іншого агента:
main_agent = Agent(
client=OpenAIChatClient(),
instructions="Ти головний асистент. Делегуй спеціалістам.",
tools=[support_agent.as_tool(), billing_agent.as_tool()],
)
Це той рідкісний випадок, коли «мультиагентна система» не потребує окремого архітектурного документа.
Третій — воркфлоу. Коли процес має чіткі кроки (перевірити → узгодити → виконати), не треба сподіватися, що LLM сама здогадається про порядок. Ви описуєте граф, а агенти в ньому — просто вузли. З чекпоінтами, паузою на підтвердження людиною і можливістю продовжити з місця зупинки.
Правило вибору просте: відкрита задача — агент, чіткий процес — воркфлоу. І фраза з документації, яку варто памʼятати: якщо задачу можна вирішити звичайною функцією — напишіть функцію, а не агента.
Статус на серпень 2026: версія 1.0 для .NET і Python вийшла у квітні, тобто це вже не експеримент, а продукт із зобовʼязаннями щодо сумісності. Go досі в публічному превʼю.
DevUI: подивитися агенту в очі
Найнеприємніше в розробці агентів — невидимість. Агент відповів дурницю. Чому? Він викликав не той інструмент? Отримав не ті дані? Не зрозумів промпт? У консолі ви бачите тільки фінальний текст.
DevUI розвʼязує це буквально одним рядком:
from agent_framework.devui import serve
serve(entities=[agent], auto_open=True)
Відкривається браузер, у ньому — чат із вашим агентом. Ви пишете запит і бачите не тільки відповідь, а весь ланцюжок: які інструменти викликалися, з якими аргументами, що повернули, скільки часу зайняло, які трейси OpenTelemetry записалися.
Є й варіант без коду взагалі — просто вказати папку з агентами:
pip install agent-framework-devui --pre
devui ./agents --port 8080 --instrumentation
DevUI сам їх знайде і покаже списком. Прапорець --instrumentation вмикає збір трейсів — врахуйте, що в документації на Learn досі фігурує старіша назва --tracing, якої в самому пакеті вже немає. Для .NET DevUI теж зʼявився: пакет Microsoft.Agents.AI.DevUI, поки в preview.
Окремий бонус: під капотом там OpenAI-сумісний API. Тобто ваш агент одразу можна смикати будь-яким клієнтом, який уміє в OpenAI:
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8080/v1", api_key="<токен з логу запуску>")
response = client.responses.create(
metadata={"entity_id": "support_agent"},
input="Де моє замовлення 12345?",
)
Тут є пастка, на якій легко втратити пів години: авторизація за Bearer-токеном тепер увімкнена за замовчуванням, навіть на localhost. Токен генерується при старті й друкується в консоль. Якщо в прикладах ви бачите api_key="not-needed" — це застаріло, і запит поверне 401. Або підставляйте токен, або запускайте з --no-auth.
Це дуже зручно для того етапу, коли фронтенду ще немає, а показати замовнику щось треба вже завтра. Одне важливе застереження: DevUI — інструмент розробки, не для продакшену, і в README це написано прямим текстом.
AG-UI: спільна мова агента й інтерфейсу
Ось тут ховається найбільша економія часу, про яку зазвичай не думають на старті.
Агент — це не чат-бот, який видає абзац тексту. Агент працює довго, викликає інструменти, змінює свій стан, іноді питає дозволу. Все це користувач має бачити. І кожна команда до недавнього часу винаходила свій спосіб це показати: свій формат подій, свій стрімінг, свої милиці.
AG-UI — це стандарт на цю комунікацію. Він навмисне простий: фронтенд шле POST, бекенд стрімить назад типізовані JSON-події через SSE. Типів подій станом на серпень 2026 — двадцять сім: життєвий цикл запуску, шматки тексту, виклики інструментів, зміни стану, міркування моделі, довільні RAW і CUSTOM. Транспорт при цьому не прибитий цвяхами: SSE є референсним, але протокол однаково працює поверх WebSocket чи вебхуків.
У Agent Framework це підключається парою рядків:
using Microsoft.Agents.AI.Hosting.AGUI.AspNetCore;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAGUIServer();
var app = builder.Build();
app.MapAGUIServer("/", agent);
app.Run();
Тут теж варто звірятися з репозиторієм, а не тільки з Learn: у частині статей і навіть на деяких сторінках документації досі трапляється старіша назва MapAGUI без AddAGUIServer(). У поточних preview-збірках працює саме MapAGUIServer.
Або на Python — тут пакет уже вийшов зі стадії превʼю, тож --pre більше не потрібен:
pip install agent-framework-ag-ui
Все. Ваш агент тепер говорить стандартною мовою, і будь-який AG-UI-сумісний фронтенд його зрозуміє.
Що саме дає протокол «з коробки»:
- Стрімінг чату з автоматичним викликом інструментів.
- Показ роботи інструментів — користувач бачить, що агент зараз шукає в базі, а не просто «думає».
- Human-in-the-loop — агент зупиняється і чекає підтвердження перед небезпечною дією.
- Спільний стан — фронтенд і бекенд синхронізують один обʼєкт стану в обидва боки.
- Генеративний UI — агент повертає не текст, а вказівку відрендерити конкретний компонент.
І головне: AG-UI підтримує не тільки Microsoft. У списку першої категорії підтримки — Microsoft Agent Framework, Google ADK, AWS Strands, LlamaIndex, Pydantic AI, Mastra, Agno, AG2; через партнерства — LangGraph і CrewAI; силами спільноти — Claude Agent SDK і Langroid. Тобто ви можете переписати бекенд агента з Python на .NET, а фронтенд навіть не помітить. Це рідкісна розкіш.
Спробувати без свого коду можна так:
npx create-ag-ui-app@latest
CopilotKit: фронтенд, який уже все вміє
AG-UI — це протокол. CopilotKit — готовий React-фронтенд, який його реалізує. Це ті самі люди, які протокол і придумали.
Одразу застереження, бо на ньому легко обпектися: у CopilotKit є два покоління API. Старі хуки — useCopilotAction, useCopilotReadable, useCoAgent — досі працюють і нікуди з пакета не поділися, але документація вже описує v2, а в коді вони позначені як legacy. Усі приклади нижче — на v2, який імпортується з підшляху /v2. Якщо гуглитимете і натрапите на старі назви — це не помилка автора, це попереднє покоління.
Мінімальний варіант — обгорнути застосунок провайдером і додати готовий чат:
import { CopilotKit, CopilotSidebar } from "@copilotkit/react-core/v2";
import "@copilotkit/react-core/v2/styles.css";
export default function App() {
return (
<CopilotKit runtimeUrl="/api/copilotkit">
<YourApp />
<CopilotSidebar labels={{ modalHeaderTitle: "Помічник" }} />
</CopilotKit>
);
}
Це вже робочий чат-асистент збоку екрана. Але цікаве починається далі.
Агент бачить те саме, що й користувач. Замість того щоб копіювати контекст у промпт руками, ви просто оголошуєте, що агенту видно:
import { useAgentContext } from "@copilotkit/react-core/v2";
useAgentContext({
description: "Поточний кошик користувача",
value: cartItems,
});
Агент може натискати кнопки у вашому інтерфейсі. Це фронтенд-інструменти — функції, які виконуються в браузері. Схема параметрів тепер описується через Zod, а не масивом обʼєктів:
import { useFrontendTool } from "@copilotkit/react-core/v2";
import { z } from "zod";
useFrontendTool({
name: "addToCart",
description: "Додати товар у кошик",
parameters: z.object({
productId: z.string().describe("ID товару"),
quantity: z.number().describe("Кількість"),
}),
handler: async ({ productId, quantity }) => {
addItem(productId, quantity);
},
});
Тепер користувач пише «додай дві такі ж футболки» — і кошик оновлюється. Без API, без окремого ендпоінта.
Агент може малювати інтерфейс. Найефектніша частина — замість тексту повернути компонент:
import { useRenderTool } from "@copilotkit/react-core/v2";
import { z } from "zod";
useRenderTool({
name: "showOrderStatus",
parameters: z.object({ orderId: z.string() }),
render: ({ status, parameters, result }) =>
status === "complete"
? <OrderCard order={result} />
: <OrderCardSkeleton id={parameters.orderId} />,
});
Замість абзацу «Ваше замовлення 12345 у дорозі, орієнтовна доставка завтра» користувач бачить нормальну картку з трекінгом і кнопкою — причому ще до того, як бекенд відповів, бо status дозволяє показати скелетон.
Одна незручність, про яку варто знати заздалегідь: у useRenderTool аргументи приходять у полі parameters, а в інлайновому render всередині useFrontendTool — у полі args. Це справді так в обох API, а не помилка в документації.
Спільний стан із бекенд-агентом. Якщо ваш агент довго працює над задачею і має власний стан — його видно в React:
import { useAgent } from "@copilotkit/react-core/v2";
const { agent, isReady } = useAgent({ agentId: "research-agent" });
// agent.state, agent.messages, agent.isRunning
agent.setState({ ...agent.state, topic: "AG-UI" });
Агент додав джерело — компонент перемалювався. Користувач змінив тему — агент про це знає.
Підключення AG-UI-бекенду. Ваш ендпоінт реєструється в рантаймі як HttpAgent — і після цього все перелічене вище працює автоматично:
// app/api/copilotkit/route.ts
import { HttpAgent } from "@ag-ui/client";
import { CopilotRuntime, copilotRuntimeNextJSAppRouterEndpoint } from "@copilotkit/runtime";
const runtime = new CopilotRuntime({
agents: { default: new HttpAgent({ url: "http://localhost:8000/" }) },
});
export const POST = async (req) => {
const { handleRequest } = copilotRuntimeNextJSAppRouterEndpoint({
runtime,
endpoint: "/api/copilotkit",
});
return handleRequest(req);
};
Ну і практичне: є готові компоненти CopilotChat, CopilotSidebar, CopilotPopup, а є headless-режим, коли вам віддають лише логіку, а весь дизайн ви робите свій. Є інтеграції зі Slack і Teams — той самий агент живе і в застосунку, і в корпоративному месенджері.
Як це складається разом
Уявімо реальну задачу: асистент для внутрішнього порталу компанії. Вміє шукати по базі знань, дивитися статуси задач, створювати заявки. Ось як виглядає шлях.
День перший. Пишете агента на Agent Framework. Три функції-інструменти, один промпт. Запускаєте serve(entities=[agent]) і в DevUI ганяєте його запитами: правильні інструменти? нормальні відповіді? Правите промпт, поки не почне поводитися пристойно. Фронтенду ще немає, і він не потрібен.
День другий. Додаєте app.MapAGUIServer("/", agent) — агент став HTTP-сервісом зі стрімінгом. Піднімаєте фронтенд на CopilotKit, вказуєте runtime URL. Отримуєте чат зі стрімінгом, показом інструментів і підтвердженнями. Написаного коду UI — рядків двадцять.
День третій. Заявку на доступ агент створювати вміє, але робити це без підтвердження страшно. Позначаєте інструмент як такий, що потребує апруву — AG-UI сам покаже користувачу діалог «підтвердити / відхилити». Далі додаєте useRenderTool, щоб замість тексту про заявку показувалася картка з кнопкою «відкрити в трекері».
День четвертий. Загортаєте все в Aspire: агент, фронтенд, Postgres для історії, Redis для кешу, окремий Python-сервіс для пошуку по базі знань. Одна команда — і вся система жива, з дашбордом, логами й наскрізними трейсами OpenTelemetry: видно, скільки коштував запит, який інструмент гальмує, де впало.
Чотири дні. Не тому, що хтось геніальний, а тому, що жоден із цих шарів не довелося писати самому.
Що варто памʼятати
Кілька тверезих зауважень, щоб стаття не виглядала рекламою.
Швидко зробити прототип ≠ швидко зробити продукт. Стек економить інфраструктурну роботу, але промпти, оцінка якості, обробка галюцинацій і граничні випадки — все одно ваші. Саме туди піде більшість часу, і це нормально.
Набір інструментів залежить від провайдера моделі. Function tools і локальний MCP працюють майже скрізь, а code interpreter чи file search — не завжди. Матрицю сумісності краще перевірити до того, як закласти щось в архітектуру, а не після.
DevUI — не продакшен. Це інструмент розробника, і в документації це написано прямо.
Частина речей досі в preview. Ядро Agent Framework і Python-пакет AG-UI уже GA, а от .NET-пакети хостингу AG-UI та DevUI, інтеграція Aspire з Foundry і функціональні воркфлоу — ні. Для внутрішніх інструментів це цілком ок, для критичних систем — тримайте в голові.
Документація місцями відстає від коду. Це найнеприємніше на практиці. Правило просте: якщо приклад із документації не працює — йдіть у репозиторій і дивіться README або код. Екосистема рухається швидше, ніж встигають оновлювати сторінки.
Але загальний напрямок дуже приємний. Розробка агентів перестала бути дослідницьким проєктом і стала звичайною інженерією: є оркестратор, є фреймворк, є протокол, є UI-бібліотека, є інструмент для дебагу. Приблизно як веб-розробка років пʼятнадцять тому перестала бути мистецтвом і стала ремеслом.
А найкраще в цьому те, що всі шари взаємозамінні. Не подобається CopilotKit — пишіть свій фронтенд на AG-UI. Не подобається Agent Framework — беріть LangGraph чи Pydantic AI, протокол той самий. Оце і є ознака зрілої екосистеми.
Sources: Aspire — AppHost, Aspire — Azure AI Foundry hosting, Aspire — Python integration, Announcing Aspire 13.2, What’s new in Aspire 13.4, Distributed multi-agent systems with Aspire and Microsoft Agent Framework, Microsoft Agent Framework Overview, DevUI README, AG-UI integration — getting started, AG-UI Protocol (GitHub), AG-UI event types, CopilotKit — migrate to v2, CopilotKit — useFrontendTool, CopilotKit — useRenderTool, CopilotKit — useAgent, CopilotKit — connect AG-UI agents