<?xml version="1.0" encoding="utf-8" ?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:tt="http://teletype.in/" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/"><title>Dmitrii Razvozzhaev</title><author><name>Dmitrii Razvozzhaev</name></author><id>https://teletype.in/atom/el_cortador</id><link rel="self" type="application/atom+xml" href="https://teletype.in/atom/el_cortador?offset=0"></link><link rel="alternate" type="text/html" href="https://teletype.in/@el_cortador?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=el_cortador"></link><link rel="next" type="application/rss+xml" href="https://teletype.in/atom/el_cortador?offset=10"></link><link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></link><updated>2026-09-23T22:33:15.278Z</updated><entry><id>el_cortador:vH2tcFBeVyf</id><link rel="alternate" type="text/html" href="https://teletype.in/@el_cortador/vH2tcFBeVyf?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=el_cortador"></link><title>Я собрал отдел из шести AI-джунов и вот что из этого вышло</title><published>2026-06-03T15:09:34.158Z</published><updated>2026-06-05T08:36:50.639Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img2.teletype.in/files/9f/f4/9ff49b93-5df2-483d-8e74-8e8c8e1da67b.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://img2.teletype.in/files/55/4d/554dc4ae-7dda-4394-be40-aaba668ec06a.png&quot;&gt;В этой статье я расскажу, как сделал своих агентов, что получилось хорошо, а что — нет, и почему это делегирование, а не замена «кожаного».</summary><content type="html">
  &lt;h2 id=&quot;HtuP&quot;&gt;Вначале была мысль&lt;/h2&gt;
  &lt;p id=&quot;f9Rj&quot;&gt;Я технический писатель и моя работа — извлекать смысл из хаоса и превращать этот смысл в документацию, которую действительно читают. Под «хаосом» я подразумеваю множество записей созвонов, постановок от аналитиков, Jira-тикетов.&lt;/p&gt;
  &lt;p id=&quot;EIam&quot;&gt;Дело в том, что между «хаосом» и «документацией, которую читают» есть прослойка в виде «механической» работы: например, несколько раз переслушать запись созвона, чтобы не пропустить ключевые нюансы, вручную пройтись по пачке тикетов, чтобы собрать релиз-ноты или побуквенно сверить текст со стайлгайдом.&lt;/p&gt;
  &lt;p id=&quot;WDIw&quot;&gt;Такая рутинная «механика» съедает время, нужное для смысловой работы, и, осознав это, я подумал: «А что, если такую рутину делегировать агентам?» (коллегам, увы, невозможно — я все-таки один техписатель в отделе)&lt;/p&gt;
  &lt;p id=&quot;Outk&quot;&gt;В этой статье я расскажу, как придумал и сделал своих агентов, что получилось хорошо, а что — нет, и почему это делегирование, а не замена «кожаного» специалиста.&lt;/p&gt;
  &lt;h2 id=&quot;kKlx&quot;&gt;От разрозненных агентов к одному мегаинструменту&lt;/h2&gt;
  &lt;p id=&quot;DmkH&quot;&gt;К единой системе агентов я пришел не сразу и сначала у меня появились отдельные наработки в виде нескольких агентов.&lt;/p&gt;
  &lt;p id=&quot;19EA&quot;&gt;Каждый из них жил сам по себе, хранился и настраивался отдельно, запускались они тоже в отдельных командных строках. Со временем меня начало бесить, что приходится запускать несколько командных строк и переключаться между ними, особенно когда задач много.&lt;/p&gt;
  &lt;p id=&quot;boOG&quot;&gt;И я-таки додумался объединить всех агентов в одном месте и весьма вовремя наткнулся на документацию OpenClaw — это стало отправной точкой для сборки своего «отдела AI-джунов».&lt;/p&gt;
  &lt;h2 id=&quot;sA32&quot;&gt;Почему OpenClaw?&lt;/h2&gt;
  &lt;p id=&quot;nj7J&quot;&gt;Здесь было бы логичным спросить меня: &lt;em&gt;«Дима, а почему ты выбрал OpenClaw, а не Hermes? Почему не делал с помощью LangChain/LangGraph?»&lt;/em&gt;&lt;/p&gt;
  &lt;p id=&quot;pI2e&quot;&gt;Я не проводил сравнительный анализ фреймворков. На одном из мероприятий я услышал, что OpenClaw — это open-source-шлюз между LLM и мессенджерами, которому можно настраивать skills. Это звучало именно так, как мне было нужно, поэтому я решил попробовать.&lt;/p&gt;
  &lt;p id=&quot;5RTQ&quot;&gt;Если хотите почитать о нем подробнее, оставлю здесь ссылку на &lt;a href=&quot;https://docs.openclaw.ai&quot; target=&quot;_blank&quot;&gt;документацию&lt;/a&gt;. А если коротко: OpenClaw — это агент, который принимает запросы пользователя в мессенджере, использует инструкции и skills, умеет вызывать внешние инструменты и жить как долгоживущий процесс.&lt;/p&gt;
  &lt;p id=&quot;6dpr&quot;&gt;Связка OpenClaw с Telegram была очевидной: в этом мессенджере я провожу много времени и хотелось, чтобы все агенты жили в одном чатике.&lt;/p&gt;
  &lt;h2 id=&quot;3INf&quot;&gt;Общая схема: Docker, оркестратор и шесть агентов&lt;/h2&gt;
  &lt;p id=&quot;sn0N&quot;&gt;Решение крутится в Docker. Его я выбрал, чтобы изолировать OpenClaw от файловой системы и глобального окружения, а не сидеть и гадать, не решит ли он что-то «оптимизировать» без спроса.&lt;/p&gt;
  &lt;p id=&quot;zguw&quot;&gt;Кодовую часть я собирал в связке с Claude Code: я писал спецификацию, задавал архитектуру, тестировал поведение и принимал решения, а Claude Code занимался кодом агентов и правил ошибки.&lt;/p&gt;
  &lt;figure id=&quot;S2TL&quot; class=&quot;m_retina&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/55/4d/554dc4ae-7dda-4394-be40-aaba668ec06a.png&quot; width=&quot;512&quot; /&gt;
    &lt;figcaption&gt;Вот так это и было&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;XQNz&quot;&gt;В моем супер-агенте OpenClaw играет роль оркестратора, а шесть специализированных агентов работают рядом с ним как отдельные FastAPI-приложения.&lt;/p&gt;
  &lt;p id=&quot;6a7u&quot;&gt;Вот они, слева направо, как говорится:&lt;/p&gt;
  &lt;ul id=&quot;dN2j&quot;&gt;
    &lt;li id=&quot;APEo&quot;&gt;&lt;strong&gt;agent-spec2doc&lt;/strong&gt; — превращает постановки от аналитиков в черновик документации;&lt;/li&gt;
    &lt;li id=&quot;jvdr&quot;&gt;&lt;strong&gt;agent-figma&lt;/strong&gt; — генерирует черновик руководства пользователя на основе Figma-макетов;&lt;/li&gt;
    &lt;li id=&quot;zXuf&quot;&gt;&lt;strong&gt;agent-release-notes&lt;/strong&gt; — собирает release notes по репозиторию или Jira-тикетам;&lt;/li&gt;
    &lt;li id=&quot;icB9&quot;&gt;&lt;strong&gt;agent-api-docs&lt;/strong&gt; — делает API-документацию из OpenAPI-спеки;&lt;/li&gt;
    &lt;li id=&quot;2Jpp&quot;&gt;&lt;strong&gt;agent-reviewer&lt;/strong&gt; — ревьюит тексты;&lt;/li&gt;
    &lt;li id=&quot;DTiV&quot;&gt;&lt;strong&gt;agent-transcribe&lt;/strong&gt; — делает расшифровку видео или аудио.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;figure id=&quot;c3lk&quot; class=&quot;m_original&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/7e/ef/7eef9f48-941b-49d2-9dc5-6cff95cae43b.png&quot; width=&quot;947&quot; /&gt;
    &lt;figcaption&gt;Схема работы&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;Tazd&quot;&gt;Эта архитектура появилась в первом коммите проекта — &lt;em&gt;6ff8379 scaffold super-agent with 6 FastAPI services and OpenClaw config&lt;/em&gt;. Там же появился &lt;em&gt;docker-compose.yml&lt;/em&gt;:&lt;/p&gt;
  &lt;pre id=&quot;HcAa&quot;&gt;services:
  agent-spec2doc:
    build: ./agent-spec2doc
    ports:
      - &amp;quot;8001:8001&amp;quot;
    env_file: .env
    networks:
      - agent-network
    restart: unless-stopped

  agent-figma:
    build: ./agent-figma
    ports:
      - &amp;quot;8002:8002&amp;quot;
    env_file: .env
    networks:
      - agent-network
    restart: unless-stopped

  agent-transcribe:
    build: ./agent-transcribe
    ports:
      - &amp;quot;8003:8003&amp;quot;
    env_file: .env
    networks:
      - agent-network
    restart: unless-stopped

  agent-release-notes:
    build: ./agent-release-notes
    ports:
      - &amp;quot;8004:8004&amp;quot;
    env_file: .env
    networks:
      - agent-network
    restart: unless-stopped

  agent-api-docs:
    build: ./agent-api-docs
    ports:
      - &amp;quot;8005:8005&amp;quot;
    env_file: .env
    networks:
      - agent-network
    restart: unless-stopped

  agent-reviewer:
    build: ./agent-reviewer
    ports:
      - &amp;quot;8006:8006&amp;quot;
    env_file: .env
    networks:
      - agent-network
    restart: unless-stopped

  openclaw:
    image: ghcr.io/openclaw/openclaw:latest
    volumes:
      - ./openclaw:/home/node/.openclaw
    env_file: .env
    networks:
      - agent-network
    restart: unless-stopped
    depends_on:
      - agent-spec2doc
      - agent-figma
      - agent-transcribe
      - agent-release-notes
      - agent-api-docs
      - agent-reviewer&lt;/pre&gt;
  &lt;p id=&quot;XZCM&quot;&gt;Отмечу, что перечисленные агенты являются агентами по роли, но технически это обычные HTTP-сервисы, а не внутренние субагенты OpenClaw. Об этом пришлось прямо упомянуть в инструкциях оркестратору: вызывать их через curl, использовать имена из docker compose, не ходить через localhost в контейнере и не запускать дополнительных сессий.&lt;/p&gt;
  &lt;p id=&quot;P41V&quot;&gt;Архитектура агентов держится не только на docker compose, но и на четко установленных границах роли оркестратора. Если не объяснить модели, что она только перенаправляет запросы, она начинает искать «творческие способы помочь» (об этом я расскажу далее).&lt;/p&gt;
  &lt;p id=&quot;Dk4X&quot;&gt;&lt;strong&gt;Промптинг OpenClaw и агентов&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;0My9&quot;&gt;Еще одна немаловажная часть работы — это инструкции. В OpenClaw поведение оркестратора и отдельных сценариев задается обычными Markdown-файлами: &lt;em&gt;AGENTS.md, SOUL.md, USER.md&lt;/em&gt;, а также файлами &lt;em&gt;skills&lt;/em&gt; вроде &lt;em&gt;workspace/skills/release-notes/SKILL.md&lt;/em&gt; или &lt;em&gt;workspace/skills/spec2doc/SKILL.md&lt;/em&gt;.&lt;/p&gt;
  &lt;p id=&quot;0s0W&quot;&gt;В моем случае эти инструкции можно разделить на два уровня.&lt;/p&gt;
  &lt;p id=&quot;2jHs&quot;&gt;&lt;strong&gt;1. Общие правила оркестратора.&lt;/strong&gt; Они лежат в &lt;em&gt;AGENTS.md&lt;/em&gt; и говорят, как классифицировать входящее сообщение, какие есть агенты, по каким URL их вызывать, что делать с ошибками, чего нельзя показывать пользователю и т.д. &lt;/p&gt;
  &lt;p id=&quot;8WUx&quot;&gt;&lt;strong&gt;2. Skills под конкретные задачи.&lt;/strong&gt; Например, &lt;strong&gt;agent-release-notes&lt;/strong&gt; знает, что Jira-ссылки нужно передавать только в &lt;em&gt;/generate-jira&lt;/em&gt;, &lt;strong&gt;agent-transcribe&lt;/strong&gt; — что конвертация видео в текст может занимать несколько минут, а &lt;strong&gt;agent-spec2doc&lt;/strong&gt; — что нельзя писать документацию самостоятельно вместо агента.&lt;/p&gt;
  &lt;p id=&quot;k3Tb&quot;&gt;Промптинг здесь похож не на литературное «будь полезным», а на инструкцию диспетчеру:&lt;/p&gt;
  &lt;pre id=&quot;1HXh&quot;&gt;- классифицируй запрос;
- выбери одного агента;
- вызови его через HTTP;
- дождись результата;
- верни результат как есть;
- не переписывай, не суммаризируй, не запускай второй процесс.&lt;/pre&gt;
  &lt;p id=&quot;zE8k&quot;&gt;Вышеперечисленные файлы стали не менее важной частью системы, чем программный код агентов. Код обрабатывает данные, а инструкции удерживают оркестратор в нужной роли.&lt;/p&gt;
  &lt;h2 id=&quot;denl&quot;&gt;&lt;strong&gt;agent-r&lt;/strong&gt;elease-notes: разбираем в деталях&lt;/h2&gt;
  &lt;p id=&quot;g5jf&quot;&gt;&lt;strong&gt;agent-release-notes&lt;/strong&gt; оказался самым полезным агентом из шести, т.к. работает безотказно и предсказуемо, а также экономит время.&lt;/p&gt;
  &lt;p id=&quot;yqrA&quot;&gt;Агент работает в двух режимах.&lt;/p&gt;
  &lt;p id=&quot;MCO5&quot;&gt;&lt;strong&gt;1. История коммитов&lt;/strong&gt;. Агент получает ссылку на репозиторий и промежуток, за который нужно собрать релиз-ноты. Затем он забирает коммиты, нормализует их и формирует release notes/changelog.&lt;/p&gt;
  &lt;p id=&quot;UfTf&quot;&gt;&lt;strong&gt;2. Jira-задачи&lt;/strong&gt;. Агент получает пачку ссылок на задачи, идет в Jira API, забирает &lt;em&gt;summary, description, тип задачи, статус, компоненты и fix version&lt;/em&gt; и собирает текст release notes/changelog.&lt;/p&gt;
  &lt;p id=&quot;GGdH&quot;&gt;&lt;strong&gt;Пример запроса:&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;qPb8&quot;&gt;Сделай release notes по задачам:
https://jira.example.com/browse/PROJ-1201
https://jira.example.com/browse/PROJ-1198
https://jira.example.com/browse/PROJ-1187

ИЛИ

Сделай release notes по этому репозиторию [ссылка на репозиторий] за период с ДД.ММ.ГГГГ по ДД.ММ.ГГГГ.&lt;/pre&gt;
  &lt;p id=&quot;96o5&quot;&gt;На выходе получается подробный release notes с описанием новых фич, улучшений и багфиксов:&lt;/p&gt;
  &lt;figure id=&quot;Yo7g&quot; class=&quot;m_original&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/2d/d7/2dd75d9e-2e25-42e5-bddc-d0236951b163.png&quot; width=&quot;496&quot; /&gt;
    &lt;figcaption&gt;Ну красота же ж!&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;FaIF&quot;&gt;В первом варианте GitHub-запрос был низкоуровневым: &lt;em&gt;owner, repo, since, branch&lt;/em&gt;. Оркестратор должен был сам разобрать сообщение пользователя и разложить его по полям. Позже, в коммите &lt;em&gt;9a55ac4 feat(agents): refine orchestrator workflows&lt;/em&gt;, я приблизил контракт к реальному пользовательскому вводу: API агента стал принимать &lt;em&gt;repository, date_from, date_to,&lt;/em&gt; а разбор URL и дат переехал в код.&lt;/p&gt;
  &lt;p id=&quot;EqrP&quot;&gt;Первая версия агента могла возвращать сразу и release notes, и changelog (причем на английском), даже если я просил что-то одно, поэтому пришлось внести фикс в схему: в ней появился &lt;em&gt;output_type&lt;/em&gt; со значениями &lt;em&gt;release_notes&lt;/em&gt; или &lt;em&gt;changelog&lt;/em&gt;. Теперь формат выбирает не настроение модели, а параметр запроса.&lt;/p&gt;
  &lt;p id=&quot;WbvJ&quot;&gt;С Jira была отдельная история. Чтобы агент не передавал гигантский HTML и не забивал контекст, чтение тикетов вынесено в код: агент ходит в &lt;em&gt;/rest/api/3/issue/{KEY}&lt;/em&gt; и забирает только нужные поля.&lt;/p&gt;
  &lt;pre id=&quot;ANPb&quot;&gt;resp = requests.get(
    f&amp;quot;{base_url}/rest/api/3/issue/{key}&amp;quot;,
    auth=self._auth,
    params={
        &amp;quot;fields&amp;quot;: &amp;quot;summary,issuetype,status,description,labels,components,fixVersions&amp;quot;
    },
    timeout=REQUEST_TIMEOUT,
)&lt;/pre&gt;
  &lt;p id=&quot;tBNz&quot;&gt;Кроме того, в инструкции оркестратора это закреплено как правило: Jira-ссылки нельзя открывать через браузер или web-fetch, а передавать в release-notes их нужно только через &lt;em&gt;/generate-jira&lt;/em&gt;.&lt;/p&gt;
  &lt;pre id=&quot;OhSl&quot;&gt;- For Jira issue URLs, never use &amp;#x60;web_fetch&amp;#x60;, &amp;#x60;web_search&amp;#x60;, browser tools, or direct page scraping.
- Jira URLs must be passed only to &amp;#x60;agent-release-notes&amp;#x60; via &amp;#x60;/generate-jira&amp;#x60;.&lt;/pre&gt;
  &lt;p id=&quot;0gyT&quot;&gt;&lt;strong&gt;Вывод:&lt;/strong&gt; LLM хорошо упаковывает смысл, но плохо подходит для всей механики вокруг задачи. URL, даты, форматы, API-ошибки и HTML-страницы лучше отдавать обычному коду.&lt;/p&gt;
  &lt;h2 id=&quot;Phlz&quot;&gt;agent-figma и agent-transcribe: ожидание не совпало с реальностью&lt;/h2&gt;
  &lt;p id=&quot;bA1g&quot;&gt;Конечно, не все было идеально (ну, а как иначе...) и два следующих агента показали, что если что-то работает локально, то не факт, что заработает в Docker.&lt;/p&gt;
  &lt;h3 id=&quot;BFqb&quot;&gt;agent-figma: осторожно, &lt;s&gt;двери закрываются&lt;/s&gt; Docker закрывается&lt;/h3&gt;
  &lt;p id=&quot;ww6V&quot;&gt;Этот агент переродился из агента, которого я представлял в этом году в своем докладе на Techwriter Days 3. Тот агент работал так: получал ссылку на Figma-макет, шел в Figma REST API, получал структуру слоев и генерировал черновик руководства пользователя.&lt;/p&gt;
  &lt;p id=&quot;eFp3&quot;&gt;Я попробовал перенести его в Docker и тут начался сущий кошмар. Как можно увидеть из истории проекта, в коммите &lt;em&gt;380cd3f fix(figma): handle API access limitations with fallback&lt;/em&gt;: в сообщении прямо указано, что Figma API из Docker блокировался CloudFront с ошибкой 403.&lt;/p&gt;
  &lt;p id=&quot;41oa&quot;&gt;Я попробовал сделать клиент аккуратнее: сначала запрос без токена для публичных файлов, потом повтор с токеном, отдельная обработка 401, 403, 404 и 429. После многих бесплодных попыток я плюнул и сделал вывод: «Не работает Figma API из контейнера? Да и Huyndai с ним!».&lt;/p&gt;
  &lt;figure id=&quot;DoZK&quot; class=&quot;m_original&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/f8/eb/f8eb26bd-c5fd-4f06-90b5-1b5638cf9df3.png&quot; width=&quot;433&quot; /&gt;
    &lt;figcaption&gt;А так все красиво представлялось...&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;CMFy&quot;&gt;В итоге пользовательский путь стал таким: агент получает PNG/JPEG-вариант макета, а агент по нему составляет черновик. Да, топорно и не так элегантно, зато отпадает зависимость от CloudFront и лимитов Figma REST API (а то, честно говоря, раздражало ловить ошибку 429 после пятой генерации).&lt;/p&gt;
  &lt;figure id=&quot;v0w4&quot; class=&quot;m_original&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/14/c8/14c8dac2-d450-46c7-ab86-4186812d11a4.png&quot; width=&quot;794&quot; /&gt;
    &lt;figcaption&gt;Уот так уот&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;1yxx&quot;&gt;Дополнительно в skill для Figma я вынес правило, что если агенту пришла ссылка &lt;em&gt;figma.com/...&lt;/em&gt;, то нужно попросить скриншот, а не вызывать &lt;strong&gt;agent-figma&lt;/strong&gt;.&lt;/p&gt;
  &lt;pre id=&quot;aRjm&quot;&gt;Если пользователь прислал ссылку &amp;#x60;figma.com/...&amp;#x60;, не вызывай &amp;#x60;agent-figma&amp;#x60;.
Ответь:
&amp;#x60;Figma-ссылки сейчас не разбираю напрямую. Пришли скриншот нужного экрана или фрейма — я составлю user guide по изображению.&amp;#x60;&lt;/pre&gt;
  &lt;p id=&quot;fDk2&quot;&gt;Проще говоря, лучше устойчивый сценарий с небольшими «телодвижениями», чем красивый, но нерабочий.&lt;/p&gt;
  &lt;h3 id=&quot;9n70&quot;&gt;agent-transcribe: размеры, форматы и болтливый оркестратор&lt;/h3&gt;
  &lt;p id=&quot;5OIQ&quot;&gt;В случае с этим агентом все уперлось в более приземленные ограничения.&lt;/p&gt;
  &lt;p id=&quot;4SFo&quot;&gt;Первое — размер. Telegram API не пропускает большие файлы и никаким промптом это не починить. Второе — формат. В моем сценарии MOV-файлы не проходили, поэтому приходилось переконвертировать видео в поддерживаемый формат.&lt;/p&gt;
  &lt;figure id=&quot;qHkp&quot; class=&quot;m_original&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/f8/d5/f8d5a63b-dd7d-4213-ba4b-ea314b0656a9.png&quot; width=&quot;439&quot; /&gt;
    &lt;figcaption&gt;Если долго мучиться...&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure id=&quot;eRM7&quot; class=&quot;m_original&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/cc/70/cc7017f3-be49-499a-8f9b-1e3b7564cb18.png&quot; width=&quot;413&quot; /&gt;
    &lt;figcaption&gt;...то фигня получится&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;SMWN&quot;&gt;Позже в коммите &lt;em&gt;d5f2602 feat(agents): add media link transcription&lt;/em&gt; для больших файлов появился обходной путь: я добавил эндпоинт &lt;em&gt;/transcribe/url&lt;/em&gt;. За счет этого можно было отправлять публичную ссылку на медиафайл, а агент ее сам скачивает, конвертирует, распознает в текст, обрабатывает и выдает пересказ видео.&lt;/p&gt;
  &lt;p id=&quot;EOmL&quot;&gt;В коде также появилась нормализация Google Drive-ссылок и проверка размера не только по &lt;em&gt;content-length&lt;/em&gt;, но и по фактически скачанным байтам. Это как раз та механика, которую лучше держать в коде, а не объяснять модели словами.&lt;/p&gt;
  &lt;p id=&quot;42pl&quot;&gt;Еще один прикол выкинул оркестратор. Пока &lt;strong&gt;agent-transcribe&lt;/strong&gt; работал над медиафайлом, OpenClaw начинал присылать в Telegram промежуточные статусы &lt;em&gt;Sifting...&lt;/em&gt;, &lt;em&gt;Process: fast-shell&lt;/em&gt;, &lt;em&gt;Process: young-forest&lt;/em&gt;. Выглядело как лишний шум и заставляло психовать от обилия сообщений.&lt;/p&gt;
  &lt;figure id=&quot;apPV&quot; class=&quot;m_retina&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/f0/11/f011ce29-b186-42cb-a505-7c66190fe7dc.jpeg&quot; width=&quot;288&quot; /&gt;
    &lt;figcaption&gt;ааааааааа&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;figure id=&quot;bqYw&quot; class=&quot;m_retina&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/05/2c/052c967f-5d78-47ac-973e-ee062c500c5c.jpeg&quot; width=&quot;288&quot; /&gt;
    &lt;figcaption&gt;АААААААААААААА&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;Q1Lj&quot;&gt;Вылечился этот «недуг» изменением конфигурации OpenClaw и инструкций оркестратора. Я отключил потоковые статусы и уведомления о завершении команд, а в инструкциях отдельно прописал, что при распознавании нужно ждать до 900 секунд, не запускать повторный запрос, не говорить, что процесс не завершился, пока агент сам не вернет ошибку:&lt;/p&gt;
  &lt;pre id=&quot;HFiY&quot;&gt;- Таймаут для &amp;#x60;/transcribe&amp;#x60; и &amp;#x60;/transcribe/url&amp;#x60; — не меньше 900 секунд.
- Если &amp;#x60;exec&amp;#x60; вернул активную process-сессию, продолжай ждать эту же сессию.
- Не запускай повторный запрос, пока первый еще выполняется.
- Не называй процесс упавшим, пока команда или агент реально не вернули ошибку.&lt;/pre&gt;
  &lt;h2 id=&quot;Ie23&quot;&gt;Еще немного про поехавший оркестратор&lt;/h2&gt;
  &lt;p id=&quot;tXrt&quot;&gt;С &lt;strong&gt;agent-spec2doc&lt;/strong&gt; тоже произошла забавная история. Первое время агент иногда возвращал пустой ответ по непонятным причинам. Оркестратор видел, что задача вроде бы не выполнена, писал в чат что-то в духе «агент не отвечает, сделаю работу за него» и начинал генерировать документацию самостоятельно.&lt;/p&gt;
  &lt;figure id=&quot;Up3E&quot; class=&quot;m_original&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/25/b5/25b5d6d9-e918-4257-963d-46dc0ebecd66.png&quot; width=&quot;1004&quot; /&gt;
    &lt;figcaption&gt;Инициативный какой!&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;AxVD&quot;&gt;Как уже и говорилось выше, оркестратор должен оркестрировать, а агенты — выполнять запросы. Если оркестратор начнет подхватывать чужую работу, то выйдет черт-те что.&lt;/p&gt;
  &lt;p id=&quot;fzw5&quot;&gt;Поэтому я внес фикс &lt;em&gt;5676d00 fix(agents): harden documentation workflows. &lt;/em&gt;До него &lt;strong&gt;agent-spec2doc&lt;/strong&gt; мог вернуть пустую строку как будто это нормальный результат:&lt;/p&gt;
  &lt;pre id=&quot;c4K3&quot;&gt;return response.choices[0].message.content or &amp;quot;&amp;quot;&lt;/pre&gt;
  &lt;p id=&quot;jzFE&quot;&gt;После фикса пустой ответ стал ошибкой:&lt;/p&gt;
  &lt;pre id=&quot;GG6X&quot;&gt;content = (response.choices[0].message.content or &amp;quot;&amp;quot;).strip()
if not content:
    raise GenerationError(&amp;quot;LLM вернул пустой черновик документации&amp;quot;)&lt;/pre&gt;
  &lt;p id=&quot;bfr5&quot;&gt;Одновременно в инструкциях появился прямой запрет на составление черновика вместо &lt;strong&gt;agent-spec2doc&lt;/strong&gt;:&lt;/p&gt;
  &lt;pre id=&quot;GeuL&quot;&gt;- Service &amp;#x60;result&amp;#x60; must be returned exactly as provided: no prefixes, no commentary, no bullet conversion, no summarizing.
- If a service returns &amp;#x60;result&amp;#x60;, send exactly that &amp;#x60;result&amp;#x60; to the user without rewriting, evaluating, or adding commentary.
- If a service returns &amp;#x60;error&amp;#x60;, reply in Russian with a short &amp;quot;service error&amp;quot; message and include the error text.
- If &amp;#x60;result&amp;#x60; is empty and &amp;#x60;error&amp;#x60; is empty, reply in Russian that the service returned an empty result and ask the user to repeat the request or send the source material again.&lt;/pre&gt;
  &lt;p id=&quot;QS8A&quot;&gt;Позже это правило было перенесено на всех агентов: если агент вернул &lt;em&gt;result&lt;/em&gt;, оркестратор должен вернуть именно &lt;em&gt;result&lt;/em&gt;, без префиксов, комментариев, пересказа и «улучшений». А если процесс еще выполняется — ждать, а не отправлять пользователю промежуточные статусы.&lt;/p&gt;
  &lt;p id=&quot;2RAt&quot;&gt;Короче говоря, промптинг в некоторых случаях — по-прежнему наше все. Оркестратору мало сказать «перенаправляй запросы», нужно ж еще прописать, чего не стоит делать, когда агент молчит или возвращает пустой ответ.&lt;/p&gt;
  &lt;h2 id=&quot;1j2U&quot;&gt;Еще два агента: api-docs и reviewer&lt;/h2&gt;
  &lt;p id=&quot;kGko&quot;&gt;Про &lt;strong&gt;agent-spec2doc&lt;/strong&gt; и &lt;strong&gt;agent-figma&lt;/strong&gt; я уже рассказал выше, поэтому здесь коротко остановлюсь на двух оставшихся агентах, которые закрывают более точечные задачи.&lt;/p&gt;
  &lt;p id=&quot;r66G&quot;&gt;&lt;strong&gt;agent-spec2doc&lt;/strong&gt; я создавал для ситуаций, когда вместо нормальной документации на руках есть только OpenAPI-спецификация в YAML или JSON. Формально это уже «документация», но на практике читать такую спеку как пользовательский материал неудобно: много служебных полей, схем, параметров, кодов ответа, но мало нормального объяснения.&lt;/p&gt;
  &lt;p id=&quot;sUSz&quot;&gt;Агент принимает OpenAPI-файл, разбирает эндпоинты и возвращает более человекочитаемый черновик: назначение метода, параметры запроса, тело, ответы, ошибки и примеры. Это не заменяет полноценную API-документацию, но хорошо закрывает первый проход: вместо пустого листа уже есть структура, которую можно проверить, уточнить и привести к стилю проекта.&lt;/p&gt;
  &lt;figure id=&quot;QKxa&quot; class=&quot;m_original&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/b6/de/b6debc2c-b76f-49fe-9119-04f357055120.png&quot; width=&quot;671&quot; /&gt;
    &lt;figcaption&gt;Типа API-дока&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;XPDV&quot;&gt;&lt;strong&gt;agent-reviewer&lt;/strong&gt; — это «проверятор», который сверяет текст со стайлгайдом и возвращает список замечаний.&lt;/p&gt;
  &lt;p id=&quot;15iB&quot;&gt;Сценарий такой: сначала агенту нужно скормить стайлгайд, потом ему можно отправлять текст, а он возвращает замечания и рекомендации по исправлению.&lt;/p&gt;
  &lt;p id=&quot;6inJ&quot;&gt;Собственно, вот как это выглядит:&lt;/p&gt;
  &lt;figure id=&quot;yBML&quot; class=&quot;m_original&quot; data-caption-align=&quot;center&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/0e/07/0e07d332-735d-4ee0-8e46-f950ad794c29.png&quot; width=&quot;487&quot; /&gt;
    &lt;figcaption&gt;Типа ревью&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;yYeq&quot;&gt;Причем стайлгайд не нужно передавать при каждом ревью, он загружается один раз и хранится в памяти.&lt;/p&gt;
  &lt;p id=&quot;WJsw&quot;&gt;Этот ревьюер хорош для первого прохода по формальным правилам. Но финальное решение все равно остается за автором (то бишь мной): иногда стайлгайд нужно применить строго, а иногда осознанно отступить от него ради смысла или читаемости.&lt;/p&gt;
  &lt;h2 id=&quot;uVxn&quot;&gt;Делегирование и замена. В чем разница?&lt;/h2&gt;
  &lt;p id=&quot;Qmvh&quot;&gt;Дабы упредить возможные упреки вроде &lt;em&gt;«Из-за тебя скоро нас, техписателей, заменят на ИИ-шницу»&lt;/em&gt;, подчеркну: это не замена, а делегирование. И вот в чем разница:&lt;/p&gt;
  &lt;p id=&quot;lGZo&quot;&gt;&lt;strong&gt;Замена&lt;/strong&gt; — это когда ИИ делает все работы по документации, от сбора знаний до финального результата, а специалист превращается в «технического читателя»: видит, что выдала машина, и все. В итоге смысл утерян, ответственность размыта и ничего хорошего из этого не будет.&lt;/p&gt;
  &lt;p id=&quot;AiFC&quot;&gt;&lt;strong&gt;Делегирование&lt;/strong&gt; — это когда механическую работу делает ИИ, а смысловую — специалист. Агент разбирает артефакты, готовит черновики и делает за несколько минут то, что вручную заняло бы полчаса-час. Специалист получает черновик, проверяет галлюцинации, принимает финальное решение и несет ответственность за результат целиком.&lt;/p&gt;
  &lt;p id=&quot;xzHZ&quot;&gt;Ключевое слово здесь — «ответственность», которую целиком и полностью несу я. Именно поэтому все, что выдает агент — это всегда черновик, а не финальный документ.&lt;/p&gt;
  &lt;h2 id=&quot;ZUEm&quot;&gt;Бэклог: что планирую доделать&lt;/h2&gt;
  &lt;p id=&quot;2Ndh&quot;&gt;Сейчас проект находится в состоянии &lt;s&gt;«работает — не трожь»&lt;/s&gt; «работает, но есть куда расти». И вот в какие стороны планируется расти:&lt;/p&gt;
  &lt;ul id=&quot;qdxP&quot;&gt;
    &lt;li id=&quot;KILQ&quot;&gt;реализовать хранение контекста предыдущих задач, чтобы заново не объяснять одно и то же (дополнительно подключал внешний OpenClaw-скилл self-improving-agent, но пока что не увидел от него существенной пользы);&lt;/li&gt;
    &lt;li id=&quot;KOsv&quot;&gt;довести до ума сценарий, когда бот долго молчит во время работы и пишет только финальный результат;&lt;/li&gt;
    &lt;li id=&quot;y6rr&quot;&gt;прикрутить версионирование промптов, чтобы откатываться к рабочим версиям промптов, если вдруг что-то ломается;&lt;/li&gt;
    &lt;li id=&quot;ecx1&quot;&gt;встроить автоматическую проверку результата другой LLM перед тем, как черновик попадет ко мне;&lt;/li&gt;
    &lt;li id=&quot;ij6v&quot;&gt;унифицировать промпты по агентам и оркестратору, т.к. сейчас часть из них на русском, часть — на английском;&lt;/li&gt;
    &lt;li id=&quot;yjEN&quot;&gt;возможно, вынесу все на сервер для доступа 24/7, но вопрос пока открытый, т.к. с одной стороны, хочется автономности, а с другой, вроде бы и нет смысла платить за сервер, если агентом пользуюсь в основном в рабочее время.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;fGct&quot;&gt;Надеюсь, статья вам понравилась. Если у вас есть опыт с похожими решениями или идеи по любому из этих пунктов — пишите в комментарии или личные сообщения.&lt;/p&gt;

</content></entry></feed>