Semantic Kernel и генеративный AI в .NET
Semantic Kernel (SK) — SDK от Microsoft для встраивания больших языковых моделей (LLM) в приложения на .NET. Типичные задачи — чат, суммаризация текста, классификация, ответы по корпоративным документам.
Рядом в экосистеме живёт ML.NET — библиотека классической машинного обучения (прогноз по таблице, классификация изображений). ML.NET и SK решают разные классы задач и часто используются в одном продукте для разных целей.
Контекст платформы — история .NET, обзор.
Словарь
| Термин | Значение |
|---|---|
| LLM | Large Language Model — модель, обученная на тексте (GPT и аналоги). |
| Prompt | Текст-инструкция для модели. |
| RAG (Retrieval-Augmented Generation) | Сначала поиск фрагментов в ваших документах, затем ответ модели по найденному контексту. |
| Embedding | Числовой вектор смысла текста; похожие тексты — близкие векторы. |
| Vector store | База для хранения и поиска embeddings. |
| Token | Единица текста для модели; от неё зависит стоимость и лимит контекста. |
| Галлюцинация | Уверенный ответ модели с выдуманными фактами. |
Когда подходит Semantic Kernel
| Задача | Инструмент |
|---|---|
| Чат-бот по документации компании | SK + RAG + vector store |
| Извлечение полей из письма | SK + prompt + function calling |
| Прогноз спроса по CSV | ML.NET |
| Расчёт цены, скидок, налогов | Код и БД; LLM — только для текста пользователю |
Критичную бизнес-логику (деньги, права доступа) держите в коде и базе. LLM — для формулировок, черновиков, поиска по тексту.
Основные части SK
- Kernel — точка входа: модель, настройки, подключённые сервисы.
- Plugins — обычные функции C#, которые модель может вызвать (получить погоду, статус заказа).
- Prompt template — шаблон с переменными
{{$input}}. - Memory / RAG — поиск релевантных фрагментов перед генерацией ответа.
Пакеты NuGet: Microsoft.SemanticKernel, коннекторы к OpenAI, Azure OpenAI, локальным моделям.
Документация — learn.microsoft.com/semantic-kernel.
Минимальный пример
using Microsoft.SemanticKernel;
var builder = Kernel.CreateBuilder();
builder.AddOpenAIChatCompletion(
modelId: "gpt-4o-mini",
apiKey: Environment.GetEnvironmentVariable("OPENAI_API_KEY")!);
var kernel = builder.Build();
var result = await kernel.InvokePromptAsync(
"Суммируй в трёх пунктах: {{$input}}",
new() { ["input"] = "Длинный текст документа..." });
Console.WriteLine(result);
Ключи API — из переменных окружения, User Secrets или Key Vault, не в git. См. безопасность C#, конфигурации.
RAG — ответ по своим документам
- Индексация — разбить документы на фрагменты (chunks), посчитать embeddings, сохранить в vector store (Azure AI Search, Qdrant, pgvector в PostgreSQL).
- Запрос пользователя — embedding вопроса, поиск top-K похожих фрагментов.
- Промпт — инструкция "отвечай только по контексту" + фрагменты + вопрос.
- Ответ — текст модели; желательно со ссылками на источники.
Риски и меры
| Риск | Мера |
|---|---|
| Галлюцинации | Жёсткий system prompt, ответ "не знаю" |
| Утечка данных в облако | Private endpoint, on-prem модель |
| Стоимость токенов | Кэш embeddings, лимиты, меньшая модель для черновика |
| PII в логах | Не логировать полный prompt с персональными данными |
PostgreSQL с pgvector — 888.
Архитектура в ASP.NET Core
Клиент → API (ASP.NET) → сервис приложения
↓
Semantic Kernel
/ | \
LLM API Plugins Vector DB
- Долгий контекст чата храните в БД или кэше, не бесконечно в памяти процесса.
- Streaming — отдавайте ответ частями (
IAsyncEnumerable, SSE) для отзывчивого UI. - Логируйте correlation id; полный prompt с PII — только в защищённом хранилище.
Веб-стек — ASP.NET, первая программа Web API.
Semantic Kernel и прямой HTTP к OpenAI
| Критерий | Semantic Kernel | HttpClient + JSON вручную |
|---|---|---|
| Плагины и цепочки шагов | Готовые абстракции | Писать самим |
| Смена провайдера (OpenAI → Azure) | Меньше переписывания | Новый клиент |
| Один простой вызов | Избыточен | Достаточно |
Для прототипа с одним запросом достаточно HTTP. Когда появляются плагины, RAG и несколько моделей — SK окупает структуру.
Частые ошибки
- LLM как единственный источник правды для цен и прав — нужна верификация по БД.
- Нет лимита на размер контекста — обрезка, summarization по частям.
- API key в
appsettings.jsonв репозитории — User Secrets / vault.
Краткая шпаргалка
| Цель | Инструмент |
|---|---|
| Чат с вызовом функций | SK Plugins |
| Ответы по документам | RAG + embeddings |
| Табличная ML | ML.NET |
| Наблюдаемость | OpenTelemetry, логи без PII |