Каждый второй заказчик приходит с запросом "нам нужен AI-агент". На вопрос "а что именно он должен делать?" обычно следует пауза и что-то вроде "ну, чтобы как ChatGPT, но наш, и чтобы работал".
Окей.
Проблема в том, что между "чат-ботом с GPT" и "AI-агентом" — пропасть размером примерно в полгода разработки и массу седых волос. И нет, дело не в том, что агент — это какая-то магия. Дело в том, что это инженерная система со своей архитектурой, компонентами и подводными камнями.
Эта статья — попытка разложить по полочкам, из чего состоит AI-агент. Без маркетингового булшита про "революцию в бизнесе" и "цифровую трансформацию". Просто архитектура, компоненты, код, грабли.
Оглавление
Сначала договоримся о терминах
Архитектура: что внутри
Память: почему агент не забывает (спойлер: забывает)
Docling: как скормить агенту PDF и не сойти с ума
Embeddings: как превратить текст в числа
Векторные базы: где всё это хранить
LLM: мозг, который иногда галлюцинирует
RAG: как не скормить модели всю базу знаний
Графы состояний: чтобы агент не ушёл в бесконечный цикл
Tools: руки агента (и почему их нужно контролировать)
Итоговая таблица для тех, кто листал до конца
1. Сначала договоримся о терминах
Потому что терминологический хаос в этой области — отдельный вид искусства.
Чат-бот — штука, которая принимает сообщение и возвращает ответ. Stateless или почти stateless. Классика: пользователь спрашивает "как оформить возврат?", бот отвечает инструкцией. Всё. На следующий вопрос он уже не помнит, что вы вообще существуете.
AI-агент — штука, которая получает задачу и пытается её выполнить. Сама. Используя инструменты, память, логику переходов между состояниями. Может сходить в CRM, вытащить данные, сгенерировать письмо, отправить его, поставить задачу менеджеру и отчитаться.
Разница примерно как между калькулятором и Excel. Калькулятор считает то, что ты ввёл. Excel может запустить макрос, который сходит в базу, обработает данные и пришлёт тебе отчёт на почту (если ты, конечно, осилил VBA и не сломал себе психику).
Пример для наглядности:
Задача: "Найди клиентов, которые не отвечали неделю, и напомни им о себе"
Чат-бот:
User: Найди клиентов без ответа 7 дней
Bot: Я языковая модель и не имею доступа к вашей CRM.
Вот пример SQL-запроса, который может помочь...
User: *закрывает вкладку, идёт делать руками*
Агент:
User: Найди клиентов без ответа 7 дней
Agent: [подключается к CRM API]
Agent: [находит 12 клиентов]
Agent: [для каждого генерирует персональное письмо]
Agent: [отправляет через email API]
Agent: [создаёт задачу в Trello: "проверить отклики через 2 дня"]
Agent: Готово. Отправил 12 писем. Задача создана.
Первый консультирует. Второй делает. Вот и вся разница.
2. Архитектура: что внутри
Типичный агент — это не один компонент, а оркестр из нескольких систем, которые как-то должны работать вместе.
┌───────────────────────────────────���─────────────────────────┐
│ AI AGENT │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ MEMORY │◄────────►│ LLM │ │
│ │ │ │ (мозги) │ │
│ │ • Short-term│ │ │ │
│ │ • Long-term │ │ DeepSeek/ │ │
│ │ • Episodic │ │ Qwen/Kimi │ │
│ └─────────────┘ └─────────────┘ │
│ ▲ ▲ │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ VECTOR DB │ │ STATE GRAPH │ │
│ │ │ │ │ │
│ │ Qdrant/ │ │ "что делать │ │
│ │ Pinecone │ │ дальше?" │ │
│ └─────────────┘ └─────────────┘ │
│ ▲ │ │
│ │ ▼ │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ EMBEDDINGS │ │ TOOLS │ │
│ │ │ │ │ │
│ │ BGE-M3/Jina │ │ • CRM API │ │
│ │ │ │ • Email │ │
│ └─────────────┘ │ • Docling │ │
│ ▲ └─────────────┘ │
│ │ │
│ ┌─────────────┐ │
│ │ DOCLING │ ← PDF/DOCX/PPTX → Markdown │
│ └─────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
Компоненты:
LLM — собственно, "мозг". Принимает решения, генерирует текст, выбирает какой инструмент вызвать.
Memory — память. Чтобы агент помнил, что было на прошлой неделе, а не только в текущем промпте.
Embeddings — способ превратить текст в вектор чисел, чтобы искать "похожее по смыслу".
Vector DB — база для хранения этих векторов и быстрого поиска.
State Graph — граф состояний, чтобы агент понимал, что делать после каждого шага.
Tools — инструменты: API, базы данных, внешние сервисы. Руки агента.
Docling — конвертер документов в формат, который LLM понимает (PDF → Markdown).
RAG — механизм "достал релевантную информацию → добавил в контекст → сгенерировал ответ".
Теперь разберём каждый компонент подробнее. С кодом и граблями.
3. Память: почему агент не забывает (спойлер: забывает)
Память — это то, что превращает stateless LLM в нечто, способное вести осмысленный диалог дольше одного сообщения.
3.1. Кратковременная память (она же контекст)
Это просто история сообщений, которую вы передаёте в LLM при каждом вызове.
conversation = [
{"role": "user", "content": "Найди клиентов без ответа"},
{"role": "assistant", "content": "Ищу в CRM..."},
{"role": "tool", "content": "Найдено 12 клиентов"},
{"role": "assistant", "content": "Нашёл 12. Отправляю письма..."}
]
# При следующем вызове LLM получает весь этот массив
response = llm.generate(messages=conversation)
Проблема: контекстное окно ограничено. GPT-5 — 128K токенов, Claude Opus 4.5 — 200K, Gemini 2.5 — 2M. Звучит много, пока не начнёшь пихать туда историю за месяц.
Решение: суммаризация старых сообщений или вынос в долговременную память.
3.2. Долговременная память
Это когда агент помнит что-то между сессиями. "Иван Петров — сложный клиент, любит скидки, последний раз общались 15 декабря".
Технически: векторная база + метаданные.
# Сохраняем факт в долговременную память
client.upsert(
collection_name="agent_memory",
points=[
PointStruct(
id="fact_ivan_petrov",
vector=get_embedding("Иван Петров сложный клиент любит скидки"),
payload={
"content": "Иван Петров — сложный клиент, любит скидки",
"client_id": 12345,
"created_at": "2024-12-15"
}
)
]
)
# Потом, когда нужно вспомнить
results = client.search(
collection_name="agent_memory",
query_vector=get_embedding("что известно про Ивана Петрова"),
limit=5
)
3.3. Эпизодическая память
Что агент делал, когда и с каким результатом. Нужна для:
Дебага ("почему он отправил письмо не тому клиенту?")
Аудита ("что вообще происходило 15 декабря?")
Обучения ("какие действия приводили к успеху?")
{
"episode_id": "ep_2024_12_24_001",
"timestamp": "2024-12-24T10:30:00Z",
"task": "Отправить напоминания",
"actions": [
{"type": "crm_search", "result": "12 leads"},
{"type": "email_send", "to": "ivan@example.com", "result": "ok"},
{"type": "email_send", "to": "maria@example.com", "result": "ok"}
],
"outcome": "success"
}
3.4. Семантическая память
База знаний: документация, политики компании, инструкции. То, что агент должен "знать", но чего нет в его весах.
Это основа для RAG (раздел 8).
4. Docling: как скормить агенту PDF и не сойти с ума
Это боль, о которой редко говорят. Агенту нужно работать с документами компании. А документы — это PDF, DOCX, PPTX, сканы с печатью и подписью CEO в углу.
Проблема: LLM работают с текстом. PDF — это не текст. Это координаты букв на странице, растровые изображения, вложенные шрифты и прочий ад.
Docling (IBM Research, 2024) — open-source тулкит, который конвертирует всё это безобразие в Markdown или JSON, сохраняя структуру: заголовки, таблицы, формулы, код.
Почему не просто PyPDF2?
PyPDF2 и подобные извлекают "сырой текст". Таблица из 5 колонок превращается в кашу из чисел без разделителей. Заголовки теряются. Формулы — вообще отдельная история.
Docling исп��льзует две модели:
Layout Model — object detection для разметки страницы (где заголовок, где таблица, где картинка)
TableFormer — специально для таблиц, восстанавливает строки и столбцы
Пример использования
from docling.document_converter import DocumentConverter
converter = DocumentConverter()
result = converter.convert("contract.pdf")
# Получаем чистый Markdown
markdown = result.document.export_to_markdown()
print(markdown)
Что получаем:
# Договор №123
## 1. Предмет договора
Исполнитель обязуется...
| Услуга | Стоимость | Срок |
|--------|-----------|------|
| Разработка | 500 000 ₽ | 3 мес |
| Поддержка | 50 000 ₽/мес | 12 мес |
Granite-Docling: ещё круче
IBM выпустили Granite-Docling-258M — ультракомпактную VLM (vision-language model), которая конвертирует документы напрямую, сохраняя связь с исходным содержимым.
Зачем это для RAG:
Если PDF extraction превращает финансовую таблицу в кашу, vector search будет искать в мусоре. Docling сохраняет структуру — когда вы chunking'ите и embed'ите документы, вы работаете с чистыми данными.
Производительность
На бенчмарке: от 0.6 сек (5-й перцентиль) до 16.3 сек (95-й) на страницу, медиана 0.79 сек на x86 CPU.
Для агента это означает: 100-страничный мануал обрабатывается за 1-2 минуты.
5. Embeddings: как превратить текст в числа
Embedding — это вектор (массив чисел), который представляет "смысл" текста. Тексты с похожим смыслом имеют близкие вектора.
"Кот спит на диване" → [0.12, 0.45, 0.78, ...]
"Кошка дремлет на кровати" → [0.13, 0.44, 0.77, ...] // близко!
"Квартальный отчёт за Q3" → [0.91, 0.02, 0.15, ...] // далеко
Это позволяет искать "по смыслу", а не по ключевым словам. Пользователь спрашивает "как вернуть товар", а в базе лежит документ "Процедура возврата продукции" — embedding найдёт.
Модели embeddings: что выбрать (декабрь 2024)
Модель | Размерность | MIRACL-ru | Лицензия | Цена за 1M токенов | Комментарий |
|---|---|---|---|---|---|
BGE-M3 (BAAI) | 1024 | ~70.0 | MIT | Бесплатно (self-hosted) | Лучшее качество для русского |
| 1024 | ~63-65 | CC-BY-NC | $0.02 | НЕ для коммерции без лицензии! |
| 1536 | ~60 | Proprietary | $0.02 | Дёшево, но качество хуже |
| 3072 | ~65 | Proprietary | $0.13 | Дорого |
Важный момент про Jina: лицензия CC-BY-NC запрещает коммерческое использование без покупки лицензии. Многие об этом не знают и получают проблемы.
Мой выбор: BGE-M3 для production. +8% качества на русском языке, MIT лицензия, self-hosted = $0.
Late Chunking: когда обычные embeddings не справляются
Классический подход: режем документ на чанки → embed'им каждый чанк отдельно → храним.
Проблема: каждый чанк теряет контекст. Фраза "см. раздел 3.2 выше" превращается в бессмыслицу.
Late Chunking (Jina AI, 2024):
Embed'им весь документ целиком (до 8K токенов)
Получаем token-level embeddings с полным контекстом
Потом режем на чанки
Mean pooling для каждого чанка
Результат: каждый чанк "знает" о контексте всего документа. +30-40% качества retrieval для технических документов.
# Обычный подход
chunks = split_text(document, chunk_size=512)
embeddings = [embed(chunk) for chunk in chunks] # контекст потерян
# Late chunking
token_embeddings = embed_full_document(document) # 8K токенов макс
chunk_embeddings = late_chunk(token_embeddings, chunk_size=512) # контекст сохранён
6. Векторные базы: где всё это хранить
Векторная база — это специализированное хранилище для embeddings с быстрым поиском "ближайших соседей".
Сравнение (без маркетинга)
БД | Тип | За | Против |
|---|---|---|---|
Qdrant | Open-source / Cloud | Быстрый (Rust), hybrid search, отличная фильтрация | Надо разворачивать самому |
Pinecone | Только Cloud | Managed, не надо думать | Дорого, vendor lock-in |
Weaviate | Open-source / Cloud | GraphQL, гибридный поиск | Сложнее в настройке |
Chroma | Open-source | Встраивается в Python | Для прототипов, не для прода |
Milvus | Open-source | Миллиарды векторов | Сложный, нужен DevOps |
Когда что:
Прототип → Chroma
Production, хочу контроль → Qdrant (наш выбор)
Production, не хочу думать → Pinecone (но готовьте $70+/мес)
Миллиарды записей → Milvus
Гибридный поиск: Dense + Sparse
Семантический поиск (dense vectors) хорош для "похожего по смыслу". Но если пользователь ищет "документ №12345", он не поможет.
Гибридный поиск = semantic (dense) + keyword (BM25/sparse).
BGE-M3 генерирует оба типа векторов из коробки. Qdrant поддерживает hybrid search нативно.
# Qdrant hybrid search
results = client.search(
collection_name="documents",
query_vector=("dense", dense_vector),
query_vector=("sparse", sparse_vector),
fusion=models.Fusion.RRF # Reciprocal Rank Fusion
)7. LLM: мозг, который иногда галлюцинирует
LLM — центр принятия решений. Он читает контекст, думает (ну, как бы думает), выбирает инструмент, генерирует текст.
Что есть на рынке (декабрь 2024)
Спойлер: западные модели безумно дороги для production агентов. Китайские — нет.
Топ-tier (дорого):
Модель | Контекст | Цена (вход/выход за 1M токенов) | Для чего |
|---|---|---|---|
Claude Opus 4.5 | 200K | $5 / $25 | Когда качество критично |
Claude Sonnet 4.5 | 200K | $3 / $15 | Баланс цена/качество |
GPT-5 | 128K | $1.25 / $10 | OpenAI flagship |
GPT-5.1 Thinking | 128K | $10 / $40 | Сложные рассуждения |
Gemini 2.5 Pro | 2M | $1.25 / $5 | Огромный контекст |
Кстати: цены на Claude Opus 4.5 снизились в 3 раза буквально месяц назад. До этого было
75 за 1M токенов — production агент обходился бы в ~$4500/мес. Сейчас "всего" $1500/мес. Прогресс!
Production-ready (разумная цена):
Модель | Параметры | Цена (вход/выход) | Сильные стороны |
|---|---|---|---|
Qwen3 235B | 235B | $0.07 / $0.46 | Лучший для русского, 9/10 качество |
DeepSeek V3.1 Terminus | 671B MoE (37B active) | $0.27 / $1.10 | 100% стабильность, отличный EN |
Kimi K2 | 1T MoE (32B active) | $0.55 / $2.25 | Лучший open-weight по бенчмаркам |
MiniMax M2 | 456B | ~$0.20 / $0.80 | 4M контекст (!), отличное качество |
GLM-4.6 | 355B MoE | $0.60 / $2.00 | Дешевле Qwen, сравнимое качество |
Xiaomi MiMo-V2-Flash | 309B MoE (15B active) | $0.10 / $0.30 | 94.1% AIME 2025, самый дешёвый |
Наш production стек:
# Language-aware routing
def select_model(language: str, task_type: str):
if task_type == "large_context":
return "x-ai/grok-4-fast" # 2M tokens, $0.20/$0.50
if language == "ru":
return "qwen/qwen3-235b-a22b-2507" # лучший для русского
else:
return "deepseek/deepseek-v3.1-terminus" # 100% стабильность для EN
# Fallback
FALLBACK_MODEL = "moonshotai/kimi-k2-0905" # премиум качество для сложных случаевПочему не GPT-5 / Claude Opus для агентов?
Посчитаем. Агент обрабатывает 1000 запросов в день, средний запрос 5K токенов вход + 1K токенов выход. За месяц — 30,000 запросов:
Claude Opus 4.5:
Входящие: 150M токенов × $5/1M = $750
Исходящие: 30M токенов × $25/1M = $750
Итого: $1500/мес
Qwen3 235B:
Входящие: 150M токенов × $0.07/1M = $10.50
Исходящие: 30M токенов × $0.46/1M = $13.80
Итого: $24/мес
Разница в 62 раза. При сравнимом качестве для большинства задач. А до снижения цен Claude было бы $4500 vs $24 — разница в 187 раз.
MiMo-V2-Flash: новинка от Xiaomi
Вышла в декабре 2024. 309B параметров, 15B активных (MoE). Интересные особенности:
Hybrid Attention: 5 слоёв Sliding Window (128 токенов) + 1 слой Global — в 6 раз меньше KV cache
Multi-Token Prediction: генерирует несколько токенов за раз
Бенчмарки: 94.1% AIME 2025 (математика), 73.4% SWE-Bench (код)
Цена: $0.10 / $0.30 — дешевле всех конкурентов
Подвох: слабее в creative writing и natural language generation. Для агентских задач (tool calling, reasoning) — отлично.
Function Calling (Tool Use)
Это когда LLM не просто генерирует текст, а говорит "хочу вызвать функцию X с параметрами Y".
tools = [
{
"type": "function",
"function": {
"name": "search_crm",
"description": "Поиск клиентов в CRM",
"parameters": {
"type": "object",
"properties": {
"filter": {
"type": "string",
"enum": ["no_response_7d", "new", "vip"]
}
},
"required": ["filter"]
}
}
}
]
response = client.chat.completions.create(
model="qwen/qwen3-235b-a22b-2507",
messages=[{"role": "user", "content": "Найди клиентов без ответа неделю"}],
tools=tools
)
# Модель ответит:
# tool_calls: [{"function": {"name": "search_crm", "arguments": '{"filter": "no_response_7d"}'}}]8. RAG: как не скормить модели всю базу знаний
RAG (Retrieval-Augmented Generation) — паттерн, когда мы сначала находим релевантную информацию, потом добавляем её в промпт.
Потому что запихнуть всю документацию компании в контекст — дорого, медленно и бессмысленно.
Как работает
Запрос: "Как вернуть товар?"
↓
[Embedding запроса]
↓
[Поиск в векторной БД]
↓
Топ-20 кандидатов
↓
[Reranking] ← важный шаг!
↓
Топ-3 релевантных чанка
↓
[Добавляем в промпт]
↓
[LLM генерирует ответ]
Chunking: как резать документы
Нельзя просто взять PDF на 100 страниц и засунуть целиком. Надо порезать на куски (chunks).
Варианты:
Стратегия | Как работает | Когда использовать |
|---|---|---|
Fixed-size | Режем по N токенов | Простые тексты |
Semantic | По абзацам/заголовкам | Структурированные документы |
Recursive | Сначала по заголовкам → абзацам → предложениям | Универсальный вариант |
Late Chunking | Embed целиком, потом режем embeddings | Документы с cross-references |
from langchain.text_splitter import RecursiveCharacterTextSplitter
splitter = RecursiveCharacterTextSplitter(
chunk_size=500,
chunk_overlap=50, # чтобы контекст не терялся на границах
separators=["\n\n", "\n", ". ", " "]
)
chunks = splitter.split_text(document_text)
Reranking: когда embedding врёт
Иногда семантический поиск возвращает ерунду. Похоже по вектору, но не по смыслу.
Решение: reranking. Берём топ-20 результатов и прогоняем через специальную модель, которая переранжирует.
Модели для reranking:
Модель | MIRACL | Лицензия | Стоимость |
|---|---|---|---|
bge-reranker-v2-m3 | 69.32 | MIT | Бесплатно (self-hosted) |
Jina Reranker v2 | 65.2 | CC-BY-NC | $1/1000 запросов |
Cohere Rerank v3 | ~68 | Proprietary | $1/1000 запросов |
from FlagEmbedding import FlagReranker
reranker = FlagReranker('BAAI/bge-reranker-v2-m3', use_fp16=True)
# Первичный поиск — 20 результатов
candidates = vector_db.search(query, limit=20)
# Reranking
pairs = [[query, doc.text] for doc in candidates]
scores = reranker.compute_score(pairs, normalize=True)
# Сортируем и берём топ-3
results = sorted(zip(candidates, scores), key=lambda x: x[1], reverse=True)[:3]
Contextual Retrieval (Anthropic, 2024)
Идея: перед embed'ингом добавляем к каждому чанку его контекст — откуда он, к чему относится.
# Было
"Возврат товара возможен в течение 14 дней."
# Стало
"[Политика возврата, раздел 3.2] Возврат товара возможен в течение 14 дней."
Результат: +30-40% качества retrieval. Чанк "знает", откуда он взялся.
9. Графы состояний: чтобы агент не ушёл в бесконечный цикл
Агент — это не "запрос → ответ". Это конечный автомат: состояния, переходы, условия.
Пример
Задача: "Найди клиентов без ответа и отправь напоминание"
[START]
↓
[Поиск в CRM]
↓
Нашли кого-то?
├── Да → [Генерация письма] → [Отправка] → [Логирование] → [END]
└── Нет → [Лог: никого не нашли] → [END]
Без графа агент может:
Зациклиться ("ищу... ищу... ищу...")
Делать не то ("отправил письмо, хотя никого не нашёл")
Не знать, когда остановиться
Фреймворки
Фреймворк | Для чего |
|---|---|
LangGraph | Графы состояний, самый гибкий |
AutoGen (Microsoft) | Мульти-агентные системы (агенты общаются между собой) |
CrewAI | Role-based: каждый агент — роль (исследователь, писатель, критик) |
Пример на LangGraph
from langgraph.graph import StateGraph, END
from typing import TypedDict, List
class AgentState(TypedDict):
leads: List[dict]
emails_sent: int
def search_leads(state: AgentState) -> AgentState:
state["leads"] = crm.search(filter="no_response_7d")
return state
def send_emails(state: AgentState) -> AgentState:
for lead in state["leads"]:
email.send(to=lead["email"], body=generate_reminder(lead))
state["emails_sent"] += 1
return state
def log_nothing(state: AgentState) -> AgentState:
logger.info("Клиентов не найдено")
return state
# Собираем граф
workflow = StateGraph(AgentState)
workflow.add_node("search", search_leads)
workflow.add_node("send", send_emails)
workflow.add_node("log_empty", log_nothing)
workflow.set_entry_point("search")
workflow.add_conditional_edges(
"search",
lambda s: "send" if len(s["leads"]) > 0 else "log_empty"
)
workflow.add_edge("send", END)
workflow.add_edge("log_empty", END)
app = workflow.compile()
result = app.invoke({"leads": [], "emails_sent": 0})
10. Tools: руки агента (и почему их нужно контролировать)
Tools — это функции, которые агент может вызывать: API, базы данных, внешние сервисы.
Примеры
# CRM
def search_clients(filter: str) -> list[dict]:
"""Поиск клиентов по фильтру"""
...
# Email
def send_email(to: str, subject: str, body: str) -> bool:
"""Отправить письмо"""
...
# Docling (конвертация документов)
def parse_document(file_path: str) -> str:
"""Конвертировать PDF/DOCX в Markdown"""
...
# Календарь
def create_meeting(title: str, datetime: str, attendees: list[str]) -> str:
"""Создать встречу"""
...
Безопасность (это важно)
Агент с доступом к инструментам — это агент, который может натворить дел.
Что делать:
Whitelist — только разрешённые функции
Подтверждение — для опасных действий (удаление, оплата) спрашивать пользователя
Rate limiting — не больше N вызовов в минуту
Аудит — логировать всё
Sandbox — для особо параноидальных
def delete_client(client_id: int, confirmed: bool = False) -> str:
if not confirmed:
return f"⚠️ Подтвердите удаление клиента {client_id}"
logger.warning(f"УДАЛЕНИЕ клиента {client_id}")
db.execute("DELETE FROM clients WHERE id = %s", (client_id,))
return f"Клиент {client_id} удалён"
11. Итоговая таблица для тех, кто листал до конца
Параметр | Чат-бот | AI-агент |
|---|---|---|
Архитектура | Stateless | Stateful (память!) |
Что делает | Отвечает на вопросы | Выполняет задачи |
Память | Только текущий диалог | Кратко/долго/эпизодическая/семантическая |
Инструменты | Нет | CRM, email, Docling, календарь, базы... |
Документы | "Вставьте текст" | Docling → Markdown → RAG |
Логика | Вопрос → ответ | Цель → план → действия → проверка |
Автономность | Нужен человек | Работает сам (до определённой степени) |
LLM | GPT-5 / Claude Opus | Qwen3 / DeepSeek / Kimi K2 / MiMo |
Стоимость LLM | $5-25 / 1M токенов | $0.07-2.25 / 1M токенов |
Embeddings | OpenAI Ada | BGE-M3 (self-hosted, бесплатно) |
Стоимость разработки | $5-15K | $20-100K+ |
Стоимость в месяц (1000 req/day) | $500-1500 (API) | $24-100 (API + инфра) |
Вместо заключения
AI-агент — это не магия и не "ChatGPT, но лучше". Это инженерная система с кучей компонентов, каждый из которых может сломаться.
Если вам нужен автоответчик — сделайте чат-бота. Это проще, дешевле и работает.
Если нужен "цифровой сотрудник", который сам ходит в CRM, парсит PDF через Docling, отправляет письма и ставит задачи — добро пожаловать в мир агентов. Только запаситесь терпением, бюджетом и готовностью дебажить промпты в 3 часа ночи.
Ключевые инсайты из production:
Не используйте GPT-5/Claude для production агентов — китайские модели (Qwen3, DeepSeek, Kimi K2) дают 90% качества за 5% цены
BGE-M3 вместо Jina — лучше качество для русского, MIT лицензия, бесплатно
Docling для документов — не изобретайте велосипед с PyPDF2
Reranking обязателен — без него RAG работа��т на 60%
Late Chunking для технических документов — +30% качества retrieval
Автор: Игорь Масленников
Пишу про AI-агентов, LLM-бенчмарки и архитектуру софта.
📢 Мой канал в Telegram: @maslennikovigor — там я публикую свежие бенчмарки и DevOps-лайфхаки.
💬 Личный контакт: @maslennikovig
