listSources
никогда не выполняетсяОбнаружение. Подключённые источники с типизированными полями, модули возможностей, сигнатуры функций — три режима из одного входа, чтобы спецификации использовали точные имена.
Для агентов — управляемый инструмент работы с данными
SQAI даёт модели с вызовом инструментов доступ только на чтение к структурированным данным через три управляемых инструмента. Модель формулирует типизированное намерение. Контракт и ваша политика проверяют его. Детерминированный движок выполняет. Каждый ответ возвращается с хешем, позволяющим его воспроизвести.
IОдин оборот цикла
“В каком регионе была наибольшая суммарная выручка?”Планирует шаги. Формулирует намерение. Никогда не касается данных.
{ version:"1", kind:"query", spec:{ metric:"revenue", aggregation:"sum", group_by:"region", source:"sales" } }contractконтракт возможностей с фиксацией хешаpolicyваши списки разрешений, проверяемые до выполненияengineдетерминированное выполнение только на чтениеstatus: ok · needs_clarification · rejected · erroreast — 2,130.50 · plan_hash f87610d8afeb…okВыход из цикла. Строки или значение — и хеш, позволяющий их воспроизвести.
needs_clarification ↺Возврат в цикл. Вопрос и найденные кандидаты — модель уточняет спецификацию и вызывает снова. Она никогда не угадывает столбец.
отказ и ошибка идут по тому же каналу возврата — типизированные результаты, которые модель может прочитать, а не исключения, прерывающие выполнение.
IIИнструменты
`sqai.tools()` возвращает ровно три инструмента — намеренно компактный интерфейс. Обнаружение и пробные запуски никогда не выполняются; выполнение происходит ровно в одном месте.
listSourcesОбнаружение. Подключённые источники с типизированными полями, модули возможностей, сигнатуры функций — три режима из одного входа, чтобы спецификации использовали точные имена.
queryDataОдин версионированный вход — размеченное объединение по kind: запрос или вычисление. Четыре исхода, всегда типизированных, без единого throw.
explainQueryРазрешает и проверяет намерение, не запуская его. Модель использует это для отладки уточнений; вы — для предварительного просмотра плана.
Набор встраивается напрямую в generateText или streamText — типизированный, присваиваемый без приведения типов. Настройка Vercel AI SDK →
IIIКонтракт ошибок
Исключение прерывает выполнение агента. Поэтому здесь ничего не бросается: неоднозначность, отказ и сбой возвращаются как типизированные статусы, которые модель может прочитать — и исправить — в рамках своего бюджета шагов.
retryable помечает временные — network_error · timeout · rate_limited · service_unavailable
queryData — четыре исхода
okРезультат: строки или значение, хэши происхождения, объявленное усечение.plan_hash · invocation_hash · computation_hash · truncatedneeds_clarificationНамерение было неоднозначным. Вопрос и варианты — никаких догадок.question · candidates · explanationrejectedРезолвер отклонил намерение. Ничего не выполнялось.rejection_reason · candidates · explanationerrorСтруктурированный сбой со стабильным кодом — модель читает его и корректирует поведение.code · message · retryable · nearest_matches?Каждая ветка — это данные. Цикл сохраняет свой ход.
Принцип
политика в коде · никаких полей политики во входных данных инструментов · только сужение
IVПринцип на практике
Индустрия усвоила это в продакшене — автономный агент для написания кода однажды удалил живую базу данных. Ответ SQAI структурный, а не поведенческий: открытая поверхность доступна только для чтения по конструкции. Категории записи и недетерминированные категории никогда не генерируются в неё, и никакой флаг, политика или входные данные модели не включают их обратно.
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?",
});Только на стороне сервера — в Next.js используйте среду выполнения Node, не Edge.
Что получает модель
Усечение всегда объявляется — truncated: true, returned_rows < total_rows. Никогда молча. Полные результаты остаются доступными в коде приложения по result_id.
VIАгентная аналитика
Агентная аналитика даёт сбои известными способами: некорректные вызовы инструментов, модели, выполняющие собственную арифметику, правдоподобные числа, которые никто не может проверить. Каждый из них решается структурно, а не лучшим промптом.
Один версионированный вход, проверяемый до запуска. Некорректное или неоднозначное намерение возвращает типизированный статус — цикл продолжается вместо аварийного завершения.
Не здесь. Вычисляет движок. На наборе из 16 количественных вопросов та же модель перешла с 0/16 до 16/16, как только вычисления взял на себя движок.
Каждый ответ несёт свой хэш. Воспроизведите то же намерение на тех же данных — хэш совпадёт, побайтово идентично в TypeScript и Python.
Цикл умножает задержку. Плоскость запросов работает внутри процесса на субмиллисекундных скоростях; тёплое вычисление измерено на уровне 0,83 мс.
VIIВопросы
Не фильтруйте SQL — не генерируйте его. Подключите источники к createSQAI() и передайте модели sqai.tools(): доступная ей поверхность — 4 574 возможности только для чтения плюс ваши источники, без пути записи по конструкции. Нет категории записи, которую нужно блокировать, и нет входных данных модели, которые её включат.
queryData возвращает needs_clarification с уточняющим вопросом и найденными полями-кандидатами. Столбец никогда не угадывается. Модель отвечает на вопрос и вызывает инструмент снова — ещё один виток цикла.
Нет. Любой сбой возвращается как структурированный результат со стабильным кодом, сообщением и флагом повторной попытки. Неоднозначность, отказ, запрет политики и временные ошибки — всё приходит в виде данных, доступных модели.
Нет. allowedSources, allowedFields и allowedFunctions задаются в коде при вызове createSQAI() и проверяются до выполнения. Схема входных данных инструмента не содержит поля политики; обращение к запрещённой возможности возвращает структурированную ошибку policy_denied.
Да — @thyn-ai/sqai-ai-sdk поставляет три инструмента как типизированный набор для generateText и streamText, с peer-зависимостями ai ^7.0.0 и zod ^4.0.0, Node 20 или новее, на стороне сервера. Базовый клиент — тот же SDK, который можно встроить в любой агентный цикл.