# LLM предсказывает — остальное инженерия

Экспресс-курс о построении приложений на больших языковых моделях. 24 понятия — next-token prediction, context window, hallucination, few-shot, structured output, context engineering, RAG, embeddings, grounding, tool use, agent loop, evals, guardrails и другие — у каждого английское название, схема, карточка и пример. В конце — шпаргалка по всем понятиям и как они связаны.

- **Author:** Фёдор Чищин
- **Level:** intro
- **Reading time:** ~35 минут чтения
- **Published:** 2026-06-02
- **Source:** https://fedorthinks.com/ru/learn/building-with-llms-express

---

## 1. Что такое LLM (и что нет)

Прежде чем строить на языковой модели, пойми, что она такое на самом деле, — потому что почти любая ошибка рождается из ожидания, что она окажется тем, чем не является.

### Карта курса: 24 понятия в семи группах

> Карта метро: сначала видишь линии целиком, потом едешь по станциям.

Курс идёт от простого к сложному. Сначала — что такое **модель** и какие у неё свойства. Потом — как с ней говорить (**prompting**), что класть ей в окно (**context**), как дать ей твои факты (**RAG**), как дать ей действовать (**agents**), как сделать всё это надёжным (**reliability**) и как строить без лишнего.

_Diagram: Семь групп понятий — по ним идут главы курса._

### Как читать каждое понятие

> Паспорт: одинаковые поля у всех, поэтому их легко сравнивать.

У каждого понятия дальше одно и то же: **английское название** (это термин, по которому его ищут в документации), образ из жизни, **схема** и **карточка** с полями — что это, пример, цена или подвох, когда брать и связи с другими понятиями. Главная мысль курса одна: **модель — лёгкая часть; инженерия вокруг неё — основная работа.**

### Next-token prediction — предсказание следующего слова

> Клавиатура телефона, подсказывающая следующее слово, — но раздутая настолько, что может написать эссе, отладить код или объяснить физику, по одному правдоподобному слову за раз.

LLM — это **предсказатель следующего токена (next-token predictor)**, обученный на огромном куске человеческого текста. Она ничего не ищет; она генерирует то, что статистически вероятно дальше. Поэтому она поразительна в языке и шаблонах рассуждений — и поэтому не база фактов. **Она выдаёт то, что звучит верно, что обычно и верно, а иногда уверенно неверно.**

_Diagram: Модель оценивает варианты следующего токена, берёт вероятный, дописывает его и повторяет._

#### Next-token prediction (предсказание следующего токена)

- **Что это:** Модель генерирует текст по одному токену, выбирая вероятное продолжение.
- **Пример:** «Кошка сидела на…» → «коврике» вероятнее, чем «диване».
- **Подвох:** Это не поиск фактов: «звучит верно» ≠ «верно».
- **Что делать:** Не используй модель как базу фактов — давай ей факты сам.
- **Связи:** Отсюда растут **Hallucination** и **Non-determinism**; лечится через **RAG**.

### Context window — окно контекста, единственная память

> Блестящий консультант с полной амнезией — на каждой встрече ты заново вручаешь ему все документы, потому что с прошлого раза он не помнит ничего.

Модель не помнит ничего между запросами. Её единственная рабочая память — **окно контекста (context window)**, текст, который ты шлёшь в этом вызове. История чата, твои данные, твои инструкции: если этого нет в контексте, модель этого не знает. Весь этот курс в каком-то смысле — о том, что ты кладёшь в это окно.

_Diagram: Модель видит только то, что лежит в окне этого вызова. Чего нет в окне — того для неё нет._

#### Context window (окно контекста)

- **Что это:** Весь текст одного вызова: system prompt, история, документы, инструменты, вопрос.
- **Пример:** Чат-бот «помнит» прошлые сообщения только потому, что ты снова шлёшь их в каждом вызове.
- **Подвох:** Окно конечно, и каждый токен в нём стоит денег и времени.
- **Что делать:** Собирай окно осознанно — это и есть **Context engineering**.
- **Связи:** Наполняется через **Context engineering** и **RAG**; за его пределами живёт **Memory**.

### Hallucination — галлюцинация: уверенная выдумка

> Обаятельный всезнайка на ужине, который скорее придумает убедительный ответ, чем признается, что не знает.

Когда модель не знает, она не останавливается — она **галлюцинирует (hallucination)**, выдавая гладкий, правдоподобный, неверный текст с той же уверенностью, что и правду. Это не баг, который можно целиком залатать; это природа угадывателя. **Бóльшая часть инженерии в этом курсе существует, чтобы управлять этим одним фактом.**

_Diagram: Правда и выдумка выходят из модели одинаково уверенными — по тону их не отличить._

#### Hallucination (галлюцинация)

- **Что это:** Гладкий, правдоподобный, но неверный ответ, сказанный уверенно.
- **Пример:** Просишь источник — модель выдаёт ссылку на статью, которой не существует.
- **Подвох:** Убрать целиком нельзя: это природа next-token prediction.
- **Что делать:** Ограничивать, где она может случиться, ловить, когда случилась, — см. главу 6.
- **Связи:** Снижают **Grounding** и **RAG**; ловят **Guardrails** и **Evals**.

### Non-determinism — недетерминированность: каждый раз по-разному

> Задай один и тот же вопрос десяти экспертам — получишь десять слегка разных хороших ответов, а не один идентичный.

Один и тот же промпт может каждый раз давать разный вывод — это **недетерминированность (non-determinism)**. Поэтому нельзя относиться к LLM как к функции с фиксированным возвратом; относись к ней как к **умному, ошибающемуся, недетерминированному входу** — который надо ограничивать, валидировать и проверять, а не слепо доверять. Этот настрой — и есть вся игра.

_Diagram: Три вызова с одним промптом — три немного разных ответа. Поэтому вывод всегда проверяют._

#### Non-determinism (недетерминированность)

- **Что это:** Один и тот же вход может дать разный выход.
- **Пример:** Дважды просишь резюме письма — получаешь два разных текста.
- **Подвох:** Обычные юнит-тесты «равно / не равно» тут ломаются.
- **Что делать:** Ограничивай формат (**Structured output**), валидируй, измеряй качество (**Evals**).
- **Связи:** Причина, по которой нужны **Evals** и **Guardrails**.

> **Прежде чем строить:** «Я отношусь к этому как к надёжной функции — или как к блестящему, забывчивому, иногда привирающему стажёру?»

> LLM не знает вещей. Она их предсказывает. Всё остальное строй вокруг этой одной истины.

## 2. Промпт

Промпт — это то, как ты говоришь модели, чего хочешь. Чем яснее инструкция, тем лучше вывод — и большинство моментов «AI тупой» на деле — это нечёткие промпты.

### Prompt — промпт: бриф, а не заклинание

> Передача задачи толковому новичку: кем он выступает, чего ты хочешь, ограничения и пример «хорошего». Расплывчатый бриф — расплывчатый результат.

Хороший **промпт (prompt)** задаёт **роль (role)** («ты внимательный редактор»), **задачу (task)**, **ограничения (constraints)** — длина, тон, формат — и в идеале **пример (example)**. Волшебных слов нет — только ясные инструкции, те же, что ты дал бы способному человеку. Большинство проблем с промптами — на самом деле проблемы спецификации.

_Diagram: Четыре части хорошего брифа: роль, задача, ограничения, пример._

#### Prompt (промпт, бриф)

- **Проблема:** Расплывчатая просьба → расплывчатый ответ, и кажется, что «AI тупой».
- **Идея:** Писать промпт как бриф: роль, задача, ограничения, пример.
- **Пример:** «Ты внимательный редактор. Сократи этот тикет до 3 пунктов, простым языком. Вот пример хорошего результата: …»
- **Цена:** Почти ноль — нужно только ясно думать, чего ты хочешь.
- **Когда брать:** Всегда. Это первая ступень лестницы.
- **Связи:** Делится на **System prompt** и user prompt; усиливается **Few-shot** примерами.

### System prompt vs user prompt — постоянные правила против запроса

> Постоянная политика ресторана — «мы вегетарианские, закрываемся в десять» — против конкретного заказа на сегодня. Одно задаёт рамку всему; другое — сам запрос.

**System-промпт (system prompt)** задаёт устойчивое поведение — роль, правила, тон, — которое держится через весь разговор. **User-промпт (user prompt)** — это конкретный запрос. Положив персону и guardrails в system-промпт, ты держишь их стабильными, пока сообщения пользователя меняются.

_Diagram: System-промпт — рамка для всех ходов; user-промпт меняется каждый ход._

#### System prompt (системный промпт)

- **Что это:** Постоянные инструкции для всего разговора: роль, правила, тон.
- **Пример:** System: «Ты бот поддержки магазина. Отвечай коротко, не обещай возвратов сверх политики». User: «Где мой заказ?»
- **Подвох:** Это не замок: пользователь может пытаться его обойти — нужны ещё **Guardrails**.
- **Когда брать:** Всё, что должно быть стабильным между ходами, — сюда.
- **Связи:** Часть **Prompt**; лежит в начале **Context window**.

### Few-shot prompting — показывай, а не только рассказывай

> Научить кого-то формату, показав три готовых примера, быстрее и яснее, чем описывать его словами.

Часто лучший способ получить нужную форму ответа — **включить несколько примеров** входа и желаемого выхода прямо в промпт. Это и есть **few-shot prompting**. Модель распознаёт их шаблон лучше, чем следует абстрактному описанию. Два-три хороших примера могут побить абзац инструкций.

_Diagram: Два примера «вход → выход» в промпте — и модель продолжает тот же шаблон для нового входа._

#### Few-shot prompting (обучение на примерах в промпте)

- **Проблема:** Формат или стиль трудно описать словами.
- **Идея:** Показать 2–3 пары «вход → желаемый выход» прямо в промпте.
- **Пример:** «“Опять опоздали!” → negative; “Обожаю” → positive; “Работает нормально” → ?»
- **Цена:** Примеры занимают место в окне; плохой пример научит плохому.
- **Когда брать:** Когда нужна точная форма, тон или классификация.
- **Связи:** Часть **Prompt**; часто вместе со **Structured output**.

### Structured output — структурированный вывод, который сможет использовать код

> Форма с подписанными полями даёт заполняемые данные; «напиши абзац про это» даёт прозу, которую потом ещё надо парсить.

Если твоя программа будет потреблять вывод, проси **структурированный вывод (structured output)** — JSON по схеме, а не свободный текст. Современные модели можно ограничить валидным JSON, превращая LLM из чат-бота в компонент, на который код может опираться. **Структурированный вывод — это мост между языком и софтом.**

_Diagram: Свободный текст приходится парсить наугад; JSON по схеме можно проверить и сразу отдать коду._

#### Structured output (структурированный вывод, JSON mode)

- **Проблема:** Код не может надёжно разобрать свободную прозу.
- **Идея:** Ограничить ответ JSON-схемой и проверить его перед использованием.
- **Пример:** `{"order_id": 42, "status": "late"}` вместо «Ваш заказ 42 опаздывает…».
- **Цена:** Нужно описать схему и обработать случай, когда проверка не прошла.
- **Когда брать:** Всегда, когда ответ читает программа, а не человек.
- **Связи:** Основа **Tool use** (вызов инструмента — это структурированный вывод); слой защиты от **Hallucination**.

> **Вопрос про промпт:** «Выдал бы умный незнакомец, получив ровно этот промпт и ничего больше, то, что мне нужно?»

> Волшебных слов нет. Хороший промпт — это ясный бриф: роль, задача, ограничения, примеры.

## 3. От промптов к контексту

Когда приложения становятся серьёзными, ремесло смещается с формулировки промпта на сборку правильного контекста. Это и есть настоящая дисциплина — «инженерия контекста».

### Context engineering — инженерия контекста

> Юрист выигрывает не хитрой формулировкой, а тем, что вручает судье ровно нужные документы, в нужном порядке и без всего лишнего.

«Инженерия промптов» (**prompt engineering**) была про формулировку; **инженерия контекста (context engineering)** — про сборку правильной информации (релевантных фактов, истории и инструментов) в окно для каждого вызова. Ответ модели хорош ровно настолько, насколько хорошо то, что ты положил перед ней. **Большинство проблем качества — это проблемы контекста, а не формулировки.**

_Diagram: Из многих источников выбирается нужное и собирается в окно — для каждого вызова заново._

#### Context engineering (инженерия контекста)

- **Проблема:** Модель отвечает плохо, хотя промпт сформулирован хорошо.
- **Идея:** Для каждого вызова собирать в окно ровно то, что нужно: инструкции, факты, историю, инструменты.
- **Пример:** Бот поддержки получает не всю базу знаний, а политику возвратов, статус заказа и вопрос клиента.
- **Цена:** Нужен код, который выбирает и собирает контекст, — это и есть работа.
- **Когда брать:** Как только приложение больше одного простого промпта.
- **Связи:** Наполняет **Context window**; главный поставщик фактов — **RAG**; ограничен **Context budget**.

### Relevance over completeness — релевантность важнее полноты

> Бриф на одну острую страницу бьёт свалку из 200 страниц — читатель находит сигнал, а не тонет в нём.

Больше контекста — не лучше. Каждый токен должен заслужить своё место: нерелевантный текст размывает внимание модели, стоит денег и **реально повышает шанс галлюцинации** в длинных контекстах. Мастерство — выбрать те немногие вещи, что важны, а не напихать всё, что может пригодиться.

_Diagram: Слева: окно забито, нужное тонет в шуме. Справа: только то, что нужно для ответа._

### Context budget — окно контекста как бюджет

> Чемодан с лимитом веса — ты кладёшь то, что реально понадобится, а не весь гардероб, потому что есть жёсткий потолок и штраф.

Окно конечно, и каждый токен стоит задержки и денег. Поэтому ты тратишь его осознанно, как **бюджет (context budget)**: подрезаешь историю, суммируешь старое, достаёшь только то, что релевантно сейчас. **Относиться к контексту как к дефицитному бюджету, а не бесконечной свалке, — вот что отличает игрушку от продукта.**

_Diagram: Окно делится между частями и упирается в жёсткий лимит. Четыре рычага: подрезать, сжать, доставать нужное, кэшировать._

#### Context budget (бюджет контекста, token budget)

- **Что это:** Лимит токенов окна, который делят system prompt, история, факты и ответ.
- **Пример:** Длинный чат: старые ходы сжимаются в краткое резюме, а не шлются целиком каждый раз.
- **Подвох:** Больше токенов — дороже, медленнее и не обязательно лучше.
- **Что делать:** Trim, summarize, retrieve только нужное, cache стабильную часть.
- **Связи:** Ограничивает **Context engineering**; напрямую влияет на **Cost & latency**.

> **Вопрос про контекст:** «Всё в этом окне заслуживает своё место — или я сваливаю текст и надеюсь?»

> Инженерия промптов — это формулировка. Инженерия контекста — это документы. Качество живёт во втором.

## 4. Дать ей факты

Модель не знает твоих данных и ничего после своей даты обучения. RAG — это как вручить ей факты, из которых отвечать, — самый важный паттерн в серьёзных LLM-приложениях.

### RAG — Retrieval-Augmented Generation: сначала достань, потом отвечай

> Экзамен с открытой книгой — вместо того чтобы полагаться на память, ты сперва находишь нужные страницы, а потом пишешь ответ по тому, что перед тобой.

**Retrieval-Augmented Generation (RAG)** означает: взять вопрос пользователя, **достать самые релевантные куски** твоих документов, положить их в контекст и попросить модель ответить из них. Теперь она работает с твоими реальными данными, а не с расплывчатой памятью. Так ассистенты отвечают про твой продукт, твою документацию, твою базу знаний.

_Diagram: Вопрос → поиск по твоим документам → лучшие куски вместе с вопросом идут в промпт → ответ со ссылками._

#### RAG (Retrieval-Augmented Generation)

- **Проблема:** Модель не знает твоих данных и ничего после даты обучения — и выдумывает.
- **Идея:** Сначала найти нужные куски документов, потом отвечать только из них.
- **Пример:** Бот документации находит 3 подходящих раздела справки и отвечает по ним со ссылками.
- **Цена:** Нужны нарезка, индекс, поиск — и их качество надо измерять.
- **Когда брать:** Когда ответ должен опираться на твои данные или свежие факты.
- **Связи:** Работает на **Embeddings**; даёт **Grounding**; кормит **Context engineering**.

### Embeddings — векторный поиск по смыслу

> Библиотекарь, который находит книги по тому, о чём они, а не по точному заголовку, — «что-то вроде этого», по смыслу.

Чтобы найти релевантные куски, ты хранишь документы как **embeddings** (векторы, которые описывают смысл текста) в **векторной базе (vector database)** и ищешь по сходству с вопросом (движок из курса по базам данных). Хорошая выборка — сердце RAG: положи правильные куски — и ответ заземлён; положи мусор — и модель уверенно отвечает из мусора.

_Diagram: Тексты с похожим смыслом лежат рядом. Поиск — это «найти ближайших соседей» вопроса._

#### Embeddings (векторные представления, vector search)

- **Что это:** Текст → вектор чисел; близкие по смыслу тексты — близкие векторы.
- **Пример:** Вопрос «как вернуть деньги?» находит раздел «Политика возвратов», хотя общих слов почти нет.
- **Подвох:** Похожесть по смыслу не гарантирует, что кусок отвечает на вопрос.
- **Когда брать:** Для поиска по смыслу в RAG, а не по точным словам.
- **Связи:** Двигатель **RAG**; качество зависит от **Chunking**.

### Grounding — заземление: ответ со ссылкой на источник

> Журналист, обязанный приводить источник под каждое утверждение, выдумывает куда меньше, чем тот, кто пишет по памяти.

Главный выигрыш RAG — **заземление (grounding)**: раз ответ извлечён из найденного текста, можно требовать **ссылок (citations)** и проверять, что утверждения реально подкреплены. Это не стирает галлюцинацию, но резко её срезает — и даёт ловить то, что проскочило. **Ответу, который ты можешь возвести к источнику, можно доверять.**

_Diagram: Каждое утверждение ведёт к источнику. Утверждение без источника — сигнал: пометить или убрать._

#### Grounding (заземление, citations)

- **Проблема:** Нельзя проверить, откуда модель взяла утверждение.
- **Идея:** Отвечать только из найденного текста и ставить ссылку под каждый факт.
- **Пример:** «Возврат в течение 30 дней [1]» — где [1] = `refund-policy.md`.
- **Цена:** Нужно проверять ссылки; ответы становятся осторожнее.
- **Когда брать:** Везде, где ошибаться дорого: деньги, право, здоровье, поддержка.
- **Связи:** Результат **RAG**; главный слой защиты от **Hallucination**.

### Chunking & retrieval quality — мусор на входе, уверенный мусор на выходе

> Дай человеку не тот файл и попроси резюмировать — он выдаст идеальное резюме не того.

RAG работает, только если работает выборка. Плохая **нарезка (chunking)**, слабый поиск, устаревшие данные — и модель добросовестно отвечает из неправильного контекста, звуча так же уверенно. Поэтому бóльшая часть работы в RAG — не модель, а **нарезка, индексация и измерение качества выборки.** Чини выборку, прежде чем винить модель.

_Diagram: Сломаться может любой шаг до модели — и итог всё равно звучит уверенно._

#### Chunking & retrieval quality (нарезка и качество выборки)

- **Проблема:** Модель уверенно отвечает из неправильных кусков.
- **Идея:** Правильно резать документы, держать индекс свежим и отдельно мерить, находит ли поиск нужное.
- **Пример:** Таблица тарифов разрезана пополам — модель видит цены без названий тарифов и путается.
- **Цена:** Скучная работа с данными, которая занимает бóльшую часть RAG.
- **Когда брать:** Всегда, когда есть RAG. Сначала чини выборку, потом модель.
- **Связи:** Определяет качество **RAG** и **Embeddings**; проверяется **Evals**.

> **Вопрос про RAG:** «Модель отвечает из извлечённых фактов со ссылками — или из своей расплывчатой памяти?»

> Не спрашивай модель, что она знает. Вручи ей факты и попроси отвечать из них.

## 5. Инструменты и агенты

Промпт выдаёт текст. Чтобы модель что-то делала — искала, считала, отправляла, смотрела, — ты даёшь ей инструменты; чтобы она шла к цели через много шагов, ты ставишь её в цикл. Это и есть агент.

### Tool use — function calling: дай ей звать твои функции

> Умный ассистент, который сам не дотянется до картотеки, — но может попросить тебя и точно указать, какой файл достать.

При **использовании инструментов (tool use, function calling)** ты описываешь функции, которые модель может запросить, — `search_orders`, `send_email`, `get_weather`, — и когда она хочет одну, она возвращает структурированный вызов, твой код его выполняет, и ты подаёшь результат назад. Модель решает, _что_ делать; твой код держит контроль над тем, _как_ это делается. **Так LLM дотягивается за пределы текста в реальный мир.**

_Diagram: Модель только просит вызвать инструмент. Выполняет его твой код — и возвращает результат модели._

#### Tool use (function calling, вызов инструментов)

- **Проблема:** Текстом нельзя проверить заказ, посчитать или отправить письмо.
- **Идея:** Описать функции; модель возвращает структурированный вызов; код выполняет и отдаёт результат.
- **Пример:** «Где мой заказ 42?» → модель просит `search_orders(42)` → код зовёт API → модель отвечает.
- **Цена:** Каждый инструмент — новая возможность ошибиться в реальном мире.
- **Когда брать:** Когда ответу нужны живые данные или действие.
- **Связи:** Построен на **Structured output**; из него собирается **Agent loop**.

### Agent loop — агент: модель в цикле

> Человек, решающий задачу: подумать, сделать действие, посмотреть на результат, снова подумать — повторяя, пока не готово, а не за один раз.

**Агент (agent)** вшивает модель в цикл — рассуждай, вызови инструмент, наблюдай результат, рассуждай снова (**agent loop**) — где LLM как дирижёр решает каждый следующий шаг. Это даёт ей справляться с открытыми задачами («исследуй это и набросай ответ»), которые не осилил бы один промпт. Кодинг-ассистенты и исследовательские боты работают так.

_Diagram: Reason → Act → Observe, и снова — пока цель не достигнута._

#### Agent loop (агент, цикл агента)

- **Проблема:** Задачу не решить за один шаг: нужно искать, пробовать, исправлять.
- **Идея:** Модель в цикле «подумать → действовать → посмотреть», сама выбирает шаг.
- **Пример:** Кодинг-ассистент: читает файл, правит, запускает тесты, видит ошибку, правит снова.
- **Цена:** Непредсказуем: может уйти не туда, зациклиться, нагнать стоимость.
- **Когда брать:** Только когда задаче правда нужно много адаптивных шагов. Иначе — один вызов или фиксированная цепочка.
- **Связи:** Состоит из **Tool use**; нужны **Memory** и **Human-in-the-loop**.

### Memory — память за пределами окна

> Долгому проекту нужен блокнот — нельзя держать месяцы работы в голове, поэтому ты записываешь важное и снова в него заглядываешь.

Раз окно конечно, агентам нужна **память (memory)**: заметки, сводки и извлекаемая история, хранимые вне контекста и подтягиваемые назад, когда релевантны. Без неё агент к концу длинной задачи забывает её начало. Память — это то, что превращает чат в нечто, способное работать во времени.

_Diagram: Агент записывает важное во внешнее хранилище и достаёт оттуда только то, что нужно сейчас._

#### Agent memory (память агента)

- **Проблема:** Длинная задача не влезает в окно — агент забывает начало.
- **Идея:** Хранить заметки и сводки вне окна и подтягивать нужное по запросу.
- **Пример:** Агент после каждого этапа пишет «что сделано, что дальше» и читает это на следующем шаге.
- **Цена:** Ещё одна система: что записывать, что доставать, что забывать.
- **Когда брать:** Для задач дольше, чем помещается в одно окно.
- **Связи:** Расширяет **Context window**; достаётся так же, как в **RAG**; нужна **Agent loop**.

### Human-in-the-loop — циклы мощны и опасны: держи на поводке

> Робот-пылесос, который в основном убирает дом, но иногда застревает, крутясь в углу, или забредает в бассейн.

Цикл агента непредсказуем: он может свернуть не туда, зациклиться, нагнать стоимость или действовать по плохому решению. Поэтому держи его на поводке — **лимиты шагов (step limits), права на инструменты (tool permissions), одобрение человека (human-in-the-loop) для рискованных действий, полное логирование.** Тянись за агентом, только когда задаче правда нужно много адаптивных шагов; один вызов или фиксированная цепочка дешевле и безопаснее, когда их хватает.

_Diagram: Поводок агента: лимит шагов, список разрешённых инструментов, логи и человек перед рискованным действием._

#### Human-in-the-loop (одобрение человеком, поводок агента)

- **Проблема:** Агент может сделать дорогое или необратимое действие по ошибке.
- **Идея:** Лимит шагов, разрешённые инструменты, логи — и человек подтверждает рискованные действия.
- **Пример:** Агент готовит возврат денег, но отправляет его только после клика оператора.
- **Цена:** Медленнее и требует людей — зато ошибка не уходит в мир.
- **Когда брать:** Перед любым действием, которое дорого или нельзя отменить.
- **Связи:** Ограничивает **Agent loop** и **Tool use**; родственник **Guardrails**.

> **Вопрос про агента:** «Этому правда нужен адаптивный многошаговый цикл — или один вызов либо фиксированная цепочка сделают работу безопаснее?»

> Инструменты дают модели действовать. Цикл даёт ей упорствовать. И тому, и другому нужен поводок — возможности без ограничений опасны.

## 6. Сделать это надёжным

Демо, которое сработало один раз, — легко. Система, которой можно доверять, требует неблагодарной работы: измерять, ограничивать и наблюдать за компонентом, недетерминированным по природе.

### Evals — эвалы: нельзя улучшить то, что не измеряешь

> Школа, которая никого не оценивает, понятия не имеет, кто учится, — и не может стать лучше.

**Эвал (eval)** — это набор тестов для твоего AI: входы с известными ожиданиями, оцениваемые автоматически: достал ли он нужные документы, вызвал ли нужный инструмент, ответил ли верно? Без эвалов ты крутишь промпты на ощущениях. И жди суровую правду: **дойти до 80% качества быстро; домолоть оттуда до 95% — это бóльшая часть работы.**

_Diagram: Набор тестов → система → автоматическая оценка. Поменял промпт — прогнал снова и сравнил._

#### Evals (эвалы, оценка качества)

- **Проблема:** Непонятно, стало лучше или хуже после правки промпта.
- **Идея:** Набор входов с ожидаемыми результатами и автоматический счёт качества.
- **Пример:** 50 реальных вопросов в поддержку: проверяем, нашёлся ли нужный документ и верен ли ответ.
- **Цена:** Нужно собрать и поддерживать набор — это постоянная работа.
- **Когда брать:** До того как начнёшь крутить промпты. Без эвала — «на ощущениях».
- **Связи:** Ответ на **Non-determinism**; измеряет **RAG**, **Tool use**, **Agent loop**.

### Guardrails — границы на входе и выходе

> Бортики на дорожке боулинга — они не катят шар за тебя, но держат его из жёлоба.

**Guardrails** — это проверки вокруг модели: на входе — блокировать **prompt injection** и запросы вне темы; на выходе — фильтровать небезопасный контент и валидировать формат, прежде чем он дойдёт до пользователя или другой системы. Они работают до и после модели, в твоём коде, — потому что нельзя доверить модели надзор за собой.

_Diagram: Проверка на входе и проверка на выходе — в твоём коде, по обе стороны от модели._

#### Guardrails (ограждения, проверки на входе и выходе)

- **Проблема:** Модель нельзя заставить надёжно следить за собой.
- **Идея:** Проверять вход до модели и выход после — обычным кодом.
- **Пример:** Вход: отсечь «забудь все инструкции и…». Выход: проверить JSON по схеме и убрать опасный текст.
- **Цена:** Лишняя задержка и ложные срабатывания.
- **Когда брать:** Всегда в продакшене, особенно если вывод уходит людям или в системы.
- **Связи:** Дополняет **System prompt**; проверяет **Structured output**; ловит **Hallucination**.

### Cost & latency — стоимость и задержка как проектные ограничения

> Таксометр, тикающий всю поездку, — каждая лишняя миля контекста, каждый лишний шаг добавляют к счёту и к ожиданию.

Каждый токен стоит денег и времени, и **стоимость растёт с тем, сколько контекста ты шлёшь** и сколько делаешь вызовов. Поэтому ты проектируешь под это: подрезаешь и кэшируешь контекст, берёшь наименьшую достаточно хорошую модель и не гоняешь цикл агента там, где работает один вызов. Отличный ответ, который слишком медленный или дорогой, — не отличный ответ.

_Diagram: Цена ≈ токены за вызов × число вызовов. Четыре рычага, чтобы её снизить._

#### Cost & latency (стоимость и задержка)

- **Что это:** Деньги и время за каждый вызов; растут с контекстом и числом вызовов.
- **Пример:** Слать всю базу знаний в каждый вызов или гонять агента там, где хватит одного вызова, — дорого и медленно.
- **Подвох:** Отличный, но медленный или дорогой ответ — не отличный ответ.
- **Что делать:** Подрезать и кэшировать контекст, брать наименьшую достаточную модель, меньше вызовов.
- **Связи:** Растёт от **Agent loop**; управляется через **Context budget**.

### Hallucination defense — галлюцинация как риск, вокруг которого проектируешь

> Ты не даёшь блестящему, но ненадёжному рассказчику микрофон без присмотра — ты проверяешь факты, прежде чем это уйдёт в печать.

Каждый приём отсюда — заземление через RAG, структурированный вывод, эвалы, guardrails, ссылки — существует, чтобы управлять одним ключевым риском: **модель убедительно заявляет ложь.** Ты никогда не убираешь его целиком; ты ограничиваешь, где он может случиться, ловишь, когда случается, и не даёшь непроверенному утверждению дойти туда, где ошибаться дорого. Это защита слоями (**defense in depth**): каждый слой ловит часть ошибок.

_Diagram: Слои защиты: каждый ловит часть ложных утверждений, до пользователя доходит проверенное._

> **Вопрос про надёжность:** «Как я измеряю, что это верно, ограничиваю, где может пойти не так, и ловлю, когда пошло?»

> Демо доверяет модели. Продукт её измеряет, ограничивает и наблюдает — потому что она недетерминирована по природе.

## 7. Строить хорошо

Паттерны складываются от простого к сложному. Мастерство — использовать наименее мощный, который решает твою задачу, и относиться к модели как к компоненту, а не как к архитектуре.

### Complexity ladder — поднимайся по лестнице ровно настолько, насколько нужно

> Ты не заказываешь грузовик для переезда, чтобы перенести одну коробку через комнату. Ты соразмеряешь усилие с задачей.

Есть лестница: **один хороший промпт**, потом **структурированный вывод**, потом **RAG**, когда нужны твои факты, потом **инструменты**, потом полный **цикл агента**, когда задаче правда нужно много адаптивных шагов. Каждая ступень добавляет мощь, стоимость и новые способы сломаться. **Начинай снизу и поднимайся, только когда задача вынуждает,** — большинству фич верх не нужен никогда.

_Diagram: Пять ступеней: каждая выше — мощнее, дороже и хрупче. Начинай с первой._

#### Complexity ladder (лестница сложности)

- **Проблема:** Тянет сразу строить агента, хотя хватило бы промпта.
- **Идея:** Prompt → Structured output → RAG → Tools → Agent loop; выше — только по нужде.
- **Пример:** Классификация тикетов: хватает промпта со structured output — RAG и агент не нужны.
- **Цена:** Каждая ступень — больше стоимости и новых способов сломаться.
- **Когда брать:** При выборе подхода к любой LLM-фиче.
- **Связи:** Связывает **Prompt**, **Structured output**, **RAG**, **Tool use**, **Agent loop**.

### LLM as a component — модель как компонент, а не архитектура

> У машины мощный двигатель, но он прикручен за перегородкой, кормится чистым топливом и окружён тормозами, — он не вся машина.

Поставь модель **за интерфейс (interface)**, как любую другую зависимость, с валидацией вокруг её входов и выходов и свободой подменить модель или провайдера. LLM — это одна мощная, ненадёжная часть твоей системы, а не её фундамент. (Тот же урок «LLM как адаптер, а не архитектура» из дизайна систем.)

_Diagram: Приложение говорит с интерфейсом; провайдеры подключаются адаптерами; вход и выход проверяются._

#### LLM as a component (модель за интерфейсом, LLM as an adapter)

- **Проблема:** Код намертво привязан к одной модели и доверяет её ответу напрямую.
- **Идея:** Модель за своим интерфейсом, с проверками на входе и выходе.
- **Пример:** Приложение зовёт `complete(prompt)`; за ним можно подменить провайдера A на B или локальную модель.
- **Цена:** Небольшой слой абстракции.
- **Когда брать:** Всегда — с первого дня.
- **Связи:** Использует **Structured output** и **Guardrails**; та же идея, что Hexagonal (ports and adapters).

### Как всё связано

> Оркестр: инструменты разные, но звучат вместе, и каждый поддерживает другого.

Понятия курса не живут поодиночке. **Embeddings** дают поиск для **RAG**; RAG поставляет факты в **Context engineering**, а та наполняет **Context window**. RAG даёт **Grounding**, а grounding, **Guardrails** и **Evals** вместе держат под контролем **Hallucination**. **Structured output** — основа **Tool use**, из инструментов собирается **Agent loop**, а **Memory** продлевает его жизнь.

_Diagram: Главные связи между понятиями курса._

#### Прежде чем выкатывать LLM-фичу

- **Какая самая простая ступень** — промпт, структурированный вывод, RAG, инструменты, агент — решает это?
- **Откуда берутся факты** — из памяти модели (рискованно) или из извлечённых данных со ссылками?
- **Что будет, когда она ошибётся**, и это место дёшево или дорого ошибаться?
- **Как я буду мерить качество** — что за эвал?
- **Какие guardrails** на входе и выходе?
- **Сколько это стоит** за вызов и насколько медленно?

#### Признаки, что ты перестроил

- **Цикл агента** для того, на что ответил бы один промпт.
- **RAG** над тремя документами, которые можно было просто вставить в промпт.
- Кручение промптов **на ощущениях**, без эвала, который скажет, стало ли лучше.
- Отправка **всей базы знаний** в контекст на каждый вызов.
- Доверие выводу модели **прямо в базу или в письмо**, без валидации.

#### Признаки, что ты построил хорошо

- Вывод **структурирован и провалидирован**, прежде чем код его использует.
- Ответы **заземлены и со ссылками**, а не взяты из воздуха.
- У тебя есть **эвал**, который говорит, помогает изменение или вредит.
- **Guardrails** стоят и на входе, и на выходе.
- Ты использовал **самую простую ступень**, которая работает, — и модель сидит за интерфейсом, который можно подменить.

## Шпаргалка: все 24 понятия

### Модель

- **Next-token prediction** (предсказание следующего токена): Модель генерирует вероятное продолжение, а не ищет факты.
- **Context window** (окно контекста): Единственная память модели — текст этого вызова.
- **Hallucination** (галлюцинация): Уверенная правдоподобная выдумка. Убрать нельзя, можно ограничить.
- **Non-determinism** (недетерминированность): Один вход — разные выходы. Поэтому проверяй и измеряй.

### Промпт

- **Prompt** (промпт, бриф): Ясный бриф: роль, задача, ограничения, пример.
- **System prompt** (системный промпт): Постоянные правила на весь разговор; user prompt — конкретный запрос.
- **Few-shot prompting** (примеры в промпте): 2–3 примера «вход → выход» вместо абзаца объяснений.
- **Structured output** (JSON по схеме): Ответ в форме, которую код может проверить и использовать.

### Контекст

- **Context engineering** (инженерия контекста): Собрать в окно ровно нужное для каждого вызова.
- **Relevance over completeness** (релевантность важнее полноты): Лишний текст размывает внимание и повышает шанс галлюцинации.
- **Context budget** (бюджет контекста): Окно — дефицитный бюджет: подрезать, сжимать, кэшировать.

### Факты (RAG)

- **RAG** (Retrieval-Augmented Generation): Сначала найти нужные куски документов, потом ответить из них.
- **Embeddings** (векторный поиск): Поиск по смыслу: близкие тексты — близкие векторы.
- **Grounding** (заземление, ссылки): Каждое утверждение ведёт к источнику — его можно проверить.
- **Chunking & retrieval quality** (нарезка и качество выборки): Мусор на входе — уверенный мусор на выходе. Чини выборку первой.

### Агенты

- **Tool use** (function calling): Модель просит вызвать функцию, твой код выполняет.
- **Agent loop** (агент): Модель в цикле «подумать → действовать → посмотреть».
- **Agent memory** (память агента): Заметки и сводки вне окна, подтягиваются по нужде.
- **Human-in-the-loop** (поводок агента): Лимиты шагов, права, логи и человек перед рискованным действием.

### Надёжность

- **Evals** (эвалы): Тесты для AI: без них — настройка на ощущениях.
- **Guardrails** (проверки на входе и выходе): Код до и после модели: блокирует, фильтрует, валидирует.
- **Cost & latency** (стоимость и задержка): Токены × вызовы. Проектное ограничение, а не мелочь.

### Строить хорошо

- **Complexity ladder** (лестница сложности): Промпт → structured output → RAG → tools → agent. Выше — только по нужде.
- **LLM as a component** (модель за интерфейсом): Модель — заменяемая часть системы, а не её фундамент.

> Построение на LLM — не магия промптов. Это обычная инженерия — контекст, выборка, валидация, эвалы — вокруг необычного, ненадёжного компонента.

Конец экспресс-курса · 7 глав · 24 понятия

Дальше — практика: читай документацию своего провайдера моделей — гайды Anthropic и OpenAI по промптингу, инструментам и эвалам — и собери что-то небольшое от начала до конца: промпт, потом RAG, потом инструмент. Но держи одну мысль выше прочих. Модель — лёгкая часть. Инженерия вокруг неё — контекст, заземление, измерение, ограничения — это то, где делается настоящий продукт.
