Как четыре бытовых кейса превратились в инвестиционный офис из агентов — и почему человек из контура так и не выпал

Когда говорят о SDD, AI PDLC или HG PDLC, обычные люди считают эти аббревиатуры очень далёкими от реальной жизни и принадлежащими жёсткой корпоративной ИТ‑сфере. Расскажу на примере ряда своих опытов (от простого к сложному), как эти абстрактные понятия реализуются для личных идей и проектов.

Кейс 1: агент‑фильтр для длинных статей

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

Решено создать первого личного агента с единственным навыком: формальная логика (по учебнику Челпанова: ревью аргументации, исправление текста, силлогизмы и логические ошибки). Получая ссылку на статью, он делает три вещи:

  1. Суммаризация статьи — краткое изложение того, что автор хотел сказать (не пересказ, а реконструкция тезисов).

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

  3. Три тезиса, с которыми агент согласен, и три — с которыми не согласен, с аргументацией по каждому.

В итоге за минуту я получаю отчёт и принимаю решение: читать статью, пропустить как неинтересную или как манипулятивную.

Этот агент — первый инструмент с недетерминированной логикой, и первыми скиллами.

Кейс 2: медицинский агент с MCP — от стопки PDF к живой карте

Периодически сдаёшь анализы, из клиники приходит куча PDF. И если в анализах есть какие‑то отклонения, то непонятно, это что‑то сломалось внутри организма или ты на прошлой неделе на ногах перенёс лёгкий вирус.

Решено создать агента, которому отгружаются все PDF из медицинского приложения. У агента есть:

  • навык распознавания PDF с кириллицей и таблицами;

  • постоянное структурированное хранилище (определенная мной структура личной медицинской карты);

  • способность по совокупности анализов и заключений разных врачей строить гипотезу о состоянии;

  • анализ врачебных рекомендаций: насколько они близки к этой гипотезе;

  • рекомендации, какие дополнительные анализы имеет смысл сдать для подтверждения, и что поменять в образе жизни и диете.

Навык распознавания появился не сразу: сначала я просто заставил агента обработать PDF от медклиник. После первой успешной попытки чтения и распознавания анализов попросил его оформить это как навык — чтобы применять в дальнейшем при появлении новых PDF. Так разовая задача превратилась в переиспользуемый инструмент.

Агент отслеживает изменение показателей по результатам анализов, а не просто смотрит на текущий срез. Он строит общую картину: что уже исправляется, а над чем ещё надо поработать. Видно не срез показателей на сейчас, а динамику: улучшается, стоит на месте или ухудшается.

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

На этом агенте впервые использован MCP — интеграция с аккаунтом Xiaomi: агент подтягивает данные с умных весов с биоимпедансным анализом о составе тела, с умных часов о физических активностях, велотренировках. Плюс распознавание Excel‑файлов, куда вручную заносятся домашние наблюдения.

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

Кейс 3 (прототип): мультиагентный прогноз курса

Столкнулся перед отпуском с необходимостью купить валюту на ежедневные расходы. Курс волатильный, покупать на пике обидно.

Получилась первая попытка мультиагентной системы. Агенты разбиты на пары, каждая пара работает по своему фактору влияния на курс: фундаментальные аспекты, технические, новости. В каждой паре — агент‑оптимист и агент‑пессимист: первый подбирает аргументы, почему курс вырастет, второй — почему снизится. Каждый выдаёт заключение в формальной структуре с вероятностным коридором. При команде «дай прогноз на 5 дней» агент‑судья последовательно вызывает субагентов, анализирует ответы и выносит итоговое заключение, приводя аргументы тех, кто показался ему более весомым.

У каждого субагента свой набор источников информации и свой набор аспектов, которые могут повлиять на курс. Эти аспекты не всегда совпадают у оптимиста и пессимиста, есть асимметричные факторы (влияющие например только на падение курса). Если бы состязательная пара имела бы зеркальные факторы, она бы просто удваивала один и тот же взгляд.

Тестирование отдал супруге: периодически запрашивать прогноз на несколько дней вперёд и в прогнозную дату фиксировать, сбылся он или нет. Системно и долго протестировать не удалось, не хватило терпения, но позитивный фидбэк оказался неожиданно сильным: она сказала, что никогда ещё не закупала валюту так эффективно, и только на курсовой разнице покупки удалось отбить значимую часть отпуска.

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

Кстати, уже после запуска узнал о похожем проекте в компании BlackRock. В августе 2025 года исследователи компании опубликовали работу AlphaAgents — мультиагентную систему для отбора акций и построения портфеля. Общий принцип похож: три специализированных агента с разными зонами ответственности — фундаментальный (анализ финансовой отчётности), агент‑сентимент (новости и аналитические рейтинги) и агент‑оценщик (исторические цены, волатильность, технический анализ). Каждый агент выдаёт независимое мнение, после чего они вступают в дебаты и приходят к консенсусу с учётом заданного риск‑профиля.

Кейс 4 (основной): инвестиционный офис из агентов

Одно из моих хобби — количественные инвестиции. Проблема известная: research съедает огромное количество времени. Нужно либо выводить свои индикаторы, либо комбинировать существующие, и все эти эксперименты бесконечны.

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

В итоге получилась совокупность агентов, которая, по сути, заменяет целый инвестиционный офис. К примеру, пайплайн research‑стадии состоит из следующих агентов:

  • агент «ресёчер» анализирует заданные источники и ищет свежие идеи;

  • агент «разработчик» по найденным идеям строит Python‑ноутбуки и оптимизирует их;

  • агент «ревьюер» проверяет ноутбуки: корректность расчётов, оптимизацию вычислений и так далее;

  • агент «риск‑аналитик» по стратегии рассчитывает заданные мной риск‑метрики и графики и дальше ждёт моего решения.

Конечно, я никогда не отпущу такую систему в автономку. На ключевых этапах пайплайна решение принимаю я, а не агенты. Только после моей отмашки, что стратегия удовлетворяет критериям, включается следующая совокупность агентов, которые уже реализуют скрипт на боевой платформе: разработка, ревью, тестирование, и всё это зациклено (при ошибках и замечаниях цикл повторяется).

Отдельно живут вспомогательные агенты: одни обновляют данные, используемые в тестировании, другие строят отчёт по портфелю, третьи проверяют, что в боевой стратегии и исследовательском ноутбуке сделки полностью идентичны. Вызываются они отдельно от пайплайна, в диалоге с агентом‑оркестратором.

Для себя я сформулировал следующий принцип разбиения пайплайна (или процесса PDLC) на агенты: сначала максимально декомпозирую процесс, и для каждого атомарного шага делаю агента. Они получаются простыми и с четко сформулированными правилами работы и образа результата.

Кажется, у меня получился human guided product development life cycle (HG PDLC) — AI‑агентизированный жизненный цикл разработки продукта, где продуктом является торговая стратегия, а человек координирует конвейер.

Самое сложное оказалось вообще не в коде и не в оркестрации. Сложнее всего чётко сформулировать образ требуемого результата (тот самый Spec из Spec‑Driven Development, SDD), который должен быть достигнут агентами пайплайна. Чем чётче сформулировано намерение, тем меньше циклов с доработками после ревью итогов и тем предсказуемее результат. Размытая постановка приводит к тому, что агенты работают в «холостую»: формально всё делают правильно, но не то, что нужно.

Отдельно хочу остановиться на вопросах взаимодействия с агентом: уведомлениях и удаленном доступе. Когда в стратегии происходит инвестиционное событие (открытие или закрытие сделки), я должен получить уведомление. Раньше использовал Telegram, но после начала его блокирования в России нашёл приложение ntfy, решающее только задачу нотификаций. Этот же инструмент пригодился не только для торговых стратегий: кодинговый агент, в котором живут все мои проекты, пишет мне через него для любого проекта, если в диалоговой сессии завершается работа, выводится итог, требуется моя реакция, выбор или даже подтверждение доступа. Уведомление приходит с указанием, какой именно проект ждёт внимания.

Система крутится дома, а вести диалог с агентами хочется откуда угодно. Поэтому сделал веб‑интерфейс к агенту: получив уведомление, захожу через браузер, быстро набираю ответ, запускаю и возвращаюсь к своим делам.

Когда рисковик прогоняет стратегию на большом диапазоне истории, это занимает много времени, и ждать результата нет смысла. Я настроил публикацию таких отчётов в Google Drive: агент завершил, уведомил меня, выложил отчёт. Я захожу, смотрю и говорю «окей, запускай вывод на пром» либо «стоп, эту стратегию дальше не рассматриваем».

В агенте реализована LLM‑память с задачей постоянно наращивать опыт, используемый в разработке торговых стратегий: лайфхаки, сформированные на основе проанализированных внешних материалов, прогонов стратегий, разработки кода на всех используемых стеках. Всё складывается в базу знаний, и все агенты обязаны перед началом работы в неё заглянуть. Получается система с обратной связью: агенты используют выученные уроки предыдущих итераций, в том числе от других агентов. Таким образом, каждый завершившийся прогон улучшает следующий.

Все бэктесты при подборе и оптимизации стратегии учитывают реальные комиссии у моего текущего брокера и биржи, используют разделение истории на тестовые и валидационные периоды. А отдельным скиллом верифицируется совпадение реальных сделок и сделок стратегии на бэктесте за прошедший период, чтобы не было расхождений между тем, что показала история, и тем, что происходит в проде.

Что получилось в итоге? Раньше, на вывод стратегии в продуктив требовалось несколько кварталов: всё делалось вручную, в свободное от работы и семьи время. Сейчас за одну неделю в продуктив выведено свыше 30 стратегий. Это те стратегии, которые соответствуют заданным мной намерениям: определённым требованиям в доходности (задан пороговый CAGR), рискам (ограничена максимальная просадка, показатель Sortino, daily VAR), частоте сделок, профит‑фактору, winrate и тому подобное. Стратегии валидируются на продуктиве на малом капитале, поэтому пока рано говорить о каком‑то успехе, но то, что достигнуто пайплайном, я не мог представить себе даже год назад.

Сквозная картина: что добавлял каждый кейс

Кейс

Новый слой автономности

Что появилось

1. Фильтр статей

Рефлексия над аргументацией

Один навык, оценка логики, суммаризация текста

2. Медицинская карта

Постоянная память + MCP

Живая карта, интеграция с внешними системами, динамика показателей

3. Прогноз курса

Мультиагентность

Состязательные пары, судья, асимметричные факторы

4. Инвест‑офис

Организация + обратная связь

Роли, AI PDLC для торговых стратегий, база знаний, асинхронные каналы (Push, web, Google Drive), human‑in‑the‑loop

Технические заметки

1. При апгрейде агентов на каждом этапе я стараюсь использовать максимально простые навыки. LLMWiki можно организовать на графовых СУБД и RAG‑технологиях, я же выбрал доступный open‑source навык LLMWiki на простых markdown‑файлах, специально организованных для хранения знаний: концепции, сущности, обобщения, синтез. Так же поступил с уведомлениями: не стал бороться с блокировкой Telegram, а взял простое приложение ntfy. А передачу мне результатов для всех проектов кодингового агента организовал через копирование на Google Drive в свою папку для каждого проекта.

2. Кодинговый агент, которого я использую для всех моих проектов — opencode: полностью open‑source агент под MIT‑лицензией, который не привязан к конкретному провайдеру моделей. Пришлось поставить одновременно и Desktop‑версию (в которой работаю дома), и CLI (которая организует веб‑сервер для удалённого веб‑интерфейса).

3. Поверх кодингового агента живут несколько скиллов, общих для всех проектов. Первый: скилл, основанный на подходе Карпатого: набор приёмов, которые заставляют агента работать с кодом так, как это делал бы вдумчивый инженер, а не автодополнение с амбициями. Второй: скилл экономии токенов: правила, которые снижают расход контекста без потери качества. Третий — скилл публикации материалов из любого проекта в Google Drive. Четвертый — скилл уведомления в ntfy.

Заключение

От одного навыка с формальной логикой до инвест‑офиса из агентов — четыре кейса, по опыту которых термины SDD, AI PDLC и HG PDLC оказались не корпоративными аббревиатурами, а понятным подходом, когда через четко сформулированное намерение и детализацию этапов (агентов) можно добиться результата и в личных проектах.

Комментарии (6)


  1. teamfighter
    24.10.2026 03:19

    Приветствую на Хабре! Расскажите по возможности в следующей статье как реализовывали агентов, с какими сложностями столкнулись. Было бы интересно почитать.


    1. grepan Автор
      24.10.2026 03:19

      Приветствую! В принципе основной подход, который я для себя выработал, я обозначил: выстраивание пайплайна агентов ничем не отличается от выстраивания процесса с людьми. Разбиваете процесс на шаги, каждый из который максимально детерминирован и завершается четким и понятным артефактом. Когда строите процесс с людьми, бывает, что человек обладает несколькими квалификациями, и вы ему поручаете несколько последовательных шагов. С агентами лучше этого не делать. Чем "атомарнее" агент, тем проще определить для него инструменты (скиллы, MCP), встроить guardrails, определить формат выходного артефакта. Например, на этапе реализации кода на основе качественной спецификации, я пришел к тому, чтобы разделить процесс на трех агентов: непосредственно разработчик (в которого встроены требования и к стеку, и к критериям качества, и набор обязательных и неизменяемых процедур, которые агент обязан использовать в шаблоне программного кода), агент-ревьювер кода (задача которого выявить лишние расчеты, от которых можно отказаться без влияния на результаты алгоритмов), и агент-тестировщик, который проверяет повторно код после итерации "разработка - ревью - доработка предложений". А сама реализация агентов в opencode, в отличие от визуальных фреймворков типа n8n, делается просто промптом: описываешь словами структуру пайплайана, последовательность агентов, ответственность и требования к каждому. Потом можно проверить их md-файлы для контроля, можно попросить вывести последовательность вызовов в конкретном проекте opencode.


  1. ENick
    24.10.2026 03:19

    Добрый вечер! "навык распознавания PDF с кириллицей и таблицами;" поясните технические детали


    1. grepan Автор
      24.10.2026 03:19

      Когда первый раз подсунул 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 (via from pdfminer.high_level import extract_text)

      • Environment path: Use C:/.../.venv/Scripts/python.exe explicitly

      • yfinance 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 data

      • If 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

      1. pdfminer on Python 3.5: Works but emits deprecation warnings — suppress with 2>/dev/null

      2. No f-strings in Python 3.5 — use '{}'.format(var) style

      3. Large 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
      


  1. ENick
    24.10.2026 03:19

    Спасибо за подробную информацию. Из текста следует, что Вы работаете с markdown: "я же выбрал доступный open‑source навык LLMWiki на простых markdown‑файлах ". Рdfminer вроде напрямую markdown не выдает?


    1. grepan Автор
      24.10.2026 03:19

      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

      1. PDF-файлы находятся в C:\Users\...\medcarta\

      2. Файлы могут быть в форматах .pdf — как текстовые, так и отсканированные (изображения)

      3. Для текстовых PDF: извлечение через pdfminer с декодированием

      4. Для image-based PDF: сообщить пользователю, что данные не извлекаются, и попросить внести их вручную

      План действий (обязательный порядок)

      При поступлении запроса «добавь новый анализ» или при появлении нового файла PDF:

      Шаг 1: Анализ PDF и извлечение данных

      • Прочитать PDF-файл

      • Если не удаётся извлечь текст (image-based PDF) — попросить пользователя ввести данные вручную

      • Извлечённые данные оформить в структурированном виде (таблицы, показатели, нормы)

      Шаг 2: Добавление в resume.md

      • Определить, в какой раздел относится исследование (УЗИ, кровь и т.д.)

      • Вставить новый подраздел ## ГГГГ.ММ с данными в правильное хронологическое место

      • Оформить в markdown-таблицы, указать нормы и статус

      Шаг 3: Обновление раздела “Динамика”

      • Обновить или создать подраздел ## Динамика (X → Y) после самого позднего анализа по дате

      • Сравнить последний и предпоследний анализы в этом разделе

      • Указать изменения по каждому параметру

      ...