Все статьи
· 9 мин чтения

Харнес агента: Что превращает тупую LLM в автономного работягу 🫡

Разбираю, что такое харнес агента — обвязка вокруг LLM, которая делает из генератора текста рабочую лошадку: цикл, вызов инструментов, контекст, песочница. Как жили без него и минимальный харнес на 20 строк Python. Без воды, с кодом и шизой.

Харнес агента: Что превращает тупую LLM в автономного работягу 🫡

Харнес агента: Что превращает тупую LLM в автономного работягу 🫡

Ну чё, малютки, думаете что GPT-5.2 или Claude сами по себе чинят вам код, гоняют тесты и заказывают такси? Поздравляю, вас обманули маркетологи. Голая LLM — это функция текст → текст: суёшь ей строку, получаешь обратно другую строку. Ни памяти, ни рук, ни глаз. Сама по себе она не откроет даже пустой файл.

А «агент» из рекламы — это та же самая модель, просто посаженная в харнес. Обвязка, которая приделывает болтливому попугаю руки и пинает его работать, пока дело не сделано.

🔥Суть за 10 секунд

Харнес (harness, «упряжь») — это вся инфраструктура вокруг LLM: цикл «подумал → сделал → посмотрел», вызов инструментов, управление контекстом, песочница для выполнения и парсинг ответов. Модель — это мозг. Харнес — это тело, руки и нервная система. Claude Code, Cursor, OpenClaw — это всё харнесы поверх одних и тех же моделей.

Короче, в этом посте разложу по полочкам: что такое харнес и нахуя он нужен, как страдальцы жили без него, из каких слоёв он состоит, и соберу минимальный рабочий харнес на 20 строк Python — чтобы вы пощупали, что там внутри.


Что такое харнес и нахуя он нужен

Смотри, малютки. Всё, что умеет LLM сама по себе — предсказывать следующий токен. Не помнит прошлый запрос, не откроет файл, не запустит команду, не узнает, сработал её ответ или нет. Каждый вызов — с чистого листа, stateless.

💡Аналогия для тех, кто не в теме

Представь мозг гения в банке. Он гениально рассуждает, но у него нет глаз, рук и памяти дольше одного разговора. Чтобы он что-то сделал в реальном мире, кто-то должен: читать ему вслух задачу, выполнять его указания руками, и пересказывать, что получилось. Этот «кто-то» — и есть харнес.

Харнес добавляет модели три вещи, которых у неё нет от рождения:

1Руки — инструменты (tools): прочитать файл, запустить команду, сходить в интернет, дёрнуть API
2Память — контекст: что уже сделали, что узнали, история диалога
3Цикл — модель работает не один раз, а крутится в петле «думай → действуй → наблюдай», пока задача не решена

Без харнеса у тебя чат-бот: спросил — ответил. С харнесом — агент: принёс задачу, ушёл, вернулся с результатом.

Голая LLM против LLM в харнесе: мозг в банке vs мозг в механическом теле с инструментами


Как жили без харнеса (раннее средневековье, 2015–2023)

А теперь, малютки, ностальгия. Когда вышел ChatGPT, никаких харнесов не было. Был ты, окно браузера и буфер обмена. Исполнителем инструкций был ты сам.

Алгоритм работы «AI-инженера» в 2023:

1Спросил у модели, как пофиксить баг
2Она написала: «запусти вот эту команду и покажи вывод»
3Ты руками запустил команду в терминале
4Скопировал вывод, вставил обратно в чат
5Модель: «ага, теперь поправь файл вот так»
6Ты руками поправил. И так по кругу, пока не заработает (или пока не надоест)

Чувствуешь? Ты и был харнесом. Медленным, на ручном приводе, с копипастой через буфер обмена. Модель думала — а всю беготню (читать файлы, запускать команды, носить результаты туда-сюда) делал живой человек.

Ручных действий с твоей стороны: 6
🩸ТЫ, вручнуюКопируешь логи из терминала
🩸ТЫ, вручнуюВставляешь в окно ChatGPT
🧠LLM«Похоже на NullPointer, покажи user.py»
🩸ТЫ, вручнуюОткрываешь файл, копируешь, вставляешь обратно
🧠LLM«Добавь проверку на None вот сюда»
🩸ТЫ, вручнуюРуками правишь файл по инструкции
🩸ТЫ, вручнуюСам запускаешь pytest в терминале
🩸ТЫ, вручнуюКопируешь вывод тестов обратно в чат
🧠LLM«Отлично, всё зелёное 🎉»
Заметил? Исполнитель — это ТЫ. Ты и был тем самым харнесом, только медленным и на ручном приводе.

Народ, конечно, пытался это автоматизировать промптами. Появился паттерн ReAct (Reasoning + Acting): модель просили выводить мысли в формате Thought: … / Action: … / Observation: …, а потом регэкспами выдирали Action из текста и выполняли. Так собрали первый примитивный харнес — кривой, на парсинге строк, но он работал.

⚠️⚠️ Почему это была боль

Модель — болтливая. Она могла вместо Action: search("погода") написать «Ну, я думаю, наверное стоит поискать погоду, давай я это сделаю». Регэксп ломался, парсер падал, агент уходил в небытие. Парсинг текста — самое хрупкое место раннего харнеса. Спасение пришло, когда модели научили нативному tool-calling — структурированному JSON вместо угадывания по тексту.


Анатомия харнеса: 5 слоёв

Окей, малютки, теперь самое вкусное — что там внутри. Любой харнес, от Claude Code до твоего самописного, состоит из пяти слоёв. Тыкай по кольцам — внутри ядро-LLM, вокруг обвязка:

🧅 Анатомия харнеса — кликай по слоям
В центре — мозг (LLM). Вокруг — пять слоёв обвязки. Тыкни любой, чтобы узнать, что он делает и что ломается без него.
🛡️
⚙️
🧠
🔧
🔁
🧠LLM
🔁Agent loop
Цикл think → act → observe. Гоняет модель, пока задача не решена.
💥 Без него агент отвечает один раз и затыкается — это просто чат.

А вот как эти слои оживают в реальном цикле — жми «Запустить» и смотри, как модель и харнес перекидывают работу друг другу:

🔁 Цикл агента: think → act → observe
LLM думает и просит инструмент. Харнес исполняет и кладёт результат обратно в контекст. Повторяем, пока не готово.
🧠ДумаетLLM
🔧Вызов toolLLM
⚙️ИсполняетХАРНЕС
👁️НаблюдаетХАРНЕС
↩︎
Итерация 1 из 3
📜 Контекст накапливается:
🧠
ДумаетЮзер просит починить баг. Сначала надо посмотреть, что в логах.
Вот что тут главное

Смотри на ярлыки LLM и ХАРНЕС в цикле. Модель только думает и просит. Всё реальное — открыть файл, запустить тест, поймать вывод — делает харнес. Поменяй модель, а харнес оставь — агент продолжит работать. Поменяй харнес — изменится всё.


Минимальный харнес на Python (~20 строк) 🔥

Хватит теории, малютки. Самый честный способ понять харнес — собрать его. Вот полноценный агентный цикл на голом Python + любой LLM с tool-calling. Никаких фреймворков.

import json
from openai import OpenAI  # подойдёт любой клиент с tool-calling

client = OpenAI()

# --- Слой 2: инструменты (руки агента) ---
def run_shell(cmd: str) -> str:
    import subprocess
    # ponytail: для демо — реальный харнес гоняет это в песочнице, а не голым
    out = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=30)
    return (out.stdout + out.stderr)[:4000]  # режем, чтобы не взорвать контекст

TOOLS = [{
    "type": "function",
    "function": {
        "name": "run_shell",
        "description": "Выполнить shell-команду и вернуть вывод",
        "parameters": {
            "type": "object",
            "properties": {"cmd": {"type": "string"}},
            "required": ["cmd"],
        },
    },
}]

# --- Слой 3: контекст (память агента) ---
messages = [{"role": "user", "content": "Сколько .py файлов в текущей папке? Посчитай."}]

# --- Слой 1: agent loop (сердце) ---
for _ in range(10):  # лимит итераций — иначе бесконечный цикл
    resp = client.chat.completions.create(
        model="gpt-5.2", messages=messages, tools=TOOLS,
    ).choices[0].message
    messages.append(resp)

    if not resp.tool_calls:        # модель сказала «готово» — отдаём ответ
        print(resp.content)
        break

    for call in resp.tool_calls:   # модель попросила инструмент — исполняем
        args = json.loads(call.function.arguments)   # слой 5: парсинг
        result = run_shell(**args)                   # слой 4: тут была бы песочница
        messages.append({                            # слой 3: результат назад в контекст
            "role": "tool",
            "tool_call_id": call.id,
            "content": result,
        })

Вот и весь харнес, малютки. Цикл for, который гоняет модель, исполняет её запросы инструментами и складывает результаты обратно в messages. Всё остальное — Claude Code, Cursor, LangGraph — это тот же цикл, только обвешанный песочницами, компакцией контекста, сотней инструментов и красивым UI.

Что мы только что собрали

Модель сама сообразит выполнить ls *.py | wc -l, дёрнет run_shell, получит число и выдаст человеческий ответ. Заметь: ты нигде не написал «как считать файлы». Ты дал руки и цикл, а думать оставил модели.


Контекст — главная головная боль харнеса

Малютки, если думаете что цикл и инструменты — это сложно, то добро пожаловать в ад под названием управление контекстом. Это слой, на котором ломается большинство агентов.

Проблема простая: окно контекста конечно. Каждая итерация цикла добавляет в messages новые данные — мысли модели, вызовы, вывод команд (а вывод бывает на тысячи строк). Через 20 шагов отладки твой контекст забит под завязку.

Поиграйся сам — добавляй данные в контекст, доводи до переполнения и жми «Сжать»:

📜 Окно контекста — заполни и сожми
Добавляй данные в контекст и смотри, как он забивается. Переполнил — жми «Сжать», харнес свернёт историю в саммари.
Заполнено8K / 200K
Контекст просторный — модели легко думать.

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

✂️ КомпакцияСжатие

Старую часть истории харнес сжимает в краткое саммари: «починили баг X, тесты прошли». Детали выкинуты, суть осталась. Claude Code делает это автоматически при заполнении окна.

📏 Усечение выводаОбрезка

Команда выплюнула 5000 строк лога? Харнес отдаёт модели последние 100. Полный вывод модели обычно не нужен — нужен хвост с ошибкой.

🔍 Подгрузка по требованиюRAG

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

🧹 Изоляция подзадачСубагенты

Жирную подзадачу харнес отдаёт отдельному субагенту со своим чистым контекстом. Тот возвращает только результат — вся его грязь не засоряет главный контекст.

🔥Вот в чём засада

80% «тупизны» агентов — это не модель тупая, а харнес плохо управляет контекстом. Засрал окно мусором, не сжал историю, напихал нерелевантного — и гениальная модель захлёбывается в шуме. Качество агента = качество модели × качество управления контекстом.


Реальные харнесы: кто есть кто

Ладно, малютки, теория — это хорошо, но вы пользуетесь конкретными харнесами каждый день. Вот кто из чего:

🛠️ Реальные харнесы — фильтруй и раскрывай
Все крутятся поверх одних и тех же моделей. Разница — в харнесе. Тыкни, чтобы увидеть фишку каждого.
Claude CodeCLICLI-агент для кода
Агрессивная компакция контекста, субагенты, права на каждое действие.
Cursor / WindsurfIDEIDE с агентом
AiderCLICLI для парного кодинга
OpenClawCLIОпенсорсный агент-рой
LangGraphФреймворкКонструктор агентов
OpenAI Agents SDKФреймворкОфициальный тулкит
💡Вот что важно понять

Все они крутятся поверх одних и тех же моделей (Claude, GPT, Gemini). Берёшь одну и ту же Claude, суёшь в наколеночный цикл — агент тупит и ходит по кругу. Суёшь в Claude Code — внезапно «сам всё сделал». Модель та же. Поменялась только обвязка.

Разные харнесы поверх общего слоя моделей


Подводные камни 🗑️🔥

Прежде чем побежите писать свой харнес — вот на чём все спотыкаются:

⚠️♾️ Бесконечные циклы

Агент застрял: думает → действует → не получается → думает то же самое → по кругу до конца света (и до конца твоего баланса на API). Всегда ставь лимит итераций и детект «топчемся на месте». В минимальном примере выше это range(10) — не убирай его.

⚠️☠️ Отравление контекста (context poisoning)

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

⚠️🎭 Галлюцинация вызовов

Модель «вызывает» инструмент, которого нет, или суёт кривые аргументы. Слой валидации (5) должен ловить это и возвращать ошибку модели, а не падать. Никогда не доверяй, что вызов корректен — проверяй.

⚠️💸 Цена

Каждая итерация цикла — это полный прогон контекста через модель. 20 шагов с жирным контекстом = 20 раз оплатил весь контекст. Плохой харнес, который не сжимает контекст, жжёт деньги в разы быстрее. Токены — это твой счёт.

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

🧰 Собери свой харнес
Задача: «почини баг и прогони тесты». Выключай слои харнеса и запускай — смотри, что именно ломается без каждого.

Итого, малютки 🫡

🔥Главный вывод

Харнес — это то, что превращает LLM в агента. Модель только думает; руки, память, цикл и песочницу даёт обвязка вокруг неё. Раньше этой обвязкой работал ты сам — глазами, руками и буфером обмена. Теперь за тебя пашут Claude Code и компания.

Про харнес почти никто не пишет, и зря. Все меряются бенчмарками моделей, лярдами параметров и MoE, а агенты за последний год скакнули в автономности по другой причине — обвязка повзрослела. Научилась жать контекст, гонять код в песочнице и не зацикливаться насмерть. Хочешь реально разобраться в агентах — собери свой харнес на 20 строк и поломай его об боевые задачи. Это даст больше, чем сотня тредов в X. Вперёд, малютки.


Источники

  1. ReAct: Synergizing Reasoning and Acting in Language Models — arXiv
  2. Building Effective Agents — Anthropic
  3. Function calling — OpenAI docs
  4. Effective context engineering for AI agents — Anthropic
  5. LangGraph — концепции агентов