Комментарии 6
Приветствую на Хабре! Расскажите по возможности в следующей статье как реализовывали агентов, с какими сложностями столкнулись. Было бы интересно почитать.
Приветствую! В принципе основной подход, который я для себя выработал, я обозначил: выстраивание пайплайна агентов ничем не отличается от выстраивания процесса с людьми. Разбиваете процесс на шаги, каждый из который максимально детерминирован и завершается четким и понятным артефактом. Когда строите процесс с людьми, бывает, что человек обладает несколькими квалификациями, и вы ему поручаете несколько последовательных шагов. С агентами лучше этого не делать. Чем "атомарнее" агент, тем проще определить для него инструменты (скиллы, MCP), встроить guardrails, определить формат выходного артефакта. Например, на этапе реализации кода на основе качественной спецификации, я пришел к тому, чтобы разделить процесс на трех агентов: непосредственно разработчик (в которого встроены требования и к стеку, и к критериям качества, и набор обязательных и неизменяемых процедур, которые агент обязан использовать в шаблоне программного кода), агент-ревьювер кода (задача которого выявить лишние расчеты, от которых можно отказаться без влияния на результаты алгоритмов), и агент-тестировщик, который проверяет повторно код после итерации "разработка - ревью - доработка предложений". А сама реализация агентов в opencode, в отличие от визуальных фреймворков типа n8n, делается просто промптом: описываешь словами структуру пайплайана, последовательность агентов, ответственность и требования к каждому. Потом можно проверить их md-файлы для контроля, можно попросить вывести последовательность вызовов в конкретном проекте opencode.
Добрый вечер! "навык распознавания PDF с кириллицей и таблицами;" поясните технические детали
Когда первый раз подсунул PDF и попросил распознать, агент реально в несколько итераций пытался, выдавая кривые символы. Я несколько раз указывал на ошибки и заставлял переделать. А когда ему удалось (он нашел в интернете подходящие библиотеки), я тут же попросил оформить это в виде навыка. Сейчас у меня в корне агента opencode (доступный навык для всех проектов) навык pdf-reader:
name: pdf-reader description: Extracts Russian/Cyrillic text from PDF files, handles encoding issues (cp1251, raw_unicode_escape), and processes tabular data. Use when working with medical PDFs, scanned documents, or any PDF with Cyrillic text that needs machine-readable conversion.
PDF Reader for Cyrillic and Tables
Extracts machine-readable text from PDF files that contain Russian text, tables, and mixed formatting. This skill handles the quirks of pdfminer in older Python environments (3.5.x) where f-strings are not available.
Environment Notes
Python: 3.5.4 (no f-strings — use
.format())PDF library:
pdfminer(viafrom pdfminer.high_level import extract_text)Environment path: Use
C:/.../.venv/Scripts/python.exeexplicitlyyfinance stub: Not related to PDF reading
Quick Start
from pdfminer.high_level import extract_text
text = extract_text('path/to/file.pdf')
for line in text.split('\n'):
s = line.strip()
if s:
print(s)
Instructions
1. Basic extraction
For simple PDFs with embedded text:
from pdfminer.high_level import extract_text
text = extract_text('file.pdf')
for line in text.split('\n'):
s = line.strip()
if s:
print(s)
2. Handle Cyrillic (cp1251) encoding
Most Russian medical PDFs encode text as cp1251. The raw text comes out as mojibake. Fix it:
from pdfminer.high_level import extract_text
text = extract_text('file.pdf')
decoded = text.encode('latin1', errors='replace').decode('cp1251', errors='replace')
for line in decoded.split('\n'):
s = line.strip()
if len(s) > 5:
print(s)
If that fails, try the raw_unicode_escape approach:
from pdfminer.high_level import extract_text
text = extract_text('file.pdf')
try:
decoded = text.encode('raw_unicode_escape').decode('cp1251', errors='replace')
except:
# fallback to direct output
decoded = text
for line in decoded.split('\n'):
s = line.strip()
if s:
print(s)
3. Detect image-based (scanned) PDFs
If text extraction yields mostly garbage or very few readable strings, the PDF may be image-based (scanned document). Use the Read tool to view it directly:
Call
read(file_path)— the tool returns base64-encoded PDF dataIf text is not extractable, ask the user to provide values manually
Signs of a scanned PDF:
Very few text fragments extracted
Extracted text is mostly header/footer garbage
PDF size is large (150K+ for a single page)
4. Extract tables
For tabular data, extract line by line and reconstruct the table structure manually. Columns are usually separated by multiple spaces or pipe characters:
from pdfminer.high_level import extract_text
text = extract_text('file.pdf')
decoded = text.encode('raw_unicode_escape').decode('cp1251', errors='replace')
for line in decoded.split('\n'):
s = line.strip()
if '|' in s:
# table row
cells = [c.strip() for c in s.split('|')]
print(cells)
elif s and not s.startswith('-'):
# label row
print(s)
5. Handle mixed success/failure
If extract_text succeeds but the output is still garbled:
# Try multiple encodings
for enc in ['cp1251', 'cp866', 'koi8_r']:
try:
decoded = text.encode('latin1').decode(enc)
print('Worked with: ' + enc)
break
except:
continue
Known Issues
pdfminer on Python 3.5: Works but emits deprecation warnings — suppress with
2>/dev/nullNo f-strings in Python 3.5 — use
'{}'.format(var)styleLarge PDF paths with spaces: Quote them in bash commands
Example Workflow
1. Read PDF with pdfminer -> raw text with mojibake
2. Decode with latin1 -> cp1251 -> readable Cyrillic
3. If still garbled -> try raw_unicode_escape path
4. If minimal text extracted -> PDF is scanned -> use Read tool or ask user
5. Reconstruct tables manually from line-by-line output
Requirements
pip install pdfminer.six
Спасибо за подробную информацию. Из текста следует, что Вы работаете с markdown: "я же выбрал доступный open‑source навык LLMWiki на простых markdown‑файлах ". Рdfminer вроде напрямую markdown не выдает?
LLMWiki в другом проекте, где нет чтения PDF файлов, только сохранение выдачи питоновских ноутбуков в PDF, и выкладывание их на Google Drive.
А в том проекте, где используется распознавание PDF, оформлен вот такой markdown SKILL.md в папке workflow проекта:
name: medcarta-workflow description: Workflow для проекта medcarta — медицинская карта с анализом PDF. Использовать при добавлении нового анализа/исследования в resume.md. Запоминает последовательность: извлечь данные -> добавить в файл -> обновить динамику -> обновить общую клиническую картину и рекомендации.
MedCarta Workflow
Проект: C:\Users\Mikl\medcarta
Файл: resume.md
Окружение: Python 3.5.4 (C:/.../.venv/Scripts/python.exe)
Библиотека: pdfminer (pip install pdfminer)
Кодировка: raw_unicode_escape → cp1251 для кириллицы
Принцип работы с PDF
PDF-файлы находятся в
C:\Users\...\medcarta\Файлы могут быть в форматах
.pdf— как текстовые, так и отсканированные (изображения)Для текстовых PDF: извлечение через
pdfminerс декодированиемДля image-based PDF: сообщить пользователю, что данные не извлекаются, и попросить внести их вручную
План действий (обязательный порядок)
При поступлении запроса «добавь новый анализ» или при появлении нового файла PDF:
Шаг 1: Анализ PDF и извлечение данных
Прочитать PDF-файл
Если не удаётся извлечь текст (image-based PDF) — попросить пользователя ввести данные вручную
Извлечённые данные оформить в структурированном виде (таблицы, показатели, нормы)
Шаг 2: Добавление в resume.md
Определить, в какой раздел относится исследование (УЗИ, кровь и т.д.)
Вставить новый подраздел
## ГГГГ.ММс данными в правильное хронологическое местоОформить в markdown-таблицы, указать нормы и статус
Шаг 3: Обновление раздела “Динамика”
Обновить или создать подраздел
## Динамика (X → Y)после самого позднего анализа по датеСравнить последний и предпоследний анализы в этом разделе
Указать изменения по каждому параметру
...

Эволюция личных ИИ‑агентов: от суммаризации до автономной организации