В этом руководстве создается агент с вызовом функций, при котором инструмент, доступный к модели, никогда не выполняет произвольный SQL. Он сочетает в себе два механизма, уже проверенных в коде Aurabase: валидатор NL2SQL и транзакцию Postgres только для чтения, два блока собственного искусственного интеллекта, интегрированные в бэкэнд. Предварительные требования: проект Aurabase, его ключ service_roleи учетная запись у одного из трех собственных поставщиков LLM (OpenAI, Anthropic, Gemini).
Самое необходимое
- Настоящий риск заключается не в вызове самой функции, а в инструменте, доступном модели: необработанный
execute_sql(query)дает ей полный доступ к SQL. - Безопасная архитектура предоставляет инструмент
query_database(question), который делегирует проверку синтаксического дерева (только SELECT, ограниченный LIMIT, изолированная схема), а не прямое выполнение. - Aurabase предоставляет этот валидатор изначально (
/nl2sql): повторное использование его в качестве реализации инструмента позволяет избежать необходимости самостоятельно перекодировать проверку SQL. - Зафиксированный SQL затем выполняется через
aura.db.sql()в режимеreadOnly: true, фактической транзакции Postgres только для чтения, а не простого текстового фильтра. - Собственная конечная точка
/chatAurabase пока не принимает ни рольtool, ни параметрtools(проверено в коде): цикл агента в настоящее время выполняется через SDK поставщика LLM, а не через прокси-сервер Aurabase. - Ключ
service_roleнамеренно обходит RLS: он никогда не должен покидать ваш сервер, а агент наследует более широкий доступ, чем обычный аутентифицированный пользователь.
Что вы построите
Вы создадите агент, который отвечает на вопросы на естественном языке о данных в проекте Postgres, не позволяя модели писать SQL, который выполняется как есть. Модель вызывает инструмент с именем query_database, этот инструмент переводит вопрос в SQL, проверенный через NL2SQL, затем выполняет этот SQL только для чтения и возвращает строки в модель, чтобы она сформулировала свой ответ.
В этом руководстве используется JavaScript SDK @aurabase/aurabase-js на стороне сервера (никогда на стороне браузера, ключ service_role не должен быть доступен клиенту) и API вызова функции OpenAI для цикла агента. Тот же принцип применяется к Anthropic или Gemini SDK.
Чем опасен инструмент «запустите этот SQL»
В большинстве руководств по агентам Postgres, включая некоторые официальные руководства, определяется один инструмент: функция execute_sql, которая принимает строку SQL в качестве аргумента и выполняет ее как есть. Модель сама записывает эту строку на основе вопроса пользователя и схемы, заданной ей в контексте.
Этот выбор перекладывает на модель ответственность, которую она не может надежно выполнить. Внедрение подсказки в вопрос может привести к деструктивному SQL-коду, который инструмент выполняет без разбора, поскольку он не имеет представления о том, как должен выглядеть «законный» запрос. В нашей специальной статье подробно описан этот вектор атаки: защита NL2SQL от SQL-инъекций.
Альтернатива, созданная в этом руководстве, предоставляет более узкий инструмент query_database(question). Модель больше не может писать SQL напрямую: она может только задавать вопросы при вызове собственного инструмента. Это механизм Aurabase NL2SQL, который переводит этот вопрос в SQL, прежде чем передать его через валидатор синтаксического дерева (только SELECT, без подзапросов, десять разрешенных функций, ограниченный LIMIT).
Инструмент execute_sql(query: string) предоставляет модели полный доступ к SQL, независимо от того, насколько хороша ваша системная подсказка. Инструкция («выполняет только SELECT») остается инструкцией, которой модель может следовать, неверно интерпретировать или считать ее обходной с помощью инъекции, подставленной в вопрос пользователя.
Определите схему инструмента, представленного в модели.
Три собственных поставщика LLM Aurabase (OpenAI, Anthropic, Gemini) принимают таблицу определений инструментов в формате JSON Schema. Для этого агента достаточно одного инструмента: query_database, который принимает вопрос на естественном языке и ничего больше. Модель не видит ни схемы SQL, ни поля query, которое она могла бы заполнить сама.
Внедрите инструмент: NL2SQL будет доступен только для чтения.
Обработчик инструмента запускается на вашем сервере, а не в браузере. Он содержит ключ проекта service_role, который по своей конструкции обходит RLS и поэтому никогда не должен быть доступен клиенту. Он выполняет два вызова Aurabase SDK.
Первый вызов переводит вопрос в SQL, проверенный через aura.ai.nl2sql(): только SELECT, ограничено LIMIT, нет доступа к системному каталогу. Второй выполняет этот SQL, уже проверенный через aura.db.sql(), с опцией readOnly: true: сам Postgres затем отказывается от любой записи в этой транзакции, независимо от текстовой проверки, уже примененной вышестоящим NL2SQL.
readOnly: true запускает реальную транзакцию Postgres только для чтения: движок отказывается от записи, это не фильтр, применяемый к тексту запроса. В сочетании с проверкой только SELECT в NL2SQL агент имеет два независимых уровня: если в одном есть дефект, другой все еще сохраняется.
Цикл агента: вызов функции на стороне SDK поставщика
Aurabase предоставляет три собственных поставщика LLM, но его конечная точка /chat еще не передает параметр tools или роль tool. ChatOptions содержит только temperature, max_tokens и model, а допустимые роли ограничены system, user и assistant (проверено в llm/mod.rs и handlers/chat.rs). Таким образом, цикл вызова функции сегодня выполняется непосредственно через SDK провайдера, а не через прокси-сервер Aurabase.
Поскольку Aurabase не осуществляет встроенную оркестрацию вызовов инструментов, ваш бэкэнд должен управлять самим циклом с помощью OpenAI, Anthropic или Gemini SDK. Выполнение NL2SQL и SQL остается классическими вызовами Aurabase внутри этого цикла.
Принцип остается тем же, если вы организуете агент с помощью LangChain или такой службы, как Azure AI Agent: инструмент, объявленный в платформе, должен оставаться тем же query_database, а не просто исполнителем SQL. Подробное сравнение, где LangChain и LlamaIndex обеспечивают реальную ценность Postgres, а где они особенно усложняют: Агенты Postgres с LangChain или LlamaIndex.
Тест с реальным вопросом
Вопрос отправлен агенту: «Сколько премиальных клиентов разместили заказ в этом месяце?» ". Шаблон вызывает query_database с этим вопросом как есть, даже не видя и не записывая никакого SQL. Вот результат двух внутренних вызовов, инициированных инструментом.
Окончательный ответ модели основан на этих реальных линиях, а не на догадках. Если инструмент возвращает ноль строк, числовые галлюцинации становятся значительно менее вероятными, чем в случае с моделью, которая реагирует без проверенных данных.
Защитите агент перед запуском в производство
- Ключ
service_roleникогда не покидает ваш сервер: ни в приглашении, отправленном в модель, ни в журнале, ни в переменной среды на стороне клиента. readOnly: trueостается активным наaura.db.sql()для этого конкретного инструмента, даже если ваш проект требует записи в другом месте приложения.service_roleнамеренно обходит RLS. Если агент должен отвечать по-разному в зависимости от пользователя, задающего вопрос, явно отфильтруйте SQL или вернитесь к классическим конечным точкам PostgREST, которые соблюдают RLS. См. раздел многопользовательской изоляции RLS.- Регистрируйте каждый вызов инструмента (заданный вопрос, проверка SQL, количество строк): это единственная полезная трассировка, если вопрос дает неожиданный результат.
- Ограничение скорости и ежемесячная квота Aurabase уже применяются к каждому проекту на
/nl2sql: разговорчивый агент не может молча превысить ваш бюджет на ИИ.
Текущие ограничения, о которых следует знать
Инструмент query_database наследует все ограничения валидатора NL2SQL: отсутствие подзапросов, отсутствие CTE/WITH, отсутствие UNION и закрытый список из десяти функций SQL. Вопрос, который, естественно, требует подзапроса («клиенты, которые никогда не заказывали»), должен быть переформулирован или обработан вторым специальным инструментом, а не принудительно перенесен в NL2SQL.
Сегодня внутри прокси-сервера Aurabase /chat не существует никакой оркестрации вызовов инструментов: описанный здесь цикл агента находится в коде вашего приложения, а не в управляемом сервисе. Если агенту необходимо объединить несколько инструментов (например, базу данных и документацию RAG), именно ваш бэкэнд организует эти два вызова.
RAG и вызов функций вместе
В этом руководстве рассматриваются структурированные вопросы по реляционным данным. Для вопросов о неструктурированном контенте (документы, заявки, заметки) тот же агент может использовать второй инструмент, подключенный к встроенному RAG Aurabase (pgvector, поиск HNSW). Эти две возможности и их сочетание подробно описаны на странице Собственный искусственный интеллект в Postgres.