Код-ревью Senior Агенты и вызов инструментов обновлено
Код-ревью: агент аналитики с SQL-инструментом
Вопрос
Агент отвечает менеджерам на вопросы о продажах, выполняя SQL по базе компании. Найдите проблемы в коде цикла агента.
TOOLS = [{
"name": "run_sql",
"description": "Выполняет любой SQL",
"parameters": {"type": "object", "properties": {"query": {"type": "string"}}},
}]
def ask(question, user):
history = [{"role": "system", "content": f"Ты аналитик. Пользователь: {user.name}, роль {user.role}"},
{"role": "user", "content": question}]
while True:
resp = llm.chat(history, tools=TOOLS)
if not resp.tool_calls:
return resp.text
for call in resp.tool_calls:
rows = db_admin.execute(call.args["query"])
history.append({"role": "tool", "content": json.dumps(rows)})
Коротко
Главное: модель получила неограниченные права в базе, и защита держится на промпте. Правильная схема: роль только на чтение с доступом к витринам, ограничения строк по правам пользователя в базе, таймауты и лимиты строк, лимит шагов агента и обработка ошибок с возвратом их модели.
Что должен найти ревьюер
- Безопасностьстрока 3Универсальный инструмент «любой SQL»: модель может выполнить UPDATE, DELETE или DROP. Нужны узкие инструменты или хотя бы только SELECT по разрешённым представлениям.
- Безопасностьстрока 15Запросы идут под админским подключением. Нужна отдельная роль только на чтение, с доступом к витринам, а не к сырым таблицам с персональными данными.
- Безопасностьстрока 8Права пользователя описаны только в промпте. Ограничение по роли (например, менеджер видит только свой регион) должно применяться в базе: row-level security или параметры в коде.
- Ошибкастрока 10
while Trueбез лимита шагов, токенов и времени: агент может зациклиться и тратить деньги бесконечно. - Производительностьстрока 16Результат запроса целиком в историю: тысячи строк раздуют контекст и стоимость. Нужен лимит строк и агрегаты.
- Ошибкастрока 15Нет обработки ошибок SQL и таймаута: исключение уронит весь запрос, а долгий запрос повесит агента. Ошибку надо вернуть модели текстом, запрос ограничить statement_timeout.
- Ошибкастрока 16Сообщение tool без идентификатора вызова: при нескольких вызовах модель не поймёт, какой результат к какому вызову относится. Большинство API требует tool_call_id.
Разбор
Главное: модель получила неограниченные права в базе, и защита держится на промпте. Правильная схема: роль только на чтение с доступом к витринам, ограничения строк по правам пользователя в базе, таймауты и лимиты строк, лимит шагов агента и обработка ошибок с возвратом их модели. Для типовых вопросов ещё лучше заранее подготовленные параметризованные запросы как отдельные инструменты.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.