Для агентов — управляемый инструмент работы с данными

Инструменты для AI-агентов,
которые отвечают с доказательством.

SQAI даёт модели с вызовом инструментов доступ только на чтение к структурированным данным через три управляемых инструмента. Модель формулирует типизированное намерение. Контракт и ваша политика проверяют его. Детерминированный движок выполняет. Каждый ответ возвращается с хешем, позволяющим его воспроизвести.

IОдин оборот цикла

запрос поступаетВ каком регионе была наибольшая суммарная выручка?
любая модель с вызовом инструментовМодель

Планирует шаги. Формулирует намерение. Никогда не касается данных.

вызов инструмента — типизированное намерение, не SQL{ version:"1", kind:"query", spec:{ metric:"revenue", aggregation:"sum", group_by:"region", source:"sales" } }
управляемый инструментSQAI
  1. contractконтракт возможностей с фиксацией хеша
  2. policyваши списки разрешений, проверяемые до выполнения
  3. engineдетерминированное выполнение только на чтение
типизированный статус — никаких исключенийstatus: ok · needs_clarification · rejected · error
ответ уходит — вместе с хешемeast — 2,130.50 · plan_hash f87610d8afeb…
ok

Выход из цикла. Строки или значение — и хеш, позволяющий их воспроизвести.

needs_clarification ↺

Возврат в цикл. Вопрос и найденные кандидаты — модель уточняет спецификацию и вызывает снова. Она никогда не угадывает столбец.

отказ и ошибка идут по тому же каналу возврата — типизированные результаты, которые модель может прочитать, а не исключения, прерывающие выполнение.

IIИнструменты

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

`sqai.tools()` возвращает ровно три инструмента — намеренно компактный интерфейс. Обнаружение и пробные запуски никогда не выполняются; выполнение происходит ровно в одном месте.

listSources

никогда не выполняется

Обнаружение. Подключённые источники с типизированными полями, модули возможностей, сигнатуры функций — три режима из одного входа, чтобы спецификации использовали точные имена.

sources · capabilitySearch · module
ops: sum avg count min max eq in gt gte lt lte is_null is_not_null

queryData

тот, что выполняет

Один версионированный вход — размеченное объединение по kind: запрос или вычисление. Четыре исхода, всегда типизированных, без единого throw.

version "1" · kind: query | computation
ok · needs_clarification · rejected · error

explainQuery

пробный прогон — без выполнения

Разрешает и проверяет намерение, не запуская его. Модель использует это для отладки уточнений; вы — для предварительного просмотра плана.

preview invocation_hash ≠ executed hash

Набор встраивается напрямую в generateText или streamText — типизированный, присваиваемый без приведения типов. Настройка Vercel AI SDK

IIIКонтракт ошибок

Инструменты не бросают ошибок.

Исключение прерывает выполнение агента. Поэтому здесь ничего не бросается: неоднозначность, отказ и сбой возвращаются как типизированные статусы, которые модель может прочитать — и исправить — в рамках своего бюджета шагов.

retryable помечает временные — network_error · timeout · rate_limited · service_unavailable

queryData — четыре исхода

okРезультат: строки или значение, хэши происхождения, объявленное усечение.plan_hash · invocation_hash · computation_hash · truncated
needs_clarificationНамерение было неоднозначным. Вопрос и варианты — никаких догадок.question · candidates · explanation
rejectedРезолвер отклонил намерение. Ничего не выполнялось.rejection_reason · candidates · explanation
errorСтруктурированный сбой со стабильным кодом — модель читает его и корректирует поведение.code · message · retryable · nearest_matches?

Каждая ветка — это данные. Цикл сохраняет свой ход.

Принцип

Относитесь к модели как к
ненадёжному клиенту.

политика в коде · никаких полей политики во входных данных инструментов · только сужение

IVПринцип на практике

Индустрия усвоила это в продакшене — автономный агент для написания кода однажды удалил живую базу данных. Ответ SQAI структурный, а не поведенческий: открытая поверхность доступна только для чтения по конструкции. Категории записи и недетерминированные категории никогда не генерируются в неё, и никакой флаг, политика или входные данные модели не включают их обратно.

Что отправляет модель
Только типизированное намерение — версионированная спецификация. Никаких SQL-строк, кода или дескрипторов соединения.
Что она не может отправить
Политику. allowedSources, allowedFields и allowedFunctions фиксируются в конфигурации createSQAI() — ни одна схема входных данных инструмента не содержит поля политики, поэтому запрос может сузить поверхность, но никогда не расширить её.
Когда она всё равно запрашивает
Структурированный отказ — policy_denied_source, policy_denied_field, policy_denied_function. Не повторяемый, читаемый моделью, выполнение продолжается.
Полная модель политик

VПодключение

Три строки — и готово. Ограничено по умолчанию.

Один пакет оборачивает клиент в инструменты. Источники подключаются лениво при первом вызове; первое вычисление инициализирует среду выполнения один раз, после чего она остаётся тёплой — измеренные 0,83 мс.

import { generateText } from "ai";
import { createSQAI } from "@thyn-ai/sqai-ai-sdk";

const sqai = createSQAI({
  sources: [{ data: "./data/sales.csv", name: "sales" }],
});

const { text, steps } = await generateText({
  model,                  // any AI SDK model
  tools: sqai.tools(),    // listSources · queryData · explainQuery
  prompt: "Which region had the highest total revenue?",
});
ai ^7.0.0zod ^4.0.0node ≥ 20runtime = "nodejs"

Только на стороне сервера — в Next.js используйте среду выполнения Node, не Edge.

Что получает модель

maxRowsToModel
25строки, которые видит модель, из всего, что выполнил движок
maxCellsToModel
250бюджет ячеек — целые строки отбрасываются для соответствия; частичная строка никогда не показывается
maxBytesToModel
32,000байтовый бюджет для значения, видимого моделью
maxExecutionRows
1,000жёсткий лимит выполнения движка — defaultLimit 100, если спецификация не задаёт limit

Усечение всегда объявляется — truncated: true, returned_rows < total_rows. Никогда молча. Полные результаты остаются доступными в коде приложения по result_id.

VIАгентная аналитика

Анализ, который агент может обосновать.

Агентная аналитика даёт сбои известными способами: некорректные вызовы инструментов, модели, выполняющие собственную арифметику, правдоподобные числа, которые никто не может проверить. Каждый из них решается структурно, а не лучшим промптом.

01Некорректные вызовы инструментов

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

02Модель считает сама

Не здесь. Вычисляет движок. На наборе из 16 количественных вопросов та же модель перешла с 0/16 до 16/16, как только вычисления взял на себя движок.

03Непроверяемые числа

Каждый ответ несёт свой хэш. Воспроизведите то же намерение на тех же данных — хэш совпадёт, побайтово идентично в TypeScript и Python.

04Накопление задержек

Цикл умножает задержку. Плоскость запросов работает внутри процесса на субмиллисекундных скоростях; тёплое вычисление измерено на уровне 0,83 мс.

VIIВопросы

Для агентов — вопросы и ответы

Как дать AI-агенту доступ к базе данных только для чтения?

Не фильтруйте SQL — не генерируйте его. Подключите источники к createSQAI() и передайте модели sqai.tools(): доступная ей поверхность — 4 574 возможности только для чтения плюс ваши источники, без пути записи по конструкции. Нет категории записи, которую нужно блокировать, и нет входных данных модели, которые её включат.

Что происходит, если запрос агента неоднозначен?

queryData возвращает needs_clarification с уточняющим вопросом и найденными полями-кандидатами. Столбец никогда не угадывается. Модель отвечает на вопрос и вызывает инструмент снова — ещё один виток цикла.

Могут ли инструменты выбрасывать исключения?

Нет. Любой сбой возвращается как структурированный результат со стабильным кодом, сообщением и флагом повторной попытки. Неоднозначность, отказ, запрет политики и временные ошибки — всё приходит в виде данных, доступных модели.

Может ли модель расширить собственные разрешения?

Нет. allowedSources, allowedFields и allowedFunctions задаются в коде при вызове createSQAI() и проверяются до выполнения. Схема входных данных инструмента не содержит поля политики; обращение к запрещённой возможности возвращает структурированную ошибку policy_denied.

Работает ли это с Vercel AI SDK?

Да — @thyn-ai/sqai-ai-sdk поставляет три инструмента как типизированный набор для generateText и streamText, с peer-зависимостями ai ^7.0.0 и zod ^4.0.0, Node 20 или новее, на стороне сервера. Базовый клиент — тот же SDK, который можно встроить в любой агентный цикл.