Первые посты про Delibera описывали ранние релизы: библиотека, пара стратегий дебатов, провайдеры LLM. С тех пор проект прошёл четырнадцать версий на NuGet, и форма продукта изменилась заметно. Этот текст — заметка изнутри работы: что за продукт получился, какие решения его определили и где он честно заканчивается.
Это не анонс. Это описание состояния на конкретный момент: версия 10.5.3, .NET 10, MIT-лицензия.
Что не так с решением, принятым в чате
Проблема, из которой вырос проект, не в том, что модель отвечает плохо. Проблема в том, что решение, принятое в чате, живёт в переписке. У него нет владельца, нет версии, нет состава участников, и через месяц никто не может восстановить, какие варианты рассматривались и почему выбрали этот.
Совет из нескольких независимых моделей решает часть этой задачи: появляется транскрипт, участники видят аргументы друг друга, а финальный вердикт пишет отдельная модель, которая читает весь разбор. Но сам по себе совет — не продукт. Продукт начинается там, где появляются версии, метрики, воспроизводимые замеры и понятная граница ответственности.
Три ограничения, из которых выросла форма
Интерфейс — это то, что переживёт смену модели
Модели провайдеров меняются каждый месяц, и логика принятия решений не должна меняться вместе с ними. Отсюда разделение: доступ к LLM живёт за ILLMProvider (и за Microsoft.Extensions.AI), а стратегии дебатов, Knowledge Keeper, компрессия и Operator работают поверх интерфейсов и не знают, кто именно отвечает.
Побочный эффект, который мы оценили выше ожиданий: когда провайдер меняется, меняется только адаптер. Стратегия дебатов, протокол раундов и формат вердикта остаются прежними — а это ровно тот слой, в котором живёт накопленная логика продукта.
Измерить раньше, чем заявить
Правило проекта простое: число появляется на сайте только после того, как измерено. Сайт проекта рендерит Markdown из самого репозитория, поэтому страница физически не может анонсировать версию, фичу или число, которых в коде нет.
Это оказалось важнее, чем мы ожидали. Тот самый «30–70% экономии от компрессии контекста» был написан в README до того, как кто-то это измерил. Когда мы добавили измерения, выяснилось, что компрессор не вызывался вообще: десять прогонов показывали ровно 0,00% при нулевых накладных расходах. Сейчас в документации стоит измеренное значение — 11,7–12,1%, — и страница не даст его подменить.
Для продукта, чья ценность в том, что он заменяет человеческое суждение, дисциплина измерения — это не отдел качества. Это часть определения.
Подробные цифры и методика лежат в разделе «Measured Behaviour» на сайте проекта, а архитектурные решения — в разделе «Measured Rounds» роадмапа: релиз 10.5.0 мы назвали именно так, потому что его содержанием был запуск на реальных дебатах и поиск того, что сломано.
Версия — это обещание, а не номер
Публичный API мы версионируем как NET_MAJOR.FEATURE.PATCH: в пределах десятой ветки ломающих изменений нет, ломка возможна только на границе крупных фич. Внутри ветки стабильным держится то, на что опираются интеграторы, и меняется то, что внутри.
Для аудитории .NET это ожидаемо и почти тривиально. Но для ИИ-фреймворка это не деталь: у библиотек этого класса привычка поставлять пре-релиз с «экспериментальным API» и переписывать его в следующем месяце. Мы решили, что стабильное ядро должно пережить смену модельного провайдера, — а значит, и смену второстепенных фич вокруг него.
Что в продукте есть сейчас
Ядро — библиотека Delibera.Core на .NET 10 (C# 15 preview):
- совет из нескольких моделей, три стратегии раундов (
StandardDebate,CritiqueDebate,ConsensusDebate) плюс своя стратегия черезIDebateStrategy; - Chairman — отдельная модель для синтеза финального вердикта;
- Knowledge Keeper — точечный поиск по векторному корпусу (Qdrant или pgvector) по ходу дебатов;
- Operator — микро-агент с доступом к MCP-серверам;
- компрессия контекста между раундами (семантика, дедупликация, суммаризация, гибрид);
- AutoChunking — прогрессивная раздача больших документов по раундам;
- кэш результатов (
InMemory,File,Redis) с детерминированным ключом; - стриминг раундов по SSE, персистентность и возобновление дебатов, структурированный вывод, наблюдаемость через OpenTelemetry;
- библиотека шаблонов дебатов:
ArchitectureReview,RiskAssessment,CodeReview,ProductDecision,SecurityAudit,DataArchitecture.
Поверх ядра — Delibera.Server (ASP.NET Core Minimal API: REST + SSE) и Delibera.Redis (оркестрация и кэш в Redis). Оба опубликованы на NuGet.
Есть веб-интерфейс на Nuxt 4: список дебатов, создание, живые раунды по SSE, вердикт со статистикой токенов, экспорт в Markdown, отмена. Он обращается к API только через серверный прокси Nitro — потому что сервер не регистрирует CORS-политику.
Тесты: 620 проходящих (493 Core, 117 Server, 10 gRPC), ни одного упавшего и ни одного пропущенного, плюс 34 теста веб-интерфейса. Релизная сборка чистая под -warnaserror.
Как это выглядит в коде — минимальный совет:
using Delibera.Core.Council;
using Delibera.Core.Providers;
using var factory = new ProviderFactory();
var ollama = factory.CreateOllama("http://localhost:11434");
var result = await new CouncilBuilder()
.AddMember("llama3.2:3b", ollama, "Analyst")
.AddMember("qwen2.5:7b", ollama, "Strategist")
.SetChairman(Chairman.CreateStandard("qwen2.5:7b", ollama))
.WithStandardDebate()
.WithUserPrompt("Microservices vs Monolith for a 5-person startup?")
.WithMaxRounds(4)
.Build()
.ExecuteAsync();
Как начать
Пакеты живут на NuGet:
dotnet add package Delibera.Core
dotnet add package Delibera.Server
dotnet add package Delibera.Redis
Образы — на Docker Hub, linux/amd64 и linux/arm64:
docker pull techbuzzz/delibera-server:10.5.3
docker pull techbuzzz/delibera-webui:10.5.3
Полный стек поднимается одной командой из клона репозитория: docker compose up -d поднимает сервер, веб-интерфейс, Redis, Qdrant, PostgreSQL с pgvector и Ollama.
Про безопасность. API дебатов не аутентифицирован и не ограничен по частоте, а дебат тратит реальные кредиты у провайдера. Поэтому все публикуемые порты привязаны к
127.0.0.1, и это не украшение: привязка и есть механизм защиты. Прежде чем выставлять стек в сеть, которой вы не управляете, поставьте перед ним аутентифицирующий обратный прокси. Ниже мы приводили измерения против Ollama Cloud — то есть против провайдера, за который кто-то платит.
Где у продукта проходит граница
Часть вещей в продукте ещё не доведена, и честнее сказать об этом прямо, чем оставить в README.
Redis не даёт распределённого исполнения раундов. В сервере есть переключатель Delibera:Redis:Enabled, он регистрирует Redis-оркестратор и, опционально, кэш результатов. Но DebateWorkerService — это сознательная заглушка: раунды по воркерам не раздаются. Всё, что даёт Redis сегодня, — публикация событий раундов в Streams.
Веб-интерфейс не разворачивается на GitHub Pages. Сайт проекта статический, у него нет серверного рантайма, а UI зависит от same-origin прокси /api/delibera/**. Статический экспорт без такого прокси потребовал бы отдельного CORS-разрешённого API-хоста. Образ techbuzzz/delibera-webui существует именно для запуска рядом с Delibera.Server.
VerdictDto в веб-интерфейсе — в основном оболочка. Маппер заполняет recommendation и rawJson; confidence, riskLevel, risks и conditions не заполняются никогда. Структурированный вывод существует, но он привязан к шаблону вердикта и лежит внутри rawJson.
Operator недоступен через API. Замеры показали operatorInteractions: 0 на каждом дебате, измеренном через сервер: сервер подключает Knowledge Keeper, а не Operator. MCP-инструменты работают внутри библиотеки, но не через эту поверхность.
Удаление осиротевших векторов не реализовано. Если исходный документ уменьшился, старые точки остаются в индексе: для этого нужен filter-delete на IVectorStore, а это ломающее изменение интерфейса.
Каналы раундов не ограничены по ёмкости. Channel.CreateUnbounded всё ещё используется в локальном и Redis-оркестраторах: потребитель, который перестал читать, будет бесконечно наращивать память.
Семантика длительности попадания в кэш сбита. Для попадания в кэш TotalDuration сообщает, откуда взят результат, а не сколько ждал вызывающий. Это зафиксированное продуктовое решение, а не баг, но называть его поведением «0,0 с» стоит аккуратно.
gRPC-пакеты не входят в GA-матрицу публикации. Delibera.Grpc и Delibera.Grpc.Client существуют, но не публикуются как часть релизной линейки.
Что дальше
Роадмап короткий и в нём есть места, о которых стоит сказать вслух.
Релиз 10.6.0 — «Harden the Edges»: удаление осиротевших векторных точек, ограничение ёмкости каналов раундов, и решение по двум продуктовым вопросам — WithCache в ICouncilBuilder и семантика длительности кэша.
11.0.0 — миграция на .NET 11, когда он выйдет из preview. Это будет ломающий релиз, и переносить в него будем только то, что действительно изменилось.
Пока этого нет, мы продолжаем измерять: следующий круг замеров — по качеству вердикта и по тому, как часто совет из нескольких моделей реально даёт результат лучше одного сильного промпта. Протокол и методика — в разделе «Measured Behaviour» на сайте проекта.
В этой серии: Назад — Multi-LLM-дебаты в .NET: архитектура, компромиссы, измерения
Источники
- Репозиторий Delibera — исходный код, документация, changelog
- Сайт проекта — документация, раздел «Measured Behaviour», релизы
- Delibera.Core на NuGet — 14 версий с июня 2026
- Роадмап проекта — что выпущено, что запланировано
- Образы на Docker Hub —
techbuzzz/delibera-serverиtechbuzzz/delibera-webui
Если вы выбираете, нужен ли вашей команде совет из нескольких моделей, начните с измерений на своих задачах, а не с чтения документации. Обсудить внедрение → techbuzzz.ru



