Разбираемся, что такое харнес в AI-агентах: как LLM с инструментами и циклом превращается в агента, и почему харнес — это скрытая логика, управляющая выполнением.
Вы когда-нибудь задумывались, что превращает обычную языковую модель в настоящего AI-агента, способного самостоятельно решать задачи? Многие думают, что достаточно просто дать LLM доступ к инструментам — и вот он, агент. Но на деле ключевой компонент остаётся в тени: харнес. В этой статье мы разберём, что такое харнес, как он работает и почему без него любой агент — просто болванка.
Саймон Уиллисон, известный разработчик и создатель Django REST framework, дал простое и ёмкое определение: AI-агент — это языковая модель (LLM), снабжённая инструментами, работающая в цикле для достижения цели. Разберём каждый элемент.
Инструменты — это функции, которые LLM может вызвать для получения данных или выполнения действий. Например, функция поиска в интернете, калькулятор или API для работы с базой данных. Механизм function calling позволяет модели не просто генерировать текст, а возвращать структурированный запрос на вызов функции. Вот пример на Python:
import openai
def search_web(query: str) -> str:
"""Поиск в интернете"""
# Здесь был бы реальный вызов API поисковика
return f"Результаты по запросу: {query}"
# Пример вызова функции из LLM
response = openai.ChatCompletion.create(
model="gpt-4",
messages=[{"role": "user", "content": "Найди последние новости о Python"}],
functions=[{
"name": "search_web",
"description": "Поиск информации в интернете",
"parameters": {
"type": "object",
"properties": {
"query": {"type": "string"}
},
"required": ["query"]
}
}]
)
# Обрабатываем вызов функции
if response.choices[0].message.get("function_call"):
func_call = response.choices[0].message["function_call"]
if func_call["name"] == "search_web":
args = json.loads(func_call["arguments"])
result = search_web(args["query"])
print(result)Цикл — это программная проверка вывода модели: завершена ли задача? Если нет — агент продолжает вызывать инструменты, анализировать результаты и уточнять запросы. Реализация цикла может выглядеть так:
def run_agent(task: str, max_iterations: int = 10):
messages = [{"role": "user", "content": task}]
for i in range(max_iterations):
response = openai.ChatCompletion.create(
model="gpt-4",
messages=messages,
functions=[...]
)
msg = response.choices[0].message
if msg.get("function_call"):
# Выполняем функцию и добавляем результат в историю
func_result = execute_function(msg["function_call"])
messages.append(msg)
messages.append({"role": "function", "name": msg["function_call"]["name"], "content": func_result})
else:
# Если функция не вызвана — считаем задачу выполненной
return msg["content"]
return "Не удалось завершить за максимальное число итераций"Харнес (harness) — это вся инфраструктура после LLM: логика цикла, управление инструментами, обработка ошибок, планирование шагов. Многие путают харнес с интерфейсом (UI), но это разные вещи. Интерфейс — это то, что видит пользователь: чат, кнопки, панель. Харнес — это невидимая «сантехника», которая решает, продолжать ли агенту работу или завершить.
Например, один и тот же харнес может работать с разными интерфейсами: веб-чат, Telegram-бот, API. И наоборот, один интерфейс может подключаться к разным харнесам. Вот почему можно заменить интерфейс, не трогая логику агента.
class AgentHarness:
def __init__(self, llm, tools):
self.llm = llm
self.tools = {t.name: t for t in tools}
self.history = []
def step(self, user_input: str) -> str:
self.history.append({"role": "user", "content": user_input})
response = self.llm.generate(self.history, self.tools_schema())
if response.function_call:
tool = self.tools[response.function_call.name]
result = tool.execute(**response.function_call.args)
self.history.append(response.message)
self.history.append({"role": "tool", "content": result})
return self.step("Продолжи") # рекурсивный цикл
else:
return response.content
def tools_schema(self):
return [t.schema for t in self.tools.values()]Если вы создаёте AI-агента, не зацикливайтесь на интерфейсе. Сначала спроектируйте харнес: какие инструменты нужны, как будет выглядеть цикл принятия решений, как обрабатывать ошибки. Начните с простого цикла из трёх шагов: запрос → вызов инструмента → проверка результата. Постепенно усложняйте, добавляя планирование и проверку завершённости.
Попробуйте написать своего первого агента с харнесом на Python, используя библиотеку openai и несколько простых функций. Убедитесь, что харнес может работать без UI — через командную строку или API. Это даст вам гибкость подключать любой интерфейс позже.
Хочешь закрепить знания на практике?
Решай задачи на Algolit — интерактивная платформа для обучения
Начать бесплатно →