Черновик
Архитектура агента
Агент итеративно заполняет шаблон кредитного заключения по пакету DD-документов клиента. Для каждого поля — значение + цитаты (файл, страница, фрагмент). Ненайденное не блокирует остальное — уходит в раздел «требует проверки» и ждёт аналитика на HITL-ревью.
Вход / выход
Вход
- Шаблон отчёта (DOCX):
LA_Template,25-appendix_template. - Пакет документов задачи (PDF / DOCX / XLSX / сканы) — из
/var/lib/cra/tasks/<task_id>/. - Методичка (reference only):
рекомендованный_чек.
Выход
Заполненный DOCX + трассировка: для каждого поля указан источник (файл, страница, цитата).
Пайплайн
- Ingest — извлекаем текст: PDF через pdfminer, сканы через OCR, DOCX через python-docx, XLSX через openpyxl. Режем на чанки с метаданными
(file, page, offset). - Index — эмбеддинги чанков в векторный стор (на задачу свой индекс, клиенты не смешиваются).
- Plan — из шаблона вытягиваем упорядоченный список полей → очередь пунктов.
- Итеративный ReAct — агент идёт по очереди, по одному пункту:
- нашёл — пишет
{value, citations}; - после N шагов / низкой уверенности не нашёл — помечает
not_foundc причиной и переходит к следующему.
- нашёл — пишет
- Assemble — собираем финальный ответ: заполненное — в DOCX, пропущенное — в раздел «требует ручной проверки» с частичными цитатами.
- Render — финальный DOCX + приложение со ссылками на источники.
Тулы агента
| Tool | Назначение | Выход |
|---|---|---|
rag.query(q, k=5) | Семантический поиск по индексу задачи | top-k чанков с (file, page, snippet, score) |
fs.list() | Перечислить файлы задачи | [{name, mime, pages}] |
fs.read_page(file, page) | Прочитать страницу целиком | текст страницы |
fs.grep(file, pattern) | Regex-поиск в файле | [(page, line, context)] |
bash.run(cmd) | Read-only утилиты в песочнице (pdftotext, pdfinfo…) | stdout / stderr, с таймаутом |
rag.query — основной путь: дёшево и с цитированием. fs.read_page / fs.grep — когда нужен полный контекст страницы или соседние поля (таблицы, реквизиты). bash.run — крайний случай.
ReAct-контур на один пункт
system: «Заполни поле X шаблона LA. Верни JSON {value, citations:[{file,page,quote}]}
либо {status:"not_found", reason, partial_evidence?}.»
loop:
thought → tool_call → observation
stop:
ok — value готов и есть ≥1 citation
give_up — достигнут лимит шагов / низкая уверенность
Giving up — штатный исход, не ошибка. Пункт уходит в «требует проверки», агент переходит к следующему. Лимит шагов (напр. 6), таймаут, валидация цитаты (страница действительно содержит quote).
Стек
| OCR | dots.ocr (для сканов и PDF без текстового слоя) |
|---|---|
| Embeddings | BAAI bge-m3 (многоязычный, длинный контекст; ру/уз) |
| Vector DB | Milvus (коллекция на задачу, метаданные file, page, offset) |
| LLM | целевой — локальная on-prem (vLLM / TGI / Ollama + Qwen2.5 / Llama-3 / DeepSeek). На этапе прототипа — OpenRouter (только обезличенные / тестовые данные), потом свитч на локальный endpoint. |
Где это живёт
- Сейчас
/app/— оболочка: задачи + файлы (SQLite + диск). - Агент — отдельный воркер (Celery / RQ или systemd-скрипт), читает очередь задач из той же БД, пишет прогресс и результаты обратно.
- HITL-ревью: аналитик видит заполненные поля с цитатами, правит, подтверждает — только потом рендер в DOCX.
Открытые вопросы
- Схема плейсхолдеров в DOCX —
{{var}}, bookmarks, content controls или заголовки. От выбора зависит парсер шаблона → очередь пунктов → рендер. - OCR-fallback — что делать, если dots.ocr не уверен (низкий confidence на страницу).
- Метрика качества — как замерять «правильность» заполнения до и после HITL.