Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Цитата "Просто потому, что вы не можете означать, что вы должны" является полезным руководством при разработке возможностей ИИ. Например, естественный язык Azure OpenAI для SQL позволяет пользователям создавать запросы к базе данных на обычном английском языке, что может быть мощным инструментом для повышения производительности. Однако мощный не всегда означает подходящий или безопасный. В этом упражнении показано, как использовать эту функцию ИИ, а также обсудить важные аспекты, которые следует учитывать перед принятием решения о его реализации.
Ниже приведен пример запроса естественного языка, который можно использовать для получения данных из базы данных:
Get the the total revenue for all companies in London.
При правильном запросе Azure OpenAI преобразует этот запрос в SQL, который можно использовать для возврата результатов из базы данных. В результате нетехническая поддержка пользователей, включая бизнес-аналитиков, маркетинговиков и руководителей, может проще получить ценные сведения из баз данных, не борясь с сложным синтаксисом SQL или опираясь на ограниченные наборы данных и фильтры. Этот упрощенный подход может повысить производительность, устраняя потребность пользователей в поиске помощи от технических экспертов.
Это упражнение предоставляет отправную точку, которая поможет вам понять, как работает естественный язык для SQL, ознакомиться с некоторыми важными рекомендациями, понять, как вы думаете о преимуществах и минусах, и показать вам код для начала работы.
В этом упражнении вы выполните следующие действия.
- Используйте запросы GPT для преобразования естественного языка в SQL.
- Экспериментируйте с различными запросами GPT.
- Используйте созданный SQL для запроса базы данных PostgreSQL, запущенной ранее.
- Результаты запроса возвращаются из PostgreSQL и отображаются в браузере.
Начнем с экспериментов с различными запросами GPT, которые можно использовать для преобразования естественного языка в SQL.
Использование естественного языка для компонента SQL
В предыдущем упражнении вы запустили базу данных, API и приложение. Вы также обновили
.envфайл. Если вы не выполнили эти действия, следуйте инструкциям в конце упражнения, прежде чем продолжить.Вернитесь в браузер (http://localhost:4200) и найдите раздел настраиваемого запроса страницы под datagrid. Обратите внимание, что образец значения запроса уже включен: получение общего дохода для всех заказов. Группировать по компании и включать город.
Нажмите кнопку "Выполнить запрос ". Это приведет к передаче запроса естественного языка пользователя в Azure OpenAI, который преобразует его в SQL. Затем SQL-запрос будет использоваться для запроса базы данных и возврата любых потенциальных результатов.
Выполните следующий пользовательский запрос:
Get the total revenue for Adventure Works Cycles. Include the contact information as well.Просмотрите окно терминала, на котором запущен сервер API в Visual Studio Code, и обратите внимание, что он отображает SQL-запрос, возвращенный из Azure OpenAI. Данные JSON используются интерфейсами API на стороне сервера для запроса базы данных PostgreSQL. Все строковые значения, включенные в запрос, добавляются в качестве значений параметров, чтобы предотвратить атаки на внедрение SQL:
{ "sql": "SELECT c.company, c.city, c.email, SUM(o.total) AS revenue FROM customers c INNER JOIN orders o ON c.id = o.customer_id WHERE c.company = $1 GROUP BY c.company, c.city, c.email", "paramValues": ["Adventure Works Cycles"] }Вернитесь в браузер и выберите "Сбросить данные ", чтобы просмотреть все клиенты снова в datagrid.
Изучение естественного языка в КОДе SQL
Подсказка
Если вы используете Visual Studio Code, вы можете открывать файлы напрямую, выбрав:
- Windows/Linux: CTRL +P
- Mac: Cmd + P
Затем введите имя файла, который нужно открыть.
Замечание
Цель этого упражнения заключается в том, чтобы показать, что возможно с помощью естественного языка в функциональных возможностях SQL и продемонстрировать, как приступить к работе с ним. Как упоминалось ранее, важно обсудить, подходит ли этот тип искусственного интеллекта для вашей организации, прежде чем продолжить любую реализацию. Кроме того, необходимо планировать надлежащие правила запроса и меры безопасности базы данных , чтобы предотвратить несанкционированный доступ и защитить конфиденциальные данные.
Теперь, когда вы видели естественный язык для функции SQL в действии, давайте рассмотрим, как она реализована.
Откройте файл сервера или apiRoutes.ts и найдите
generateSqlмаршрут. Этот маршрут API вызывается клиентским приложением, работающим в браузере, и используется для создания SQL из запроса естественного языка. После получения SQL-запроса он используется для запроса базы данных и возврата результатов.router.post('/generateSql', async (req, res) => { const userPrompt = req.body.prompt; if (!userPrompt) { return res.status(400).json({ error: 'Missing parameter "prompt".' }); } try { // Call Azure OpenAI to convert the user prompt into a SQL query const sqlCommandObject = await getSQLFromNLP(userPrompt); let result: any[] = []; // Execute the SQL query if (sqlCommandObject && !sqlCommandObject.error) { result = await queryDb(sqlCommandObject) as any[]; } else { result = [ { query_error : sqlCommandObject.error } ]; } res.json(result); } catch (e) { console.error(e); res.status(500).json({ error: 'Error generating or running SQL query.' }); } });Обратите внимание на следующие функции маршрута
generateSql:- Он извлекает значение пользовательского запроса из
req.body.promptи назначает его переменной с именемuserPrompt. Это значение будет использоваться в запросе GPT. - Она вызывает функцию
getSQLFromNLP()для преобразования естественного языка в SQL. - Он передает созданный SQL функции с именем
queryDb, которая выполняет SQL-запрос и возвращает результаты из базы данных.
- Он извлекает значение пользовательского запроса из
Откройте файл сервера или openAI.ts в редакторе и найдите функцию
getSQLFromNLP(). Эта функция вызывается маршрутомgeneratesqlи используется для преобразования естественного языка в SQL.async function getSQLFromNLP(userPrompt: string): Promise<QueryData> { // Get the high-level database schema summary to be used in the prompt. // The db.schema file could be generated by a background process or the // schema could be dynamically retrieved. const dbSchema = await fs.promises.readFile('db.schema', 'utf8'); const systemPrompt = ` Assistant is a natural language to SQL bot that returns a JSON object with the SQL query and the parameter values in it. The SQL will query a PostgreSQL database. PostgreSQL tables with their columns: ${dbSchema} Rules: - Convert any strings to a PostgreSQL parameterized query value to avoid SQL injection attacks. - Return a JSON object with the following structure: { "sql": "", "paramValues": [] } Examples: User: "Display all company reviews. Group by company." Assistant: { "sql": "SELECT * FROM reviews", "paramValues": [] } User: "Display all reviews for companies located in cities that start with 'L'." Assistant: { "sql": "SELECT r.* FROM reviews r INNER JOIN customers c ON r.customer_id = c.id WHERE c.city LIKE 'L%'", "paramValues": [] } User: "Display revenue for companies located in London. Include the company name and city." Assistant: { "sql": "SELECT c.company, c.city, SUM(o.total) AS revenue FROM customers c INNER JOIN orders o ON c.id = o.customer_id WHERE c.city = $1 GROUP BY c.company, c.city", "paramValues": ["London"] } User: "Get the total revenue for Adventure Works Cycles. Include the contact information as well." Assistant: { "sql": "SELECT c.company, c.city, c.email, SUM(o.total) AS revenue FROM customers c INNER JOIN orders o ON c.id = o.customer_id WHERE c.company = $1 GROUP BY c.company, c.city, c.email", "paramValues": ["Adventure Works Cycles"] } `; let queryData: QueryData = { sql: '', paramValues: [], error: '' }; let results = ''; try { results = await callOpenAI(systemPrompt, userPrompt); if (results) { console.log('results', results); const parsedResults = JSON.parse(results); queryData = { ...queryData, ...parsedResults }; if (isProhibitedQuery(queryData.sql)) { queryData.sql = ''; queryData.error = 'Prohibited query.'; } } } catch (error) { console.log(error); if (isProhibitedQuery(results)) { queryData.sql = ''; queryData.error = 'Prohibited query.'; } else { queryData.error = results; } } return queryData; }- Параметр
userPromptпередается в функцию. ЗначениемuserPromptявляется запрос естественного языка, введенный пользователем в браузере. - Определяет
systemPromptтип помощника по искусственному интеллекту, который следует использовать, и правила, которые следует соблюдать. Это помогает Azure OpenAI понимать структуру базы данных, какие правила следует применять, а также как возвращать созданный SQL-запрос и параметры. - Вызывается
callOpenAI()функция иsystemPromptuserPromptпередаются в нее значения. - Результаты проверяются, чтобы гарантировать, что в созданный SQL-запрос не включены запрещенные значения. При обнаружении запрещенных значений SQL-запрос имеет пустую строку.
- Параметр
Более подробно рассмотрим системный запрос:
const systemPrompt = ` Assistant is a natural language to SQL bot that returns a JSON object with the SQL query and the parameter values in it. The SQL will query a PostgreSQL database. PostgreSQL tables with their columns: ${dbSchema} Rules: - Convert any strings to a PostgreSQL parameterized query value to avoid SQL injection attacks. - Return a JSON object with the following structure: { "sql": "", "paramValues": [] } Examples: User: "Display all company reviews. Group by company." Assistant: { "sql": "SELECT * FROM reviews", "paramValues": [] } User: "Display all reviews for companies located in cities that start with 'L'." Assistant: { "sql": "SELECT r.* FROM reviews r INNER JOIN customers c ON r.customer_id = c.id WHERE c.city LIKE 'L%'", "paramValues": [] } User: "Display revenue for companies located in London. Include the company name and city." Assistant: { "sql": "SELECT c.company, c.city, SUM(o.total) AS revenue FROM customers c INNER JOIN orders o ON c.id = o.customer_id WHERE c.city = $1 GROUP BY c.company, c.city", "paramValues": ["London"] } User: "Get the total revenue for Adventure Works Cycles. Include the contact information as well." Assistant: { "sql": "SELECT c.company, c.city, c.email, SUM(o.total) AS revenue FROM customers c INNER JOIN orders o ON c.id = o.customer_id WHERE c.company = $1 GROUP BY c.company, c.city, c.email", "paramValues": ["Adventure Works Cycles"] } `;Определяется тип используемого помощника по искусственному интеллекту. В этом случае "естественный язык для бота SQL".
Определены имена таблиц и столбцы в базе данных. Высокоуровневая схема, включенная в запрос, находится в файле server/db.schema и выглядит следующим образом.
- customers (id, company, city, email) - orders (id, customer_id, date, total) - order_items (id, order_id, product_id, quantity, price) - reviews (id, customer_id, review, date, comment)Подсказка
Возможно, вы можете создать представления только для чтения, содержащие только пользователей данных, разрешены запрашивать с помощью естественного языка в SQL.
Правило определяется для преобразования строковых значений в параметризованное значение запроса, чтобы избежать атак внедрения SQL.
Правило определяется, чтобы всегда возвращать объект JSON с sql-запросом и значениями параметров в нем.
Приведены примеры запросов пользователей и ожидаемых значений sql-запроса и параметров. Это называется "несколькими выстрелами" обучение. Хотя LLM обучены на больших объемах данных, их можно адаптировать к новым задачам только в нескольких примерах. Альтернативный подход — это "нулевой снимок", в котором нет примера, и модель, как ожидается, создаст правильные значения SQL-запроса и параметров.
Функция
getSQLFromNLP()отправляет системе и пользователю запросы в функцию с именемcallOpenAI(), которая также находится в файле сервера или openAI.ts . ФункцияcallOpenAI()определяет, следует ли вызывать Azure OpenAI в модели Foundry или службе OpenAI, проверяя переменные среды. Если ключ, конечная точка и модель доступны в переменных среды, вызывается Azure OpenAI, в противном случае вызывается OpenAI.function callOpenAI(systemPrompt: string, userPrompt: string, temperature = 0, useBYOD = false) { const isAzureOpenAI = OPENAI_API_KEY && OPENAI_ENDPOINT && OPENAI_MODEL; if (isAzureOpenAI) { if (useBYOD) { return getAzureOpenAIBYODCompletion(systemPrompt, userPrompt, temperature); } return getAzureOpenAICompletion(systemPrompt, userPrompt, temperature); } return getOpenAICompletion(systemPrompt, userPrompt, temperature); }Замечание
Хотя мы сосредоточимся на Azure OpenAI в этом руководстве, если вы предоставляете
OPENAI_API_KEYтолько значение в env-файле , приложение будет использовать OpenAI вместо этого. Если вы решили использовать OpenAI вместо Azure OpenAI, вы можете увидеть разные результаты в некоторых случаях.Найдите функцию
getAzureOpenAICompletion().async function getAzureOpenAICompletion(systemPrompt: string, userPrompt: string, temperature: number): Promise<string> { const completion = await createAzureOpenAICompletion(systemPrompt, userPrompt, temperature); let content = completion.choices[0]?.message?.content?.trim() ?? ''; console.log('Azure OpenAI Output: \n', content); if (content && content.includes('{') && content.includes('}')) { content = extractJson(content); } return content; }Эта функция выполняет следующие действия:
Параметры:
-
systemPrompt,userPromptиtemperatureявляются основными параметрами.-
systemPrompt: сообщает модели Azure OpenAI о своей роли и правилах, которые необходимо выполнить. -
userPrompt: содержит предоставленные пользователем сведения, такие как входные данные естественного языка или правила для создания выходных данных. -
temperature: диктует уровень творчества ответа модели. Более высокое значение приводит к более творческим выходным данным, а более низкие значения (например, 0) создают более детерминированные ответы.
-
-
Создание завершения:
- Вызовы
createAzureOpenAICompletion()функции сsystemPrompt,userPromptаtemperatureтакже для создания завершения. - Он извлекает содержимое из первого выбора в завершении, обрезая любое дополнительное пробелы.
- Если содержимое содержит такие структуры JSON (указано наличием
{и}), извлекает содержимое JSON.
- Вызовы
Ведение журнала и возвращаемое значение:
- Функция записывает выходные данные Azure OpenAI в консоль.
- Он возвращает обработанное содержимое в виде строки.
Найдите функцию
createAzureOpenAICompletion().async function createAzureOpenAICompletion(systemPrompt: string, userPrompt: string, temperature: number, dataSources?: any[]): Promise<any> { const baseEnvVars = ['OPENAI_API_KEY', 'OPENAI_ENDPOINT', 'OPENAI_MODEL']; const byodEnvVars = ['AZURE_AI_SEARCH_ENDPOINT', 'AZURE_AI_SEARCH_KEY', 'AZURE_AI_SEARCH_INDEX']; const requiredEnvVars = dataSources ? [...baseEnvVars, ...byodEnvVars] : baseEnvVars; checkRequiredEnvVars(requiredEnvVars); const config = { apiKey: OPENAI_API_KEY, endpoint: OPENAI_ENDPOINT, apiVersion: OPENAI_API_VERSION, deployment: OPENAI_MODEL }; const aoai = new AzureOpenAI(config); const completion = await aoai.chat.completions.create({ model: OPENAI_MODEL, // gpt-4o, gpt-3.5-turbo, etc. Pulled from .env file max_tokens: 1024, temperature, response_format: { type: "json_object", }, messages: [ { role: 'system', content: systemPrompt }, { role: 'user', content: userPrompt } ], // @ts-expect-error data_sources is a custom property used with the "Azure Add Your Data" feature data_sources: dataSources }); return completion; } function checkRequiredEnvVars(requiredEnvVars: string[]) { for (const envVar of requiredEnvVars) { if (!process.env[envVar]) { throw new Error(`Missing ${envVar} in environment variables.`); } } }Эта функция выполняет следующие действия:
Параметры:
-
systemPrompt,userPromptиtemperatureявляются основными параметрами, рассмотренными ранее. - Необязательный
dataSourcesпараметр поддерживает функцию "Azure Bring Your Own Data", которая будет описана далее в этом руководстве.
-
Проверка переменных среды:
- Функция проверяет наличие важных переменных среды, вызывая ошибку, если отсутствуют какие-либо.
Объект конфигурации:
-
configОбъект создается с помощью значений.envиз файла (OPENAI_API_KEY,OPENAI_ENDPOINT, ,OPENAI_API_VERSIONOPENAI_MODEL). Эти значения используются для создания URL-адреса для вызова Azure OpenAI.
-
Экземпляр AzureOpenAI:
- Создается экземпляр
AzureOpenAIс помощью объектаconfig. СимволAzureOpenAIявляется частьюopenaiпакета, который должен быть импортирован в верхней части файла.
- Создается экземпляр
Создание завершения:
- Функция
chat.completions.create()вызывается со следующими свойствами:-
model: указывает модель GPT (например, gpt-4o, gpt-3.5-turbo), как определено в файле.env. -
max_tokens: определяет максимальное количество маркеров для завершения. -
temperature: задает температуру выборки. Более высокие значения (например, 0,9) дают больше творческих ответов, а более низкие значения (например, 0) создают более детерминированные ответы. -
response_format: определяет формат ответа. Здесь задано значение для возврата объекта JSON. Дополнительные сведения о режиме JSON см. в справочной документации по Azure OpenAI. -
messages: содержит сообщения для создания завершения чата. В этом примере содержатся два сообщения: один из системы (определение поведения и правил) и один из пользователей (содержащий текст запроса).
-
- Функция
Возвращаемое значение:
- Функция возвращает объект завершения, созданный Azure OpenAI.
Закомментируйте следующие строки в
getSQLFromNLP()функции:// if (isProhibitedQuery(queryData.sql)) { // queryData.sql = ''; // }Сохраните openAI.ts. Сервер API автоматически перестроит код TypeScript и перезагрузит сервер.
Вернитесь в браузер и введите все имена таблиц из базы данных в входные данные пользовательского запроса . Выберите "Выполнить запрос". Отображаются ли имена таблиц?
Вернитесь к
getSQLFromNLP()функции на сервере или openAI.ts и добавьте следующее правило вRules:раздел системного запроса, а затем сохраните файл.- Do not allow the SELECT query to return table names, function names, or procedure names.Вернитесь в браузер и выполните следующие задачи:
- Введите все имена таблиц из базы данных в входные данные пользовательского запроса . Выберите "Выполнить запрос". Отображаются ли имена таблиц?
- Введите все имена функций из базы данных. В входные данные настраиваемого запроса и снова нажмите кнопку "Выполнить запрос ". Отображаются ли имена функций?
ВОПРОС. Будет ли модель всегда соответствовать правилам, заданным в запросе?
ОТВЕТ: Нет! Важно отметить, что модели OpenAI могут возвращать непредвиденные результаты иногда, которые могут не соответствовать определенным правилам. Важно планировать это в коде.
Вернитесь на сервер или openAI.ts и найдите функцию
isProhibitedQuery(). Это пример кода после последующей обработки, который может выполняться после возврата результатов в Azure OpenAI. Обратите внимание, что свойство присваиваетсяsqlпустой строке, если запрещенные ключевые слова возвращаются в созданном SQL-запросе. Это гарантирует, что если непредвиденные результаты возвращаются из Azure OpenAI, sql-запрос не будет выполняться в базе данных.function isProhibitedQuery(query: string): boolean { if (!query) return false; const prohibitedKeywords = [ 'insert', 'update', 'delete', 'drop', 'truncate', 'alter', 'create', 'replace', 'information_schema', 'pg_catalog', 'pg_tables', 'pg_proc', 'pg_namespace', 'pg_class', 'table_schema', 'table_name', 'column_name', 'column_default', 'is_nullable', 'data_type', 'udt_name', 'character_maximum_length', 'numeric_precision', 'numeric_scale', 'datetime_precision', 'interval_type', 'collation_name', 'grant', 'revoke', 'rollback', 'commit', 'savepoint', 'vacuum', 'analyze' ]; const queryLower = query.toLowerCase(); return prohibitedKeywords.some(keyword => queryLower.includes(keyword)); }Замечание
Важно отметить, что это только демонстрационный код. При выборе преобразования естественного языка в SQL могут быть другие запрещенные ключевые слова, необходимые для покрытия конкретных вариантов использования. Это функция, которую необходимо запланировать и использовать с осторожностью, чтобы гарантировать, что возвращаются только допустимые запросы SQL и выполняются в базе данных. Помимо запрещенных ключевых слов, также необходимо учитывать безопасность.
Вернитесь к серверу или openAI.ts и раскомментируйте следующий код в
getSQLFromNLP()функции. Сохраните файл.if (isProhibitedQuery(queryData.sql)) { queryData.sql = ''; }Удалите следующее правило из
systemPromptфайла и сохраните его.- Do not allow the SELECT query to return table names, function names, or procedure names.Вернитесь в браузер, введите все имена таблиц из базы данных в входные данные пользовательского запроса и нажмите кнопку "Выполнить запрос ".
Отображаются ли результаты таблицы? Даже без правила
isProhibitedQueryкод после обработки запрещает выполнение этого типа запроса в базе данных.Как уже говорилось ранее, интеграция естественного языка с SQL в бизнес-приложениях может быть довольно полезной для пользователей, но она имеет собственный набор рекомендаций.
Преимущества.
Удобство работы с пользователем. Эта функция может сделать взаимодействие с базами данных более доступными для пользователей без технического опыта, уменьшая потребность в знаниях SQL и потенциально ускоряя операции.
Повышение производительности: бизнес-аналитики, специалисты по маркетингу, руководители и другие нетехническая пользователи могут получать ценные сведения из баз данных без необходимости полагаться на технических экспертов, тем самым повышая эффективность.
Широкое приложение. С помощью расширенных языковых моделей приложения могут быть разработаны для обеспечения широкого спектра пользователей и вариантов использования.
Соображения.
Безопасность: одной из самых больших проблем является безопасность. Если пользователи могут взаимодействовать с базами данных с помощью естественного языка, необходимо обеспечить надежные меры безопасности, чтобы предотвратить несанкционированный доступ или вредоносные запросы. Вы можете реализовать режим только для чтения, чтобы запретить пользователям изменять данные.
Конфиденциальность данных. Некоторые данные могут быть конфиденциальными и не должны быть легко доступными, поэтому вам потребуется обеспечить надлежащие гарантии и разрешения пользователей.
Точность. В то время как обработка естественного языка значительно улучшилась, это не идеально. Неправильное представление запросов пользователей может привести к неточным результатам или непредвиденному поведению. Вам потребуется спланировать, как будут обрабатываться непредвиденные результаты.
Эффективность. Нет никаких гарантий, что SQL, возвращенный из запроса естественного языка, будет эффективным. В некоторых случаях дополнительные вызовы к Azure OpenAI могут потребоваться, если правила после обработки обнаруживают проблемы с запросами SQL.
Обучение и адаптация пользователей: пользователям необходимо обучено правильно сформулировать свои запросы. Хотя это проще, чем обучение SQL, может быть и кривая обучения.
Перед переходом к следующему упражнению следует рассмотреть несколько окончательных пунктов:
- Помните, что "Просто потому, что вы не можете означать, что вы должны" применяется здесь. Используйте крайне осторожность и тщательное планирование перед интеграцией естественного языка с SQL в приложение. Важно понимать потенциальные риски и планировать их.
- Прежде чем использовать эту технологию, обсудите потенциальные сценарии с командой, администраторами баз данных, командой безопасности, заинтересованными лицами и другими соответствующими сторонами, чтобы убедиться, что она подходит для вашей организации. Важно обсудить, соответствует ли естественному языку SQL безопасность, конфиденциальность и другие требования вашей организации.
- Безопасность должна быть основной проблемой и встроена в процесс планирования, разработки и развертывания.
- Хотя естественный язык для SQL может быть очень мощным, тщательное планирование должно перейти в него, чтобы обеспечить наличие необходимых правил и включена функция после обработки. Запланируйте дополнительное время для реализации и тестирования таких функций и для учета сценариев, в которых возвращаются непредвиденные результаты.
- С помощью Azure OpenAI клиенты получают возможности безопасности Microsoft Azure, выполняя те же модели, что и OpenAI. Azure OpenAI предлагает частные сети, региональную доступность и ответственную фильтрацию контента ИИ. Дополнительные сведения о данных, конфиденциальности и безопасности для Azure OpenAI.
Теперь вы узнали, как использовать Azure OpenAI для преобразования естественного языка в SQL и узнали о преимуществах и недостатках реализации этого типа функций. В следующем упражнении вы узнаете, как создавать сообщения электронной почты и SMS с помощью Azure OpenAI.