На статью данный текст точно не тянет, скорее это маленькая заметка. Как известно свои дети и свои идеи они всегда самые лучшие. Я давно работаю с реляционными базами и очень люблю язык SQL за его формализм, скорее всего из-за этой моей профдеформации и родилась эта мысль. На работе ко мне иногда обращались сделать выгрузку в CSV файл из базы для обучения моделей или анализа данных, и я подумал, а зачем выгружать данные, а потом иногда загружать обратно результат в базу. Почему не сделать так что бы результат запроса сразу отправлялся на обработку в AI и затем выдавался ответ на запрос. Нам всего лишь нужна SQL функция которая берет результат запроса, заворочает его в вызов к модели, а потом выдает результат. Понятно, что серебряной пули нет и данный подход не везде будет работать, например, такой подход не подразумевает асинхронность, а значит если нужна высокая производительность, то данный подход не очень подходит, с другой стороны сейчас запросы к AI не дёшевы и если вы пошлете 100 запросов в секунду, не дождавшись ответа на предыдущие то скорее всего получите ошибку. Я думаю в будущем это будет стандартная функции в базах данных.

Теперь рассмотрим простейшую реализацию данной функции. Под рукой был PostgreSQL, но можно реализовать это и для ORACLEили других баз. Для этого нам понадобится расширение. В качестве AI будем использовать Groq. Первое что нам надо это получить API ключ. Сама функция очень простая.

CREATE OR REPLACE FUNCTION ai.completions(
	role_user text, role_sys text DEFAULT '')
    RETURNS jsonb
    LANGUAGE 'plpgsql'
AS $BODY$
DECLARE
	url text = 'https://api.groq.com/openai/v1/chat/completions';
  	j text;
  	req http_request;
  	key_header http_header;
  	http_status integer;
  	error text;
BEGIN
    key_header.field = 'Authorization';
    key_header.value = 'Bearer ' ||  ‘API key’;
    req.method = 'POST';
    req.headers	= array[key_header];
    req.uri = url;
    req.content_type = 'application/json';
    req.content = format('{
    "model": "meta-llama/llama-4-scout-17b-16e-instruct",
    "messages": [
      {"role": "system", "content": "%s"},
      {"role": "user", "content": "%s"}
    ],
    "temperature": 0.7
  }', role_sys, role_user);

	SELECT status, content INTO http_status, j FROM http(req);	
	IF (http_status != 200) THEN		
		RAISE EXCEPTION  USING  ERRCODE = 'AI002', MESSAGE = j;
	END IF;
	RETURN j::jsonb;
END;
$BODY$;

Примеры работы, перед запуском советую установить следующие параметры

select http_set_curlopt('CURLOPT_CONNECTTIMEOUT', '10');
select http_set_curlopt('CURLOPT_TIMEOUT', '10');
select * from 
ai.completions('сколько будет 2 + 2', 'ты математик, верни только ответ') t

Результат

{
  "id": "chatcmpl-ac97506b-0b35-4e4d-bc82-3142fd0d3bc3",
  "model": "meta-llama/llama-4-scout-17b-16e-instruct",
  "usage": {
    "queue_time": 0.09607076599999999,
    "total_time": 0.008472493,
    "prompt_time": 0.003623623,
    "total_tokens": 30,
    "prompt_tokens": 28,
    "completion_time": 0.00484887,
    "completion_tokens": 2
  },
  "object": "chat.completion",
  "x_groq": {
    "id": "req_01k0vr86dtfz1rfh86ba6ztd7d"
  },
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "4"
      },
      "logprobs": null,
      "finish_reason": "stop"
    }
  ],
  "created": 1753278061,
  "service_tier": "on_demand",
  "usage_breakdown": null,
  "system_fingerprint": "fp_37da608fc1"
}
select * from 
ai.completions('Стоит ли сейчас шортить биткоин?', 
    'ты профессиональный помощник по криптотрейдингу. Отвечай кратко и точно.') t

Результат

{
  "id": "chatcmpl-1f78c32f-8ae9-4134-a90d-748fd1b507c2",
  "model": "meta-llama/llama-4-scout-17b-16e-instruct",
  "usage": {
    "queue_time": 0.412265067,
    "total_time": 0.062087713,
    "prompt_time": 0.003936061,
    "total_tokens": 70,
    "prompt_tokens": 45,
    "completion_time": 0.058151652,
    "completion_tokens": 25
  },
  "object": "chat.completion",
  "x_groq": {
    "id": "req_01k0vrhw0yexxavgh5p6m0z507"
  },
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "Нет, сейчас не лучший момент для шорта биткоина. Лучше дождаться подтверждения нисходящего тренда."
      },
      "logprobs": null,
      "finish_reason": "stop"
    }
  ],
  "created": 1753278378,
  "service_tier": "on_demand",
  "usage_breakdown": null,
  "system_fingerprint": "fp_79da0e0073"
}
select  
ai.completions('Сосчитай сумму чисел в массиве '  
               || string_agg(d.price::text, ','), 'ты математик')  
from (
select t.price  
  from crypto_bot2.binance_data t where t.pair='BTCUSDT' 
  order by t.t_date desc limit 10) d

Результат

{
  "id": "chatcmpl-dc5f9394-518f-4011-9494-0a8e88d5aff9",
  "model": "meta-llama/llama-4-scout-17b-16e-instruct",
  "usage": {
    "queue_time": 1.975420253,
    "total_time": 0.474911567,
    "prompt_time": 0.006071319,
    "total_tokens": 262,
    "prompt_tokens": 76,
    "completion_time": 0.468840248,
    "completion_tokens": 186
  },
  "object": "chat.completion",
  "x_groq": {
    "id": "req_01k0vrn55ef6rbw3ztzkk08p2v"
  },
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "Чтобы найти сумму чисел в данном массиве, я сложу все числа:\n\n117763.12 + 117789.74 = 235552.86\n235552.86 + 117735.53 = 353288.39\n353288.39 + 117718.625 = 471006.015\n471006.015 + 117725.19 = 588731.205\n588731.205 + 117674.25 = 706405.455\n706405.455 + 117656.75 = 824062.205\n824062.205 + 117646.13 = 941708.335\n941708.335 + 117646.086 = 1059354.421\n1059354.421 + 117650.914 = 1177005.335\n\nСумма чисел в данном массиве равна: 1177005.335"
      },
      "logprobs": null,
      "finish_reason": "stop"
    }
  ],
  "created": 1753278487,
  "service_tier": "on_demand",
  "usage_breakdown": null,
  "system_fingerprint": "fp_37da608fc1"
}

Где мы можем использовать данный подход

Наверное, эта часть самая сложная. Это как Raspberry pi или Arduino, отличные игрушки, но где их применить в реальной жизни. Я думаю вот несколько примеров где пригодится данный подход

  1. У нас есть старая система и мы хотим без переделки добавить AI в нее, и анализировать наши данные и рисовать графики. К старой системе прилагаются старые программисты, которым работать с запросами гораздо проще чем делать вызовы REST API

  2. Генерация тестовых данных

  3. Для торговых ботов подтверждение сигналов тех анализа, новостными сигналами

  4. Разбор больших текстов и заполнение нужных полей в зависимости от содержимого текста.

  5. В медицинских базах или базах автосервиса и тому подобное, постановка диагноза на основе жалоб клиента и автоматическое заполнение нужных полей.

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

Комментарии (7)


  1. Ninil
    23.07.2025 20:50

    • Подобное уже есть у ведоров нативно - например Датабрикс или Сноуфлейк.

    • Надеюсь, вы понимаете, что это только для "поиграться в песочнице с игрушечным данными"? Если такое реализовать на реальной базе в компании, то всех причасных надо как минимум подвергнуть самым серьезным "мерам дисциплинарного взыскания", а лучше (или вдобавок) вообще уволить

    ПыСы не благодарите, если я только что спас вас от увольнения)


  1. savostin
    23.07.2025 20:50

    Только не понятно зачем это в базе делать. Вот если б можно было туда результаты запроса отправить и ответ в виде таблицы получить…


  1. antokols Автор
    23.07.2025 20:50

    День добрый. Вы обоснуйте. Конечно это решение не универсальное, можно реализовать по другому. AI может быть локальным что бы своими данными не с кем не делится и быть закрытым от внешнего мира, но какой то большой проблемы я не вижу, а работать удобно. Конечно если у вас oltp приложение и ограничен пул соединений , надо что то другое придумать, запрос может подвисать. Я знаю планету где нет охотников , но там нет и кур :-)


    1. Ninil
      23.07.2025 20:50

      AI может быть локальным...

      Вы же предлагаете не локальное решение тут? С локальным AI будут другие проблемы - например он не такой "умный", как решения от больших вендоров + надо его самому хостить (железо), обучать и дообучать (еще больше железа + специалисты) и т.п.

      Вы не видите проблему, потому что смотрите узко, к сожалению. Enterprise-grade системы - это не то же самое, что локальный PoC


      1. antokols Автор
        23.07.2025 20:50

        Я не говорю что это универсальное решение. Просто как вариант, очень неплохо кстати генерит тестовые данные имена фамилии телефоны адреса и даже номера кредиток. Для больших ERP систем наверное другие решения требуются. В HANA такое точно не стоит встраивать соглашусь с вами. Как говорил Карлсон, главное спокойствие. А если по опыту работы то я работал в SAP довольно долго и что такое большие системы хорошо представляю, но при этом иногда программную Arduino не перенося туда опыт больших систем :-)


  1. vmalyutin
    23.07.2025 20:50

    Все просто и прикольно. Спасибо!

    Ну да, апологеты бизнес-логики в приложении будут ругать. Да и бог с ними. Они как правило возможностей PG не знают.

    С другой стороны вы правы. Высокопроизводительное решение так не построишь. Хотя может тут оно и не нужно.

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

    Понятное дело тут нужен оффлайн ИИ, но все же


    1. antokols Автор
      23.07.2025 20:50

      Не пробовал, я думаю использовать этот метод для подтверждения технических торговых сигналов которые считаю в базе и когда сигнал говорит покупать или пробовать для верности спрашивать AI. У меня весь бот написан на pgsql, в предыдущих статьях писал об этом.