На статью данный текст точно не тянет, скорее это маленькая заметка. Как известно свои дети и свои идеи они всегда самые лучшие. Я давно работаю с реляционными базами и очень люблю язык 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, отличные игрушки, но где их применить в реальной жизни. Я думаю вот несколько примеров где пригодится данный подход
-
У нас есть старая система и мы хотим без переделки добавить AI в нее, и анализировать наши данные и рисовать графики. К старой системе прилагаются старые программисты, которым работать с запросами гораздо проще чем делать вызовы REST API
-
Генерация тестовых данных
-
Для торговых ботов подтверждение сигналов тех анализа, новостными сигналами
-
Разбор больших текстов и заполнение нужных полей в зависимости от содержимого текста.
-
В медицинских базах или базах автосервиса и тому подобное, постановка диагноза на основе жалоб клиента и автоматическое заполнение нужных полей.
Понятно, что реализация может быть лучше и на другом языке, можно реализовать функцию построения рисунка или графика на основе данных из базы. Это всего лишь пример. Наверное, это все, чем я хотел с вами поделится, пишите, что думаете об этой идеи, сильно прошу не бить.
ссылка на оригинал статьи https://habr.com/ru/articles/930406/
Добавить комментарий