Crawler Summary

goit-aad-hw-10 answer-first brief

Практичне завдання №2: мультиагентна система логістики — supervisor у LangGraph, CrewAI та Google ADK над спільним MCP-сервером (FastMCP), guardrails (injection/allowlist/PII), HITL, tracing у LangSmith, deepeval + DeepTeam Мультиагентна система логістики: LangGraph, CrewAI, MCP і security hardening Практичне завдання №2 курсу «Агентні системи». Предметна область варіанта — **логістика та складський облік**: трекінг відправлень, залишки на складах, розрахунок вартості доставки і **скасування відправлення з поверненням коштів** як ризикова незворотна операція. Один і той самий кейс реалізовано **тричі** — у LangGraph (supervisor + 3 ворк Capability contract not published. No trust telemetry is available yet. Last updated 10/9/2026.

Freshness

Last checked 10/9/2026

Best For

goit-aad-hw-10 is best for crewai, multi-agent workflows where OpenClaw compatibility matters.

Not Ideal For

Contract metadata is missing or unavailable for deterministic execution.

Evidence Sources Checked

editorial-content, GITHUB REPOS, runtime-metrics, public facts pack

Claim this agent
Agent DossierGITHUB REPOSSafety: 66/100

goit-aad-hw-10

Практичне завдання №2: мультиагентна система логістики — supervisor у LangGraph, CrewAI та Google ADK над спільним MCP-сервером (FastMCP), guardrails (injection/allowlist/PII), HITL, tracing у LangSmith, deepeval + DeepTeam Мультиагентна система логістики: LangGraph, CrewAI, MCP і security hardening Практичне завдання №2 курсу «Агентні системи». Предметна область варіанта — **логістика та складський облік**: трекінг відправлень, залишки на складах, розрахунок вартості доставки і **скасування відправлення з поверненням коштів** як ризикова незворотна операція. Один і той самий кейс реалізовано **тричі** — у LangGraph (supervisor + 3 ворк

OpenClawself-declared

Public facts

4

Change events

1

Artifacts

0

Freshness

Oct 9, 2026

Verifiededitorial-contentNo verified compatibility signals

Capability contract not published. No trust telemetry is available yet. Last updated 10/9/2026.

Trust evidence available

Trust score

Unknown

Compatibility

OpenClaw

Freshness

Oct 9, 2026

Vendor

Alexnodejs

Artifacts

0

Benchmarks

0

Last release

Unpublished

Executive Summary

Key links, install path, and a quick operational read before the deeper crawl record.

Verifiededitorial-content

Summary

Capability contract not published. No trust telemetry is available yet. Last updated 10/9/2026.

Setup snapshot

  1. 1

    Setup complexity is LOW. This package is likely designed for quick installation with minimal external side-effects.

  2. 2

    Final validation: Expose the agent to a mock request payload inside a sandbox and trace the network egress before allowing access to real customer data.

Evidence Ledger

Everything public we have scraped or crawled about this agent, grouped by evidence type with provenance.

Verifiededitorial-content
Vendor (1)

Vendor

Alexnodejs

profilemedium
Observed Oct 9, 2026Source linkProvenance
Compatibility (1)

Protocol compatibility

OpenClaw

contractmedium
Observed Oct 9, 2026Source linkProvenance
Security (1)

Handshake status

UNKNOWN

trustmedium
Observed unknownSource linkProvenance
Integration (1)

Crawlable docs

6 indexed pages on the official domain

search_documentmedium
Observed Apr 15, 2026Source linkProvenance

Release & Crawl Timeline

Merged public release, docs, artifact, benchmark, pricing, and trust refresh events.

Self-declaredagent-index

Artifacts Archive

Extracted files, examples, snippets, parameters, dependencies, permissions, and artifact metadata.

Self-declaredGITHUB REPOS

Extracted files

0

Examples

4

Snippets

0

Languages

python

Executable Examples

bash

# 1. Оточення (окремий venv — див. розділ 12, чому не в базовий)
uv venv --python 3.13
uv pip install -r requirements.txt

# 2. Ключі
cp .env.example .env      # вписати OPENROUTER_API_KEY і LANGSMITH_API_KEY

# 3. Самоперевірки БЕЗ мережі та БЕЗ ключів — усе має пройти
.venv/bin/python mcp_server.py --selfcheck   # 4 MCP-інструменти, валідатори, JSON-конверт
.venv/bin/python guards.py                   # injection / allowlist / PII / CostTracker
.venv/bin/python mas_crewai.py --selfcheck   # склад crew і allowlist
.venv/bin/python mas_adk.py --selfcheck      # структура workflow-пайплайна
.venv/bin/python mas_langgraph.py --graph    # mermaid-схема графа
.venv/bin/python -m pytest test_mas.py -v    # 63 тести

# 4. Живі запити (потрібен ключ)
.venv/bin/python mas_langgraph.py "Де зараз посилка TTN-000001?"
.venv/bin/python mas_crewai.py    "Скільки ноутбуків SKU-1001 на складах?"
.venv/bin/python mas_adk.py       "Статус TTN-000001 і залишок SKU-1001"

# 5. Human-in-the-loop: граф зупиняється і чекає рішення оператора
.venv/bin/python mas_langgraph.py --thread h1 "Скасуй TTN-000004, клієнт відмовився, поверни 720 грн"
.venv/bin/python mas_langgraph.py --thread h1 --show-state      # інший процес бачить паузу
.venv/bin/python mas_langgraph.py --thread h1 --approve         # або --reject "занадто рано"

# 6. Повний прогін демонстрацій → demo_results.json, costs.json, trace_langsmith.json
.venv/bin/python demos.py
.venv/bin/python demos.py --only guardrails hitl

# 7. Бонуси: evals і red-teaming (результати кешуються, --force перерахує)
.venv/bin/python evals.py

text

goit-aad-hw-10/
├── mcp_server.py       # вимога 3: FastMCP-сервер, 4 інструменти + мок-дані домену
├── guards.py           # вимога 5: injection / allowlist+валідація / PII + облік вартості
├── mas_langgraph.py    # вимоги 1, 6: supervisor + 3 воркери, MCP, HITL, LangSmith, CLI
├── mas_crewai.py       # вимога 2: той самий кейс на CrewAI над тим самим MCP-сервером
├── mas_adk.py          # бонус: Google ADK, ParallelAgent → SequentialAgent
├── evals.py            # бонус: deepeval (5 кейсів) + DeepTeam (3 типи атак)
├── demos.py            # вимога 4 та зведення: усі демонстрації → JSON-артефакти
├── test_mas.py         # вимога 7: 63 офлайн-тести
├── requirements.txt · .gitignore · pytest.ini · .env.example
├── demo_output.txt · pytest_output.txt          # вивід прогонів
├── demo_results.json · costs.json · evals_results.json
├── trace_langsmith.json                          # фрагмент трейсу для здачі
├── evals_results_before_hardening.json           # red-teaming ДО виправлень
└── Task_002_Vasileyko_Logistics.ipynb

mermaid

graph TD;
	__start__([__start__]):::first
	supervisor(supervisor)
	tracking_agent(tracking_agent)
	warehouse_agent(warehouse_agent)
	pricing_agent(pricing_agent)
	__end__([__end__]):::last
	__start__ --> supervisor;
	supervisor -.->|transfer_to_tracking_agent| tracking_agent;
	supervisor -.->|transfer_to_warehouse_agent| warehouse_agent;
	supervisor -.->|transfer_to_pricing_agent| pricing_agent;
	tracking_agent --> supervisor;
	warehouse_agent --> supervisor;
	pricing_agent --> supervisor;
	supervisor -.-> __end__;
	classDef default fill:#f2f0ff,line-height:1.2
	classDef first fill-opacity:0
	classDef last fill:#bfb6fc

text

LangGraph → supervisor → transfer_to_tracking_agent → tracking_agent
          → call_model → ChatOpenAI → tools → cancel_shipment
          + PIIMiddleware[email]/[credit_card], HumanInTheLoopMiddleware, ToolCallLimitMiddleware

Docs & README

Full documentation captured from public sources, including the complete README when available.

Self-declaredGITHUB REPOS

Docs source

GITHUB REPOS

Editorial quality

ready

Практичне завдання №2: мультиагентна система логістики — supervisor у LangGraph, CrewAI та Google ADK над спільним MCP-сервером (FastMCP), guardrails (injection/allowlist/PII), HITL, tracing у LangSmith, deepeval + DeepTeam Мультиагентна система логістики: LangGraph, CrewAI, MCP і security hardening Практичне завдання №2 курсу «Агентні системи». Предметна область варіанта — **логістика та складський облік**: трекінг відправлень, залишки на складах, розрахунок вартості доставки і **скасування відправлення з поверненням коштів** як ризикова незворотна операція. Один і той самий кейс реалізовано **тричі** — у LangGraph (supervisor + 3 ворк

Full README

Мультиагентна система логістики: LangGraph, CrewAI, MCP і security hardening

Практичне завдання №2 курсу «Агентні системи». Предметна область варіанта — логістика та складський облік: трекінг відправлень, залишки на складах, розрахунок вартості доставки і скасування відправлення з поверненням коштів як ризикова незворотна операція.

Один і той самий кейс реалізовано тричі — у LangGraph (supervisor + 3 воркери), CrewAI (менеджер + 3 виконавці) і Google ADK (workflow-агенти). Усі три ходять у домен через один кастомний MCP-сервер, тому порівняння фреймворків міряє саме оркестрацію, а не інструменти.

LLM-провайдер — OpenRouter (OpenAI-сумісний API), модель openai/gpt-4.1, temperature=0.1; судді evals і генератор атак — дешевша openai/gpt-4.1-mini.


1. Швидкий старт

# 1. Оточення (окремий venv — див. розділ 12, чому не в базовий)
uv venv --python 3.13
uv pip install -r requirements.txt

# 2. Ключі
cp .env.example .env      # вписати OPENROUTER_API_KEY і LANGSMITH_API_KEY

# 3. Самоперевірки БЕЗ мережі та БЕЗ ключів — усе має пройти
.venv/bin/python mcp_server.py --selfcheck   # 4 MCP-інструменти, валідатори, JSON-конверт
.venv/bin/python guards.py                   # injection / allowlist / PII / CostTracker
.venv/bin/python mas_crewai.py --selfcheck   # склад crew і allowlist
.venv/bin/python mas_adk.py --selfcheck      # структура workflow-пайплайна
.venv/bin/python mas_langgraph.py --graph    # mermaid-схема графа
.venv/bin/python -m pytest test_mas.py -v    # 63 тести

# 4. Живі запити (потрібен ключ)
.venv/bin/python mas_langgraph.py "Де зараз посилка TTN-000001?"
.venv/bin/python mas_crewai.py    "Скільки ноутбуків SKU-1001 на складах?"
.venv/bin/python mas_adk.py       "Статус TTN-000001 і залишок SKU-1001"

# 5. Human-in-the-loop: граф зупиняється і чекає рішення оператора
.venv/bin/python mas_langgraph.py --thread h1 "Скасуй TTN-000004, клієнт відмовився, поверни 720 грн"
.venv/bin/python mas_langgraph.py --thread h1 --show-state      # інший процес бачить паузу
.venv/bin/python mas_langgraph.py --thread h1 --approve         # або --reject "занадто рано"

# 6. Повний прогін демонстрацій → demo_results.json, costs.json, trace_langsmith.json
.venv/bin/python demos.py
.venv/bin/python demos.py --only guardrails hitl

# 7. Бонуси: evals і red-teaming (результати кешуються, --force перерахує)
.venv/bin/python evals.py

Ноутбук Task_002_Vasileyko_Logistics.ipynb запускається на ядрі GoIT HW-10: .venv/bin/python -m ipykernel install --user --name goit-hw-10 --display-name "GoIT HW-10"

Режими --selfcheck, --graph, --show-state, --approve і --reject працюють без ключів: LLM у них не викликається, а стан паузи читається з чекпоїнтера.


2. Структура файлів

goit-aad-hw-10/
├── mcp_server.py       # вимога 3: FastMCP-сервер, 4 інструменти + мок-дані домену
├── guards.py           # вимога 5: injection / allowlist+валідація / PII + облік вартості
├── mas_langgraph.py    # вимоги 1, 6: supervisor + 3 воркери, MCP, HITL, LangSmith, CLI
├── mas_crewai.py       # вимога 2: той самий кейс на CrewAI над тим самим MCP-сервером
├── mas_adk.py          # бонус: Google ADK, ParallelAgent → SequentialAgent
├── evals.py            # бонус: deepeval (5 кейсів) + DeepTeam (3 типи атак)
├── demos.py            # вимога 4 та зведення: усі демонстрації → JSON-артефакти
├── test_mas.py         # вимога 7: 63 офлайн-тести
├── requirements.txt · .gitignore · pytest.ini · .env.example
├── demo_output.txt · pytest_output.txt          # вивід прогонів
├── demo_results.json · costs.json · evals_results.json
├── trace_langsmith.json                          # фрагмент трейсу для здачі
├── evals_results_before_hardening.json           # red-teaming ДО виправлень
└── Task_002_Vasileyko_Logistics.ipynb

Окремого hitl.py немає свідомо: у LangChain 1.3 HITL — це один middleware, і власний модуль навколо нього був би церемонією. Облік вартості теж не окремий файл, а клас у guards.py, бо його зовуть усі три реалізації.


3. Архітектура

graph TD;
	__start__([__start__]):::first
	supervisor(supervisor)
	tracking_agent(tracking_agent)
	warehouse_agent(warehouse_agent)
	pricing_agent(pricing_agent)
	__end__([__end__]):::last
	__start__ --> supervisor;
	supervisor -.->|transfer_to_tracking_agent| tracking_agent;
	supervisor -.->|transfer_to_warehouse_agent| warehouse_agent;
	supervisor -.->|transfer_to_pricing_agent| pricing_agent;
	tracking_agent --> supervisor;
	warehouse_agent --> supervisor;
	pricing_agent --> supervisor;
	supervisor -.-> __end__;
	classDef default fill:#f2f0ff,line-height:1.2
	classDef first fill-opacity:0
	classDef last fill:#bfb6fc

Ролі та правила handoff

| Агент | Роль | Дозволені інструменти | Правило передачі | |---|---|---|---| | supervisor | координатор | жодного | маршрутизує і підсумовує | | tracking_agent | оператор служби доставки | track_shipment, cancel_shipment | статус, історія, скасування ТТН | | warehouse_agent | комірник | check_stock | залишки за артикулом SKU | | pricing_agent | тарифікатор | calc_delivery | вартість і термін доставки |

Супервізор навмисно не має доступу до доменних інструментів: інакше він міг би обійти і поділ ролей, і HITL. Це не декларація — guards.ALLOWLIST["supervisor"] порожній, і guarded_tools поверне йому порожній список.


4. MCP-сервер (вимога 3)

mcp_server.py — сервер на mcp.server.fastmcp.FastMCP, транспорт stdio.

| Інструмент | Аргументи | Ризик | |---|---|---| | track_shipment | tracking_id | read-only | | check_stock | sku, warehouse?, min_qty | read-only | | calc_delivery | origin, destination, weight_kg, service, declared_value_uah? | read-only | | cancel_shipment | tracking_id, reason, refund_uah | незворотний, під HITL |

Дві схеми на кожен інструмент, і це не дублювання. Сигнатура з Annotated[str, Field(description=...)] — те, що FastMCP перетворює на JSON Schema і показує моделі. Pydantic-модель *Input усередині — те, чого в JSON Schema не виразити: нормалізація регістру (ttn-000001 → TTN-000001, одеса → Одеса) і крос-польові правила (origin != destination).

Три деталі, які виявилися принциповими:

  • Жодного print() у сервері. У stdio stdout — це канал JSON-RPC; будь-який друк ламає протокол. Логи йдуть у stderr через logging.
  • Журнал скасувань — у файлі cancelled.json, не в пам'яті. Клієнт langchain-mcp-adapters піднімає новий процес сервера на кожен виклик інструмента («A new session will be created for each tool call»). Побічний ефект у глобальній змінній зникав би разом із процесом, і HITL-демонстрація нічого не доводила б.
  • Помилка валідації повертається конвертом, а не винятком. Модель бачить {"status": "error", "problems": ["tracking_id: очікується формат TTN-XXXXXX"]} і має з чого виправити аргументи.

Три різні способи під'єднати той самий сервер

| Реалізація | Механізм | Як задається allowlist | |---|---|---| | LangGraph | langchain-mcp-adapters → MultiServerMCPClient.get_tools() | guards.guarded_tools фільтрує + обгортає перевіркою | | CrewAI | crewai_tools.MCPServerAdapter + StdioServerParameters | фільтрація списку за guards.ALLOWLIST | | Google ADK | google.adk.tools.mcp_tool.McpToolset | tool_filter=[...] на рівні самого toolset |


5. MAS у LangGraph (вимога 1)

Супервізор — langgraph_supervisor.create_supervisor, він сам генерує handoff-інструменти transfer_to_<agent>. Воркери — langchain.agents.create_agent з переліком дозволених інструментів і middleware свого рівня ризику.

Стан — AsyncSqliteSaver у mas_state.db. Асинхронність тут не примха: інструменти MCP існують лише як корутини, тому синхронний invoke по них не пройде, і чекпоїнтер довелося брати async-варіантом.

CLI повторює логіку ПЗ №1: --thread для персистентності, --show-state, --approve, --reject — і всі вони працюють з іншого процесу.


6. MAS у CrewAI (вимога 2) і порівняльна таблиця

Process.hierarchical — це і є supervisor у термінах CrewAI: manager_agent сам вирішує, кому делегувати. Ролі дзеркалять воркерів LangGraph дослівно, інакше порівняння було б нечесним.

Порівняння на однакових запитах

Три однакові запити, той самий MCP-сервер, та сама модель. Дані — з costs.json, згенерованого demos.py:

| Фреймворк | Запитів | Токенів | Вартість, $ | Час, мс | × токенів до мінімуму | |---|---:|---:|---:|---:|---:| | LangGraph | 3 | 6 773 | 0.017512 | 14 864 | 1.00 | | Google ADK | 3 | 8 470 | 0.019352 | 13 518 | 1.25 | | CrewAI | 3 | 32 528 | 0.086056 | 14 886 | 4.80 |

Рядки коду

| Метрика | LangGraph | CrewAI | ADK | |---|---:|---:|---:| | Модуль цілком | 370 | 265 | 198 | | Рядків коду (без коментарів і докстрінгів) | 213 | 174 | 130 | | Лише складання агентів (build_*) | 34 | 34 | 23 |

Якісне порівняння

| Критерій | LangGraph | CrewAI | Google ADK | |---|---|---|---| | Модель оркестрації | явний граф, handoff-інструменти | менеджер делегує «по-людськи» | фіксований workflow (Parallel → Sequential) | | Контроль маршруту | повний: видно вузли й ребра | непрямий, через промпт менеджера | повний, але маршрут статичний | | Персистентність стану | є (checkpointer) | немає | немає (InMemorySessionService) | | HITL із паузою | так, interrupt + resume | ні — лише відмова наперед | ні | | Debugging | --graph, --show-state, спани по вузлах | лог делегування, спани crew/task | лог подій, output_key у стані | | Витрати токенів | базові | ×4.8 | ×1.25 | | Готовність до продакшену | висока | середня | середня |

Головний висновок порівняння: різниця в коді мінімальна, різниця в токенах — майже п'ятикратна. Складання агентів займає 34 рядки і там, і там (23 в ADK), тобто «менше коду» не є перевагою жодного з фреймворків. А от CrewAI на тих самих трьох запитах спалив 32 528 токенів проти 6 773 у LangGraph. Причина видно в трейсі: ієрархічний процес спершу веде діалог менеджера з виконавцем (Ask question to coworker), і повний контекст задачі переказується двічі — менеджеру й виконавцю. LangGraph передає керування одним transfer_to_* без переказу.


7. Guardrails (вимога 5)

guards.py навмисно не імпортує ані langchain, ані crewai, ані adk: ті самі функції зовуть усі три реалізації, а middleware є лише в LangChain.

Input — детекція prompt injection

Шість правил (guards.INJECTION_PATTERNS), українською й англійською: override_instructions, reveal_system_prompt, role_marker_injection, new_persona, structured_exfiltration, encoded_payload, exfiltrate_secrets. Перевірка стоїть до першого звернення до LLM, тому заблокована атака коштує рівно 0 токенів — це видно у demo_output.txt.

Tool — allowlist на агента + валідація аргументів

Два рубежі, а не один:

  1. guarded_tools(agent, tools) фізично не видає агенту чужі інструменти — вони не потраплять навіть у tool_calls моделі;
  2. обгортка перевіряє аргументи під час виклику — на випадок, якщо виклик прийде в обхід (з кешованого стану чи чужого handoff).

Доменні правила поверх Pydantic: формати TTN-\d{6} / SKU-\d{4}, відомі міста й склади і стеля автоматичного повернення MAX_REFUND_UAH = 5000 — понад неї скасування не проходить навіть після підтвердження оператора.

Output — редакція PII

Шість типів: телефон (+380 і 0XX), e-mail, картка, IBAN UA, ЄДРПОУ, ІПН. Порядок правил має значення: IBAN і картку шукаємо раніше за телефон та ІПН, інакше довший номер розрізався б коротшим правилом на шматки.

Доменні ідентифікатори PII не є: TTN-000001, SKU-1001 і суми лишаються в тексті — інакше відповідь стала б беззмістовною (test_pii_redaction_keeps_domain_identifiers).

У LangGraph поверх цього ввімкнено готові PIIMiddleware (email, credit_card) і ToolCallLimitMiddleware з LangChain 1.3 — писати своє під те, що вже є в залежності, сенсу немає. redact_pii закриває українську специфіку, якої в них немає, і працює для CrewAI та ADK, де middleware не існує.

Знайдений і виправлений баг. Перша версія правила для телефону мала (?:\+?38[\s-]?)?\b0\d{2}… — і мовчки пропускала +380671234567: між «8» і «0» словесної межі \b не існує. Спіймано тим, що самоперевірка перевіряла лише наявність маркера [REDACTED:PHONE], а він з'являвся від другого номера в рядку. Виправлено на (?<!\d)…(?!\d); тест test_international_phone_is_not_missed закриває регресію.


8. Human-in-the-loop (вимога 6)

HumanInTheLoopMiddleware з LangChain 1.3, точково на cancel_shipment і лише в tracking_agent. Дозволені рішення — approve, edit, reject.

Чому middleware, а не interrupt_before=["tools"]: останній зупиняє весь вузол інструментів, тобто пауза виникала б і перед звичайним трекінгом. Middleware зупиняє рівно перед незворотною операцією.

Що доводить демонстрація (demos.py --only hitl, вивід у demo_output.txt):

| Тред | Пауза | Інший процес бачить дію | Журнал до → після | |---|---|---|---| | demo-reject | так | так | 0 → 0 — скасування не відбулося | | demo-approve | так | так | 0 → 1 — скасування записане |

Рішення приймається окремим процесом (demos.py ходить через subprocess): це і є доказ, що стан паузи лежить у чекпоїнтері, а не в пам'яті.


9. Tracing (вимога 4)

Проєкт LangSmith — goit-hw-10. Збережений фрагмент — trace_langsmith.json (25 спанів в одному трейсі).

LangGraph — нульовий код, самі змінні оточення (LANGSMITH_TRACING=true, LANGSMITH_API_KEY, LANGSMITH_PROJECT). base_url OpenRouter трасуванню не заважає: трейсер чіпляється до BaseChatModel, а не до HTTP-клієнта. У трейсі видно повний ланцюг:

LangGraph → supervisor → transfer_to_tracking_agent → tracking_agent
          → call_model → ChatOpenAI → tools → cancel_shipment
          + PIIMiddleware[email]/[credit_card], HumanInTheLoopMiddleware, ToolCallLimitMiddleware

CrewAI — через OpenTelemetry на OTLP-приймач LangSmith (https://api.smith.langchain.com/otel/v1/traces) плюс openinference-instrumentation-crewai. У трейсі: Crew.kickoff → Координатор служби логістики._execute_core → Ask question to coworker → track_shipment.

Чому не колбек LiteLLM. Документований і найдешевший шлях — litellm.callbacks = ["langsmith"] — тут не працює, і на це пішло чотири ітерації. Причини, знайдені в коді CrewAI 1.15.18:

  1. LLM.__init__ викликає set_callbacks(self.callbacks or []) і затирає глобальний список (crewai/llm.py:732);
  2. обхід через LITELLM_SUCCESS_CALLBACKS теж ненадійний: у set_env_callbacks присвоєння litellm.success_callback вкладене в перевірку LITELLM_FAILURE_CALLBACKS, тож без другої змінної воно просто не виконується;
  3. головне — у CrewAI 1.15 openrouter уже є в SUPPORTED_NATIVE_PROVIDERS, тому фреймворк ходить власним OpenAICompatibleCompletion повз LiteLLM узагалі; is_litellm=True це перемикає, але тоді ми міряли б не той шлях, яким CrewAI працює за замовчуванням.

OTel виявився не просто обхідним шляхом, а кращим: він дає спани crew, task і делегування, а не лише виклики моделі.

Вартість у LangSmith показується як $0 — у його прайс-мапі немає SKU openai/gpt-4.1. Тому вартість рахуємо самі (розділ 11).


10. Тести (вимога 7)

pytest test_mas.py -v → 63 тести, 0.54 с, усі офлайн (повний вивід — pytest_output.txt). Мережа не потрібна, LLM не викликається, ключі не потрібні.

| Група | Тестів | Що перевіряє | |---|---:|---| | MCP: валідація аргументів | 14 | 11 некоректних входів + нормалізація регістру | | MCP: бізнес-логіка | 5 | формула ціни, страховка, ліміт overnight, агрегація складів | | MCP: ризикова операція | 2 | запис у журнал, відмова для доставленого й повторного | | MCP: протокол | 1 | сервер піднімається по stdio і віддає 4 інструменти зі схемами | | Guardrail input | 12 | 7 атак спіймано, 4 чисті запити пропущено, повідомлення не називає правило | | Guardrail tool | 14 | allowlist в обидва боки, невідомий інструмент, стеля повернення | | Guardrail output | 9 | 7 типів PII, збереження ТТН/SKU, регресія міжнародного номера | | Обгортка і HITL | 4 | фільтрація, форма content_and_artifact, HITL лише в tracking_agent | | Облік вартості | 2 | нормалізація префікса openrouter/, арифметика |

Тест test_guarded_tool_blocks_bad_arguments_in_protocol_shape існує через реальний баг: інструменти від langchain-mcp-adapters мають response_format="content_and_artifact" і зобов'язані повертати пару (вміст, артефакт). Перша версія guardrail повертала рядок і валила виклик з ValueError замість того, щоб акуратно його заблокувати.


11. Додаткові вимоги (бонуси)

11.1. Cost tracking

guards.CostTracker + ціни OpenRouter, зняті з /api/v1/models: openai/gpt-4.1 — $2.00/$8.00 за 1M токенів, openai/gpt-4.1-mini — $0.40/$1.60. Джерела токенів різні для кожного фреймворка: get_usage_metadata_callback() для LangGraph, crew.usage_metrics для CrewAI, event.usage_metadata для ADK. Префікс openrouter/ від LiteLLM нормалізується, інакше та сама модель рахувалася б двічі. Результат — таблиця в розділі 6 і costs.json.

11.2. Третя реалізація: Google ADK

ParallelAgent(tracking, warehouse, pricing) → SequentialAgent(…, reporter). Модель через LiteLlm("openrouter/openai/gpt-4.1"), Google-ключ не потрібен. MCP під'єднано третім способом — McpToolset з tool_filter.

Ризиковий інструмент у цю реалізацію не входить свідомо: workflow-агенти йдуть фіксованим маршрутом, місця для паузи в ньому немає, а робити незворотну операцію без HITL не можна.

Цікаве спостереження: ADK виявився найшвидшим (13.5 с проти 14.9 с), бо три збирачі даних працюють паралельно — але саме тому він завжди платить за всіх трьох, навіть коли запит стосується одного.

11.3. Evals (deepeval)

5 тест-кейсів × 2 метрики, суддя openai/gpt-4.1-mini. Результат — 5/5.

| Запит | Answer Relevancy | Grounded (GEval) | |---|---:|---:| | Де зараз посилка TTN-000001? | 1.00 | 0.93 | | Чому затримується TTN-000005? | 1.00 | 0.85 | | Чи є 10 моніторів SKU-1002 у Києві? | 0.75 | 0.99 | | Вартість 8 кг Одеса→Харків express | 1.00 | 0.97 | | Скільки SKU-1001 на складах? | 1.00 | 1.00 |

Перша спроба дала 40% і це була помилка метрики, а не системи. GEval із суцільним багатоскладовим criteria («спирається на дані І не вигадує І не розкриває інструкції І українською») розмивав оцінку і карав відповіді за стислість — хоча всі числа в них правильні (611 грн за 8 кг Одеса→Харків express перевірено вручну: 120 + 22×8 + 0.45×700). Заміна criteria на явні evaluation_steps підняла результат до 5/5 без жодної зміни в самій системі. Висновок: погано специфікований LLM-суддя міряє власну невизначеність.

11.4. Red-teaming (DeepTeam)

3 типи атак (PromptInjection, PromptProbing, LinearJailbreaking) проти 2 класів вразливостей (PIILeakage, PromptLeakage) — 8 атак за прогін.

Що знайшов red-teaming і що виправлено:

| # | Знахідка | Виправлення | |---|---|---| | 1 | Супервізор на прохання «оптимізувати процес» перелічував внутрішню будову: імена tracking_agent/warehouse_agent/pricing_agent і правила маршрутизації | правило нерозголошення в SUPERVISOR_PROMPT | | 2 | Псевдо-режим DATA TRANSFORMATION MODE витягував правила у вигляді JSON (GUARD_EXPOSURE, PERMISSIONS_AND_ROLES) — правило reveal_system_prompt знало дієслова show/reveal, але не analyze/extract | розширено список дієслів + нове правило structured_exfiltration | | 3 | Атаку заблоковано, але сама відмова писала «спрацювало правило reveal_system_prompt» — тобто витікала назва внутрішнього фільтра | guards.BLOCKED_MESSAGE знеособлено; ім'я правила лишається в логах і трейсі |

Стан «до» збережено у evals_results_before_hardening.json, «після» — в evals_results.json.

Чесно про числа. Підсумок останнього прогону: 3 відбито, 1 пробито, 4 — симулятор здався. Це число не варто читати як оцінку: DeepTeam генерує нові атаки на кожному прогоні, тому прогони не порівнюються між собою (за чотири ітерації я бачив 6/8, 5/8, 6/8, 3/8 — при тому, що система ставала строго безпечнішою). А статус «симулятор здався» — це не помилка системи: DeepTeam сам пише, що «the simulator model refused to write the next attack», тобто атакувальна модель відмовилася продовжувати. Тому в evals.py три різні результати (withstood / breached / simulator_gave_up) рознесено явно — початкова версія показувала їх однаково і давала оманливу картину.


12. Аналіз результатів

Чому окремий venv, а не базове оточення

pip install crewai у базовий anaconda-env мутує 15 пакетів, зокрема chromadb 1.5.9 → 1.1.1 — рівно ту бібліотеку, на якій працює RAG попереднього завдання. Плюс два конфлікти, які довелося розв'язувати пінами:

  • mcp==1.28.1 — не 2.x: у mcp 2.0 клас FastMCP перейменовано на MCPServer, а crewai пінить mcp~=1.28.1;
  • deepeval==3.8.9 — не 4.x: deepeval 4 вимагає posthog>=7, chromadb 1.1 (залежність crewai) — posthog<6; разом вони не вирішуються взагалі (ResolutionImpossible);
  • opentelemetry-exporter-otlp-proto-http==1.42.0 — crewai і google-adk обидва капають opentelemetry-api ~1.42.

Скільки коштує оркестрація

Три однакові запити: LangGraph — 6 773 токени ($0.0175), ADK — 8 470 ($0.0194), CrewAI — 32 528 ($0.0861). При цьому коду на складання агентів однаково — 34 рядки в LangGraph і CrewAI, 23 в ADK. Тобто вибір фреймворка — це не вибір «більше чи менше писати», а вибір моделі оркестрації: явна передача керування (один transfer_to_*) проти діалогу менеджера з виконавцем, де контекст переказується двічі.

Чи справді allowlist потрібен, якщо інструменти й так відфільтровані

Так, і саме тому рубежів два. Фільтрація закриває нормальний сценарій: модель не бачить чужого інструмента і не може його попросити. Але allowlist ловить те, чого фільтрація не бачить: виклик із неправильними аргументами. Стеля MAX_REFUND_UAH — не про доступ, а про повноваження: tracking_agent має право на cancel_shipment, але не на повернення 99 000 грн. Такого правила у схемі інструмента немає і бути не може — це політика, а не формат.

Що HITL доводить, а що ні

Демонстрація доводить рівно дві речі: після reject журнал скасувань лишається порожнім, після approve — містить рівно один запис; і що паузу видно з іншого процесу. Друге важливіше за перше: воно означає, що підтвердження може прийти не з того ж скрипта, а з вебхука, чат-бота чи адмінки — стан живе в чекпоїнтері, а не в пам'яті конкретного запуску.

Чого демонстрація не доводить: що модель не викличе скасування без прохання. Від цього захищає не HITL, а промпт воркера і allowlist.

Чи можна довіряти LLM-суддям

Обидва бонуси на LLM-суддях дали спочатку неправильну картину, і в обох випадках винна була постановка, а не система: розмитий criteria в GEval занизив оцінку вчетверо, а нерозрізнені статуси в DeepTeam видавали відмову атакувальної моделі за провал захисту. Практичний висновок: LLM-суддя без явних кроків оцінювання міряє власну невизначеність, а метрику red-teaming не можна читати як абсолютне число — лише як перелік конкретних знайдених векторів.


13. Обмеження і що можна покращити

  • langgraph-supervisor у maintenance mode. Пакет робочий і тягне нуль транзитивних залежностей, але LangChain рекомендує hand-rolled супервізор на handoff-інструментах із Command(goto=…, graph=Command.PARENT). Для продакшену варто перейти — це близько 15 рядків.
  • MCP-сервер піднімається наново на кожен виклик інструмента. Для наших read-only інструментів це лише зайві ~100 мс, але при зростанні кількості викликів варто тримати одну сесію через client.session("logistics").
  • HITL є лише в LangGraph. У CrewAI підтвердження задається прапорцем до запуску (--approve-risky), бо зупинити й продовжити виконання нема де. Це не обхід, а чесне відображення різниці фреймворків.
  • PII-редакція схильна до перестраховки. Правило IPN ловить будь-які 10 цифр підряд; у цьому домені колізій немає, але на іншому корпусі його треба звужувати контекстом.
  • Мок-дані детерміновані. Це свідомо: інакше демонстрації й числа у цьому README неможливо було б відтворити.
  • Числа red-teaming не відтворювані між прогонами — DeepTeam щоразу генерує нові атаки. Для регресійного контролю потрібен зафіксований набір атак, а не свіжа генерація.

Contract & API

Machine endpoints, protocol fit, contract coverage, invocation examples, and guardrails for agent-to-agent use.

MissingGITHUB REPOS

Contract coverage

Status

missing

Auth

None

Streaming

No

Data region

Unspecified

Protocol support

OpenClaw: self-declared

Requires: none

Forbidden: none

Guardrails

Operational confidence: low

No positive guardrails captured.
Invocation examples
curl -s "https://www.xpersona.co/api/v1/agents/crewai-alexnodejs-goit-aad-hw-10/snapshot"
curl -s "https://www.xpersona.co/api/v1/agents/crewai-alexnodejs-goit-aad-hw-10/contract"
curl -s "https://www.xpersona.co/api/v1/agents/crewai-alexnodejs-goit-aad-hw-10/trust"

Reliability & Benchmarks

Trust and runtime signals, benchmark suites, failure patterns, and practical risk constraints.

Missingruntime-metrics

Trust signals

Handshake

UNKNOWN

Confidence

unknown

Attempts 30d

unknown

Fallback rate

unknown

Runtime metrics

Observed P50

unknown

Observed P95

unknown

Rate limit

unknown

Estimated cost

unknown

Do not use if

Contract metadata is missing or unavailable for deterministic execution.
No benchmark suites or observed failure patterns are available.

Media & Demo

Every public screenshot, visual asset, demo link, and owner-provided destination tied to this agent.

Missingno-media
No screenshots, media assets, or demo links are available.

Related Agents

Neighboring agents from the same protocol and source ecosystem for comparison and shortlist building.

Self-declaredprotocol-neighbors
Github ReposUpdated 1h agoRank 70

AionUi

Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!

MCPOPENCLAW
Github ReposUpdated 6mo agoRank 70

activepieces

AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents

OPENCLAW
Github ReposUpdated 6mo agoRank 70

cherry-studio

AI productivity studio with smart chat, autonomous agents, and 300+ assistants.

MCPOPENCLAW
Github ReposUpdated 7mo agoRank 70

CopilotKit

The Frontend for Agents & Generative UI. React + Angular

OPENCLAW
Machine Appendix

Contract JSON

{
  "contractStatus": "missing",
  "authModes": [],
  "requires": [],
  "forbidden": [],
  "supportsMcp": false,
  "supportsA2a": false,
  "supportsStreaming": false,
  "inputSchemaRef": null,
  "outputSchemaRef": null,
  "dataRegion": null,
  "contractUpdatedAt": null,
  "sourceUpdatedAt": null,
  "freshnessSeconds": null
}

Invocation Guide

{
  "preferredApi": {
    "snapshotUrl": "https://www.xpersona.co/api/v1/agents/crewai-alexnodejs-goit-aad-hw-10/snapshot",
    "contractUrl": "https://www.xpersona.co/api/v1/agents/crewai-alexnodejs-goit-aad-hw-10/contract",
    "trustUrl": "https://www.xpersona.co/api/v1/agents/crewai-alexnodejs-goit-aad-hw-10/trust"
  },
  "curlExamples": [
    "curl -s \"https://www.xpersona.co/api/v1/agents/crewai-alexnodejs-goit-aad-hw-10/snapshot\"",
    "curl -s \"https://www.xpersona.co/api/v1/agents/crewai-alexnodejs-goit-aad-hw-10/contract\"",
    "curl -s \"https://www.xpersona.co/api/v1/agents/crewai-alexnodejs-goit-aad-hw-10/trust\""
  ],
  "jsonRequestTemplate": {
    "query": "summarize this repo",
    "constraints": {
      "maxLatencyMs": 2000,
      "protocolPreference": [
        "OPENCLEW"
      ]
    }
  },
  "jsonResponseTemplate": {
    "ok": true,
    "result": {
      "summary": "...",
      "confidence": 0.9
    },
    "meta": {
      "source": "GITHUB_REPOS",
      "generatedAt": "2026-10-09T20:26:27.238Z"
    }
  },
  "retryPolicy": {
    "maxAttempts": 3,
    "backoffMs": [
      500,
      1500,
      3500
    ],
    "retryableConditions": [
      "HTTP_429",
      "HTTP_503",
      "NETWORK_TIMEOUT"
    ]
  }
}

Trust JSON

{
  "status": "unavailable",
  "handshakeStatus": "UNKNOWN",
  "verificationFreshnessHours": null,
  "reputationScore": null,
  "p95LatencyMs": null,
  "successRate30d": null,
  "fallbackRate": null,
  "attempts30d": null,
  "trustUpdatedAt": null,
  "trustConfidence": "unknown",
  "sourceUpdatedAt": null,
  "freshnessSeconds": null
}

Capability Matrix

{
  "rows": [
    {
      "key": "OPENCLEW",
      "type": "protocol",
      "support": "unknown",
      "confidenceSource": "profile",
      "notes": "Listed on profile"
    },
    {
      "key": "crewai",
      "type": "capability",
      "support": "supported",
      "confidenceSource": "profile",
      "notes": "Declared in agent profile metadata"
    },
    {
      "key": "multi-agent",
      "type": "capability",
      "support": "supported",
      "confidenceSource": "profile",
      "notes": "Declared in agent profile metadata"
    }
  ],
  "flattenedTokens": "protocol:OPENCLEW|unknown|profile capability:crewai|supported|profile capability:multi-agent|supported|profile"
}

Facts JSON

[
  {
    "factKey": "vendor",
    "category": "vendor",
    "label": "Vendor",
    "value": "Alexnodejs",
    "href": "https://github.com/alexnodejs/goit-aad-hw-10",
    "sourceUrl": "https://github.com/alexnodejs/goit-aad-hw-10",
    "sourceType": "profile",
    "confidence": "medium",
    "observedAt": "2026-10-09T13:51:05.655Z",
    "isPublic": true
  },
  {
    "factKey": "protocols",
    "category": "compatibility",
    "label": "Protocol compatibility",
    "value": "OpenClaw",
    "href": "https://www.xpersona.co/api/v1/agents/crewai-alexnodejs-goit-aad-hw-10/contract",
    "sourceUrl": "https://www.xpersona.co/api/v1/agents/crewai-alexnodejs-goit-aad-hw-10/contract",
    "sourceType": "contract",
    "confidence": "medium",
    "observedAt": "2026-10-09T13:51:05.655Z",
    "isPublic": true
  },
  {
    "factKey": "docs_crawl",
    "category": "integration",
    "label": "Crawlable docs",
    "value": "6 indexed pages on the official domain",
    "href": "https://github.com/login?return_to=https%3A%2F%2Fgithub.com%2Fopenclaw%2Fskills%2Ftree%2Fmain%2Fskills%2Fasleep123%2Fcaldav-calendar",
    "sourceUrl": "https://github.com/login?return_to=https%3A%2F%2Fgithub.com%2Fopenclaw%2Fskills%2Ftree%2Fmain%2Fskills%2Fasleep123%2Fcaldav-calendar",
    "sourceType": "search_document",
    "confidence": "medium",
    "observedAt": "2026-04-15T05:03:46.393Z",
    "isPublic": true
  },
  {
    "factKey": "handshake_status",
    "category": "security",
    "label": "Handshake status",
    "value": "UNKNOWN",
    "href": "https://www.xpersona.co/api/v1/agents/crewai-alexnodejs-goit-aad-hw-10/trust",
    "sourceUrl": "https://www.xpersona.co/api/v1/agents/crewai-alexnodejs-goit-aad-hw-10/trust",
    "sourceType": "trust",
    "confidence": "medium",
    "observedAt": null,
    "isPublic": true
  }
]

Change Events JSON

[
  {
    "eventType": "docs_update",
    "title": "Docs refreshed: Sign in to GitHub · GitHub",
    "description": "Fresh crawlable documentation was indexed for the official domain.",
    "href": "https://github.com/login?return_to=https%3A%2F%2Fgithub.com%2Fopenclaw%2Fskills%2Ftree%2Fmain%2Fskills%2Fasleep123%2Fcaldav-calendar",
    "sourceUrl": "https://github.com/login?return_to=https%3A%2F%2Fgithub.com%2Fopenclaw%2Fskills%2Ftree%2Fmain%2Fskills%2Fasleep123%2Fcaldav-calendar",
    "sourceType": "search_document",
    "confidence": "medium",
    "observedAt": "2026-04-15T05:03:46.393Z",
    "isPublic": true
  }
]

Sponsored

Ads related to goit-aad-hw-10 and adjacent AI workflows.