AI-агенты и автоматизация Собрать руками
Как собрать агента с tool-calling
Tool-calling — это сердце современного AI-агента. В этом гайде вы соберёте рабочий агент «руками», пройдя путь от концепции до отладки и evals.
Что такое tool-calling и зачем он нужен
Tool-calling — это механизм, при котором LLM не просто генерирует текст, а формирует структурированный запрос к внешнему инструменту (API, функции, скрипту). Это превращает LLM из «разговорного интерфейса» в автономного исполнителя. Без tool-calling агент не может взаимодействовать с реальными системами: базами данных, CRM, платёжными шлюзами и т.д.
Цикл мышления агента с tool-calling
flowchart TD
A[Пользователь] -->|Запрос| B[Контекст + Инструкция]
B --> C[LLM: Планирование]
C --> D{Нужен ли инструмент?}
D -->|Да| E[Генерация tool_call]
D -->|Нет| F[Генерация ответа]
E --> G[Исполнение инструмента]
G --> H[Результат инструмента]
H --> I[LLM: Синтез ответа]
I --> J[Ответ пользователю]
F --> J
Минимальный пример: Python + OpenAI
Пример агента, который умеет получать текущее время через инструмент:
import openai
# 1. Инструмент (реальная функция)
def get_current_time():
from datetime import datetime
return datetime.now().isoformat()
# 2. Описание инструмента для LLM
tools = [
{
"type": "function",
"function": {
"name": "get_current_time",
"description": "Возвращает текущее время в ISO формате",
"parameters": {"type": "object", "properties": {}}
}
}
]
# 3. Цикл агента
messages = [{"role": "user", "content": "Сколько сейчас времени?"}]
response = openai.chat.completions.create(
model="gpt-4o-mini",
messages=messages,
tools=tools,
tool_choice="auto"
)
choice = response.choices[0]
if choice.message.tool_calls:
# 4. Исполнение инструмента
tool_call = choice.message.tool_calls[0]
if tool_call.function.name == "get_current_time":
result = get_current_time()
messages.append(choice.message)
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": result
})
# 5. Финальный ответ
final = openai.chat.completions.create(
model="gpt-4o-mini",
messages=messages
)
print(final.choices[0].message.content)
else:
print(choice.message.content)
Типичные ошибки при сборке
- Нет валидации tool_call — агент вызывает несуществующий инструмент или с неверными параметрами. Решение: всегда проверять `tool_call.function.name` и `arguments` перед исполнением.
- Циклические вызовы — агент бесконечно вызывает один и тот же инструмент. Решение: лимитировать число tool-calls в сессии (например, max_steps=5).
- Утечка контекста — результаты инструментов попадают в публичный лог. Решение: фильтровать `tool_call` и `tool` сообщения перед сохранением.
- Отсутствие fallback — при ошибке инструмента агент «зависает». Решение: возвращать структурированную ошибку (например, `{"error": "DB_TIMEOUT", "retry_after": 30}`).
Пример: агент-помощник в CRM
Сценарий: пользователь просит «найти клиента по email и показать последнюю сделку».
- Инструменты: `find_customer(email)`, `get_last_deal(customer_id)`
- Контекст: инструкция + история диалога + описание инструментов
- Лог агента:
[user] "Найди клиента ivan@company.ru и покажи последнюю сделку" [agent] → tool_call: find_customer(email="ivan@company.ru") [tool] → {"id": "c123", "name": "Иван Петров"} [agent] → tool_call: get_last_deal(customer_id="c123") [tool] → {"deal": "SaaS Pro", "amount": 15000, "date": "2025-04-10"} [agent] → "У клиента Ивана Петрова последняя сделка: SaaS Pro (15 000 ₽, 10 апреля)"
Чеклист перед запуском в прод
- [ ] Все tool_call обрабатываются в `try/except` с fallback-сообщением
- [ ] Лимит шагов (max_steps) задан и логируется
- [ ] Инструменты не возвращают чувствительные данные (пароли, токены)
- [ ] Аудит: сохраняется `tool_call.id`, `name`, `status`, `duration_ms`
- [ ] Тесты: есть evals с синтетическими инструментами (mocked)
- [ ] Human review: для критичных инструментов (например, списание средств) включён ручной апрув
Следующий шаг
После освоения базового tool-calling — переходите к тестированию агента и оркестрации шагов. В реальном проекте вы будете комбинировать tool-calling с памятью, ретраями и fallback-логикой — это создаёт устойчивые агентные системы.