PRODसंप्रभु यूरोपीय BaaS मंचडैशबोर्ड खोलें →

मूल एआई · 10 मिनट पढ़ा

फ़ंक्शन कॉलिंग के साथ सुरक्षित Postgres एजेंट (ट्यूटोरियल)

Affane Daylami · Fondateur · 21 मार्च 2026

ब्लॉग पर वापस जाएँ

पोस्टग्रेज़ से पूछताछ करने वाला एक एजेंट कोड की पहली पंक्ति से पहले एक विशिष्ट सुरक्षा प्रश्न पूछता है: आप मॉडल में कौन सा फ़ंक्शन प्रदर्शित कर रहे हैं? यदि एलएलएम जिस उपकरण को कॉल कर सकता है, वह स्वयं लिखे गए एसक्यूएल को सीधे निष्पादित करता है, तो एक अस्पष्ट प्रश्न या एक त्वरित इंजेक्शन प्रोजेक्ट में किसी भी तालिका को पढ़ने के लिए पर्याप्त है।

यह अंग्रेजी पाठ फ़्रेंच मूल से स्वचालित रूप से उत्पन्न हुआ था और अभी तक इसकी समीक्षा नहीं की गई है।
यह पृष्ठ स्वचालित रूप से अनुवादित किया गया था. अंग्रेजी संस्करण प्रामाणिक है.

यह ट्यूटोरियल फ़ंक्शन कॉलिंग के साथ एक एजेंट बनाता है जहां मॉडल के संपर्क में आने वाला टूल कभी भी मनमाना SQL निष्पादित नहीं करता है। यह ऑराबेस कोड में पहले से ही सत्यापित दो तंत्रों को जोड़ता है: एनएल2एसक्यूएल सत्यापनकर्ता और एक रीड-ओनली पोस्टग्रेज लेनदेन,मूल AI की दो ईंटेंबैकएंड में एकीकृत हैं। आवश्यक शर्तें: एक ऑराबेस प्रोजेक्ट, इसकी service_roleकुंजी, और तीन मूल एलएलएम प्रदाताओं (ओपनएआई, एंथ्रोपिक, जेमिनी) में से एक के साथ एक खाता।

अनिवार्य है

  • वास्तविक जोखिम फ़ंक्शन को कॉल करना नहीं है, बल्कि मॉडल के संपर्क में आने वाला टूल है: एक कच्चा execute_sql(query) इसे पूर्ण SQL एक्सेस देता है।
  • सुरक्षित आर्किटेक्चर एक query_database(question) टूल को उजागर करता है जो सीधे निष्पादन के बजाय एक सिंटैक्स ट्री सत्यापनकर्ता (केवल चयन, सीमित सीमा, पृथक स्कीमा) को सौंपता है।
  • ऑराबेस इस सत्यापनकर्ता को मूल रूप से उजागर करता है (/nl2sql): इसे उपकरण के कार्यान्वयन के रूप में पुन: उपयोग करने से SQL सत्यापन को स्वयं दोबारा कोड करने से बचा जाता है।
  • प्रतिबद्ध SQL तब readOnly: trueमोड में aura.db.sql() के माध्यम से निष्पादित होता है, एक वास्तविक रीड-ओनली पोस्टग्रेज़ लेनदेन, न कि एक साधारण टेक्स्ट फ़िल्टर।
  • ऑराबेस का मूल /chat एंडपॉइंट अभी तक tool भूमिका और न ही tools पैरामीटर (कोड में सत्यापित) को स्वीकार नहीं करता है: एजेंट लूप वर्तमान में एलएलएम प्रदाता के एसडीके के माध्यम से चलता है, ऑराबेस प्रॉक्सी के माध्यम से नहीं।
  • service_role कुंजी डिज़ाइन द्वारा आरएलएस को बायपास करती है: इसे आपके बैकएंड को कभी नहीं छोड़ना चाहिए, और एजेंट को एक सामान्य प्रमाणित उपयोगकर्ता की तुलना में व्यापक पहुंच प्राप्त होती है।
#
उद्देश्य

आप क्या बनाएंगे

आप एक ऐसा एजेंट बनाएंगे जो पोस्टग्रेज़ प्रोजेक्ट में डेटा के बारे में प्राकृतिक भाषा के सवालों का जवाब देता है, बिना मॉडल को एसक्यूएल लिखने की अनुमति दिए जो कि वैसे ही निष्पादित होता है। मॉडल query_databaseनाम के एक टूल को कॉल करता है, यह टूल प्रश्न को NL2SQL के माध्यम से सत्यापित SQL में अनुवादित करता है, फिर इस रीड-ओनली SQL को निष्पादित करता है और लाइनों को मॉडल में लौटाता है ताकि वह अपना उत्तर तैयार कर सके।

जानकारी

यह ट्यूटोरियल सर्वर साइड पर @aurabase/aurabase-js JavaScript SDK का उपयोग करता है (ब्राउज़र साइड पर कभी भी, service_role कुंजी क्लाइंट के सामने नहीं आनी चाहिए) और एजेंट लूप के लिए OpenAI फ़ंक्शन कॉलिंग एपीआई का उपयोग करता है। यही सिद्धांत एंथ्रोपिक या जेमिनी एसडीके के साथ भी लागू होता है।

#
हुड के नीचे

"यह SQL चलाएँ" उपकरण खतरनाक क्यों है?

अधिकांश पोस्टग्रेज एजेंट ट्यूटोरियल, जिनमें कुछ आधिकारिक गाइड भी शामिल हैं, एक एकल टूल को परिभाषित करते हैं: एक execute_sql फ़ंक्शन जो एक SQL स्ट्रिंग को एक तर्क के रूप में लेता है और इसे वैसे ही निष्पादित करता है। मॉडल इस स्ट्रिंग को उपयोगकर्ता के प्रश्न और संदर्भ में दिए गए स्कीमा के आधार पर स्वयं लिखता है।

tool-schema-dangereux.json (विरोधी पैटर्न)json
{
  "name": "execute_sql",
  "parameters": {
    "query": { "type": "string" }  // मॉडल सीधे SQL लिखता है
  }
}

यह विकल्प मॉडल पर एक जिम्मेदारी स्थानांतरित करता है जिसे वह विश्वसनीय रूप से पूरा नहीं कर सकता है। प्रश्न में डाला गया एक त्वरित इंजेक्शन विनाशकारी एसक्यूएल उत्पन्न कर सकता है जिसे उपकरण अंधाधुंध रूप से निष्पादित करता है, क्योंकि इसमें इसकी कोई अवधारणा नहीं है कि "वैध" क्वेरी कैसी दिखनी चाहिए। हमारा समर्पित लेख इस आक्रमण वेक्टर का विवरण देता है: SQL इंजेक्शन के विरुद्ध NL2SQL को सुरक्षित करना।

इस ट्यूटोरियल में निर्मित विकल्प एक संकीर्ण टूल, query_database(question)को उजागर करता है। मॉडल अब सीधे SQL नहीं लिख सकता: यह केवल अपने टूल कॉल में ही एक प्रश्न पूछ सकता है। यह ऑराबेस NL2SQL इंजन है जो इस प्रश्न को सिंटैक्टिक ट्री वैलिडेटर (केवल चयन, कोई सबक्वेरी नहीं, दस फ़ंक्शन अधिकृत, सीमित सीमा) के माध्यम से पारित करने से पहले SQL में अनुवाद करता है।

सिस्टम प्रॉम्प्ट कोई सुरक्षा जांच नहीं है

एक execute_sql(query: string) टूल मॉडल को पूर्ण SQL एक्सेस देता है, भले ही आपका सिस्टम प्रॉम्प्ट कितना भी अच्छा क्यों न हो। एक निर्देश ("केवल SELECTs को निष्पादित करता है") एक निर्देश बना रहता है जिसका मॉडल अनुसरण कर सकता है, गलत व्याख्या कर सकता है, या उपयोगकर्ता के प्रश्न में डाले गए इंजेक्शन द्वारा बाधित हो सकता है।

#
स्टेप 1

मॉडल के संपर्क में आने वाले टूल की स्कीमा को परिभाषित करें

ऑराबेस के तीन मूल एलएलएम प्रदाता (ओपनएआई, एंथ्रोपिक, जेमिनी) JSON स्कीमा प्रारूप में टूल परिभाषाओं की एक तालिका स्वीकार करते हैं। इस एजेंट के लिए एक ही टूल पर्याप्त है: query_database, जो किसी प्रश्न को प्राकृतिक भाषा में लेता है और कुछ नहीं। मॉडल न तो SQL स्कीमा देखता है और न ही query फ़ील्ड जिसे वह स्वयं भर सकता है।

lib/agent-tools.tstypescript
export const tools = [
  {
    type: 'function',
    function: {
      name: 'query_database',
      description:
        "Interroge les données du projet en langage naturel. N'accepte pas de SQL : posez une question.",
      parameters: {
        type: 'object',
        properties: {
          question: {
            type: 'string',
            description: 'Question en français sur les données du projet.'
          },
        },
        required: ['question'],
        additionalProperties: false
      },
    },
  },
]
#
चरण दो

उपकरण लागू करें: NL2SQL फिर केवल पढ़ने के लिए

टूल हैंडलर आपके बैकएंड पर चलता है, ब्राउज़र में कभी नहीं। इसमें प्रोजेक्ट कुंजी service_roleहै, जो डिज़ाइन द्वारा आरएलएस को बायपास करती है और इसलिए इसे कभी भी क्लाइंट के सामने उजागर नहीं किया जाना चाहिए। यह ऑराबेस एसडीके को दो कॉल करता है।

पहली कॉल प्रश्न को aura.ai.nl2sql()के माध्यम से सत्यापित SQL में अनुवादित करती है: केवल चयन करें, सीमा सीमित है, सिस्टम कैटलॉग तक कोई पहुंच नहीं है। दूसरा aura.db.sql()के माध्यम से पहले से ही मान्य इस SQL ​​को readOnly: true विकल्प के साथ निष्पादित करता है: पोस्टग्रेज स्वयं इस लेनदेन में किसी भी लेखन को अस्वीकार कर देता है, एनएल2एसक्यूएल अपस्ट्रीम द्वारा पहले से ही लागू किए गए पाठ्य सत्यापन से स्वतंत्र।

server/tools/query-database.tstypescript
// क्लाइंट को service_role कुंजी के साथ प्रारंभ किया गया, ब्राउज़र साइड पर कभी नहीं
import { aura } from '@/lib/aurabase'

export async function queryDatabase(question: string) {
  const { data: validated, error } = await aura.ai.nl2sql(
    question,
    undefined,
    { limit: 50 },
  )
  if (error) return { error: error.message }

  const { data: rows, error: execError } = await aura.db.sql(
    validated.sql,
    [],
    { readOnly: true },
  )
  if (execError) return { error: execError.message }

  return { sql: validated.sql, rows }
}
अस्टुसे

readOnly: true एक वास्तविक रीड-ओनली पोस्टग्रेज़ लेनदेन को ट्रिगर करता है: इंजन लिखने से इंकार कर देता है, यह अनुरोध पाठ पर लागू फ़िल्टर नहीं है। NL2SQL के SELECT-only सत्यापन के साथ संयुक्त, एजेंट के पास दो स्वतंत्र परतें हैं: यदि एक में कोई दोष है, तो दूसरा अभी भी बरकरार है।

#
चरण 3

एजेंट लूप: आपूर्तिकर्ता के एसडीके पक्ष पर फ़ंक्शन कॉलिंग

ऑराबेस तीन मूल एलएलएम प्रदाताओं को उजागर करता है, लेकिन इसका /chat समापन बिंदु अभी तक tools पैरामीटर या toolभूमिका को रिले नहीं करता है। ChatOptions में केवल temperature, max_tokens और modelहैं, और स्वीकृत भूमिकाएं system, user और assistant (llm/mod.rs और handlers/chat.rsमें सत्यापित) तक सीमित हैं। इसलिए फ़ंक्शन कॉलिंग लूप आज सीधे प्रदाता के एसडीके के माध्यम से चलता है, ऑराबेस प्रॉक्सी के माध्यम से नहीं।

वर्तमान सीमा, कोई निश्चित विकल्प नहीं

जब तक ऑराबेस मूल रूप से टूल कॉल को व्यवस्थित नहीं करता है, तब तक आपके बैकएंड को लूप को ओपनएआई, एंथ्रोपिक या जेमिनी एसडीके के साथ ही प्रबंधित करना होगा। NL2SQL और SQL निष्पादन इस लूप के अंदर क्लासिक ऑराबेस कॉल बने हुए हैं।

server/agent.tstypescript
import OpenAI from 'openai'
import { tools } from './lib/agent-tools'
import { queryDatabase } from './tools/query-database'

const openai = new OpenAI()

export async function askAgent(question: string) {
  const messages = [{ role: 'user', content: question }]

  const first = await openai.chat.completions.create({
    model: 'gpt-4.1', messages, tools,
  })

  const call = first.choices[0].message.tool_calls?.[0]
  if (!call) return first.choices[0].message.content

  const args = JSON.parse(call.function.arguments)
  const result = await queryDatabase(args.question)

  const second = await openai.chat.completions.create({
    model: 'gpt-4.1',
    messages: [
      ...messages,
      first.choices[0].message,
      { role: 'tool', tool_call_id: call.id, content: JSON.stringify(result) },
    ],
  })

  return second.choices[0].message.content
}

यदि आप एजेंट को लैंगचेन या एज़्योर एआई एजेंट जैसी सेवा के साथ व्यवस्थित करते हैं तो सिद्धांत वही रहता है: फ्रेमवर्क में घोषित टूल वही रहना चाहिए query_database, कभी भी कच्चा SQL निष्पादक नहीं। हमारा तुलनात्मक विवरण जहां लैंगचेन और लामाइंडेक्स पोस्टग्रेज पर वास्तविक मूल्य प्रदान करते हैं, और जहां वे विशेष रूप से जटिलता जोड़ते हैं: लैंगचेन या लामाइंडेक्स के साथ पोस्टग्रेज एजेंट।

#
चरण 4

वास्तविक प्रश्न के साथ परीक्षण करें

एजेंट को प्रश्न भेजा गया: "इस महीने कितने प्रीमियम ग्राहकों ने ऑर्डर दिया?" "। टेम्प्लेट इस प्रश्न के साथ query_database को कॉल करता है, बिना किसी SQL को देखे या लिखे। यहां टूल द्वारा ट्रिगर की गई दो आंतरिक कॉल का परिणाम है।

उपकरण परिणाम (निकालें)json
{
  "sql": "SELECT count(*) FROM orders WHERE customer_plan = 'premium' AND created_at >= date_trunc('month', now()) LIMIT 50",
  "rows": [{ "count": 128 }]
}

मॉडल का अंतिम उत्तर इन वास्तविक रेखाओं पर आधारित है, अनुमान पर नहीं। यदि उपकरण शून्य पंक्तियाँ लौटाता है, तो एक संख्या मतिभ्रम उस मॉडल की तुलना में काफी कम हो जाता है जो सत्यापित डेटा के बिना प्रतिक्रिया देगा।

#
सुरक्षा

उत्पादन में जाने से पहले एजेंट को सुरक्षित कर लें

  • service_role कुंजी आपके बैकएंड को कभी नहीं छोड़ती है: न तो मॉडल को भेजे गए प्रॉम्प्ट में, न ही लॉग में, न ही क्लाइंट-साइड वातावरण चर में।
  • readOnly: true इस विशिष्ट टूल के लिए aura.db.sql() पर सक्रिय रहता है, भले ही आपके प्रोजेक्ट को एप्लिकेशन में कहीं और लिखने की आवश्यकता हो।
  • service_role डिज़ाइन द्वारा RLS को बायपास करता है। यदि एजेंट को प्रश्न पूछने वाले उपयोगकर्ता के आधार पर अलग-अलग प्रतिक्रिया देनी चाहिए, तो SQL में स्पष्ट रूप से फ़िल्टर करें या क्लासिक PostgREST एंडपॉइंट पर वापस आएँ, जो RLS का सम्मान करते हैं। बहु-किरायेदार आरएलएस अलगावदेखें।
  • प्रत्येक टूल कॉल को लॉग करें (प्रश्न पूछा गया, SQL मान्य, पंक्तियों की संख्या): यदि कोई प्रश्न अप्रत्याशित परिणाम उत्पन्न करता है तो यह एकमात्र प्रयोग करने योग्य ट्रेस है।
  • ऑराबेस की दर सीमित और मासिक कोटा पहले से ही /nl2sqlपर प्रति प्रोजेक्ट लागू है: एक बातूनी एजेंट चुपचाप आपके एआई बजट को पार नहीं कर सकता है।
#
ईमानदारी

वर्तमान सीमाओं के बारे में जागरूक होना चाहिए

query_database टूल को NL2SQL सत्यापनकर्ता की सभी सीमाएँ विरासत में मिली हैं: कोई सबक्वेरी नहीं, कोई CTE/WITH नहीं, कोई UNION नहीं, और दस SQL ​​फ़ंक्शंस की एक बंद सूची। एक प्रश्न जो स्वाभाविक रूप से एक उप-क्वेरी ("ग्राहक जिन्होंने कभी ऑर्डर नहीं किया है") की मांग करता है, उसे NL2SQL में डालने के बजाय दूसरे समर्पित टूल द्वारा पुन: तैयार किया जाना चाहिए या संसाधित किया जाना चाहिए।

ऑराबेस /chat प्रॉक्सी के अंदर टूल कॉल का कोई ऑर्केस्ट्रेशन आज मौजूद नहीं है: यहां वर्णित एजेंट लूप आपके एप्लिकेशन कोड में रहता है, प्रबंधित सेवा में नहीं। यदि एजेंट को कई टूल (उदाहरण के लिए डेटाबेस और डॉक्यूमेंट्री आरएजी) की श्रृंखला बनानी होगी, तो यह आपका बैकएंड है जो दो कॉलों को व्यवस्थित करता है।

#
और आगे बढ़ें

RAG और फ़ंक्शन कॉलिंग संयुक्त

यह ट्यूटोरियल संबंधपरक डेटा पर संरचित प्रश्नों को शामिल करता है। असंरचित सामग्री (दस्तावेज़, टिकट, नोट्स) के बारे में प्रश्नों के लिए, वही एजेंट ऑराबेस के मूल आरएजी (पीजीवेक्टर, एचएनएसडब्ल्यू खोज) से जुड़े दूसरे टूल को उजागर कर सकता है। दो क्षमताएं और उनकी अभिव्यक्ति पृष्ठ नेटिव AI on Postgresपर विस्तृत हैं।

#
अक्सर पूछे जाने वाले प्रश्नों

पूछे जाने वाले प्रश्न

क्या मैं एजेंट को लिखने की पहुंच (INSERT/UPDATE) दे सकता हूं?+
तकनीकी रूप से हाँ, केवल पढ़ने योग्य विकल्प को हटाकर और एक अलग टूल की ओर इंगित करके, लेकिन एनएल2एसक्यूएल आज ऐसा नहीं करता है: सत्यापनकर्ता केवल SELECT क्वेरीज़ की अनुमति देता है, क्लाइंट पक्ष पर चुने गए निष्पादन विकल्प की परवाह किए बिना। एक लेखन एजेंट एक अलग सत्यापनकर्ता का अनुरोध करता है, जिसके कार्यों की अपनी श्वेतसूची होती है और संभवतः निष्पादन से पहले मानव पुष्टि होती है।
क्या यह लैंगचेन, लामाइंडेक्स या एज़्योर एआई एजेंट जैसी सेवा के साथ संगत है?+
हां: ये फ्रेमवर्क आपके लिए फ़ंक्शन कॉलिंग लूप को व्यवस्थित करते हैं, लेकिन टूल का कार्यान्वयन आपका ही रहता है। वही हैंडलर (NL2SQL तब केवल-पढ़ने के लिए निष्पादन) उन्हें कच्चे SQL को निष्पादित करने की अनुमति देने के बजाय, खुद को लैंगचेन या एज़्योर एजेंट में घोषित टूल के फ़ंक्शन के रूप में तार देता है।

तैनाती के लिए तैयार हैं?

पाँच मिनट में आपका बैकएंड।

किसी क्रेडिट कार्ड की आवश्यकता नहीं · 500 एमबी निःशुल्क · 50,000 एमएयू