Гайд · TNWS AI

Как добавить безопасный tool в LangChain-агента для проверки статуса заказа

LangChain 1.xPythonopenai:gpt-5.5ChatGPT#LangChain#Python#AI-агенты
5 мин—

Декоратор @tool, схема аргументов, серверная проверка заказа и отрицательные тесты на чужой ID.

Задача и применимость

Русскоязычный запрос: «как добавить tool LangChain agent create_agent безопасно». Проверка официальной документации LangChain — 19 сентября 2026 года. LangChain 1.x Python и модель с поддержкой tool calling; пример локального read-only инструмента, не реальное подключение к CRM.

@tool использует аннотации типов для схемы аргументов и docstring для описания назначения. create_agent принимает callable, объект Tool или словарь. Вызов инструмента выполняется приложением: модель предлагает аргументы, но функция должна сама проверять права. Даже return_direct, описанный в документации, управляет циклом агента, а не авторизацией пользователя.

Порядок действий

  1. Определите узкую read-only функцию для статуса, которая получает order_id и проверяет его по серверной таблице разрешённых ID.
  2. Оформите сигнатуру с type hints и кратким docstring, чтобы модель понимала инструмент.
  3. Передайте функцию через tools в create_agent; system_prompt запретит додумывать статус без результата инструмента.
  4. Запустите положительный тест по своему заказу и отрицательный по неизвестному ID.
  5. Проверьте, что backend не отдаёт статусы других пользователей даже при ручной подмене аргумента.

Пример ниже предназначен для демонстрационного окружения: установите соответствующий пакет интеграции, настройте ключ через секреты сервера и убедитесь, что модель доступна вашему аккаунту. Если доступ к указанному model ID отсутствует, выберите поддерживаемую модель со сходными возможностями и заново проверьте работу именно на ней. Ни один пример не содержит действующего API-ключа и не разрешает обход ограничений провайдера.

Готовый шаблон на Python

from langchain.agents import create_agent
from langchain.tools import tool

# Демонстрационные данные, замените защищённым серверным источником.
ALLOWED = {"AB-417": "Передан в доставку"}

@tool
def get_order_status(order_id: str) -> str:
    """Получить статус разрешённого заказа по его ID."""
    return ALLOWED.get(order_id, "Недоступен или не найден")

agent = create_agent(model="openai:gpt-5.5", tools=[get_order_status],
    system_prompt="Не выдумывай статусы. Используй tool для номера заказа.")
result = agent.invoke({"messages": [{"role": "user", "content":
    "Где мой заказ AB-417?"}]})
print(result["messages"][-1].content)

Конкретные входные и ожидаемые данные

Вход: «Где мой заказ AB-417?» и локальная таблица с AB-417 → «Передан в доставку». Ожидается подтверждённый статус; запрос для XX-999 должен закончиться «Недоступен или не найден», без придуманного местонахождения. В production принадлежность AB-417 определяется из проверенной серверной сессии, а не из значения, которое модель вставила в функцию.

Оценивать стоит не красоту формулировки, а проверяемое выполнение задачи. Сохраните исходный текст, ID пользователя или теста и ожидаемое значение отдельно от ответа модели. Если пример выдаёт неверный факт, разберите данные на входе и состояние инструмента до изменения промпта: иначе можно замаскировать ошибку инфраструктуры удачной перефразировкой.

Диагностика и границы решения

Это критическая граница доверия: LLM не может быть арбитром полномочий. Она выбирает, когда вызвать get_order_status и какой ID передать; функция на сервере обязана отвергнуть доступ к чужому заказу независимо от текста запроса. В демонстрационном словаре доступен всего один ID, но в реальной CRM нужно проверять связь пользователя и заказа каждый раз, а не один раз при создании агента. Docstring направляет модель, но не служит security policy. Для инструментов записи — отмена заказа, изменение адреса, возврат — требуется отдельный поток подтверждения; не расширяйте read-only инструмент параметром action без анализа побочных эффектов. Ограничивайте размер и формат аргументов до обращения к БД, задавайте таймаут и журналируйте идентификатор операции без сырых секретов. Проверьте попытку prompt injection внутри названия товара: сторонний текст не должен позволить модели вызвать инструмент с чужим ID. Сравнивайте ответ агента с реальным ToolMessage и проверяйте, что никакая фантазия модели не подменяет «Недоступен». Если сервис упал, отображайте явную ошибку, а не статус «Отменён», которого система не видела.

Контрольный эксперимент

Для тестирования создайте четыре ситуации: разрешённый ID, запрещённый ID, malformed ID и временная ошибка базы. Положительный тест доказывает только функциональность; остальные определяют безопасность и честность ответа. Сохраняйте трассу с именем вызванного tool, аргументом, временем и результатом после редакции персональных данных. Если один вопрос содержит два заказа, проверяйте каждый доступ независимо. Для публичного чат-бота применяйте rate limiting на уровне API инструмента, поскольку пользователь может многократно просить модель вызывать дорогой сервис. Нельзя доверять ответу модели «я проверил заказ», если в журнале вызов get_order_status отсутствует. Наконец, выбирайте возвращаемую строку так, чтобы инструмент не раскрывал, существует ли чужой заказ: одинаковое «Недоступен или не найден» уменьшает утечку.

Дополнительный проверочный сценарий

Проектируйте интерфейс инструмента вокруг минимальных прав. Функция статуса не должна одновременно отдавать домашний адрес, телефон и историю платежей, если вопрос пользователя лишь о доставке. Ограничьте выход заранее определённым набором статусов и не возвращайте внутренний JSON целиком. Проверьте аргумент order_id на длину и формат до запроса БД; подготовленные запросы устраняют риск SQL-инъекции, но не заменяют проверку владельца заказа. Отдельно протестируйте запрос «проверь все заказы» — read-only не значит безопасный при массовом раскрытии. Если tool отвечает «Недоступен или не найден», агент не должен уточнять, что заказ существует, но скрыт. Именно строгий контракт результата снижает вероятность утечки через естественный язык.

Критерии результата

  • Документация функции и type hint позволяют собрать tool schema.
  • Доступный AB-417 возвращает проверенный статус.
  • Запрещённый ID не раскрывает существование чужого заказа.
  • Сбой источника не превращается в выдуманный статус.

При провале критерия помечайте задачу незавершённой. Корректный HTTP-ответ от провайдера не доказывает истинность результата, а удачный результат локального теста не гарантирует ту же доступность модели или сервисов в вашем рабочем окружении.

Типичные ошибки и что не делать

  • Считать system_prompt проверкой прав.
  • Выставить административный токен в коде инструмента для браузера.
  • Подменять ToolMessage произвольной фразой модели.
  • Добавлять побочные эффекты в read-only пример без подтверждения.

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

FAQ

Кто выполняет tool?

Код приложения после запроса модели.

Можно ли доверять аргументам модели?

Нет, валидируйте ID и полномочия на сервере.

Что делает docstring?

Описывает предназначение инструмента для модели.

Официальные источники

Частые вопросы

Кто выполняет tool?

Код приложения после запроса модели.

Можно ли доверять аргументам модели?

Нет, валидируйте ID и полномочия на сервере.

Что делает docstring?

Описывает предназначение инструмента для модели.

Читайте также

Комментарии

Пока тихо. Скажите первое слово