AI でデータソースをクエリする
データベースについて自然言語で質問し、回答、チャート、およびそれらを生成するために使用されたクエリを取得します。
Query with AI を使用する理由
ユーザーはデータベースからの回答を求めていますが、SQL は書きません。プロダクトチームはチケットを起票せずに「各リージョンにアクティブユーザーは何人いますか?」を知りたいと考えています。サポートチームはスキーマを学ぶことなく「過去 24 時間で最も一般的なエラーメッセージ」を見つけたいと考えています。
データベース用の自然言語インターフェースを構築するには、独自の prompt engineering、schema serialization、query validation、error correction、result formatting を実装する必要があります。Query with AI では、バックエンドがこれらすべてを処理します。
- TypeScript
- Python
const response = await this.squid.ai().executeAiQuery(
'postgres',
'How many users signed up last week, broken down by country?',
);
console.log(response.answer); // "1,247 users signed up last week..."
console.log(response.executedQueries); // The actual SQL Squid ran
response = await self.squid.execute_ai_query(
'postgres',
'How many users signed up last week, broken down by country?',
)
print(response['answer']) # "1,247 users signed up last week..."
print(response['executedQueries']) # The actual SQL Squid ran
自然言語の質問を渡すだけです。計画、生成、実行、説明を行います。
概要
Query with AI は自然言語の prompt と database connector を受け取り、3 段階のパイプラインを実行します。
- Collection selection は、スキーマから関連するテーブルまたはコレクションを選択します
- Query generation は、データベース固有の dialect で native query を記述し、syntax error 発生時には自動で再試行します
- Result analysis は、raw row を自然言語の回答に変換します
回答、使用したクエリ、そして(任意で)raw result row を返します。
Query with AI を使用する場合
| ユースケース | 推奨 |
|---|---|
| ユーザーが自然言語でデータベースについて質問できるようにする | Query with AI |
| データからチャートやグラフを生成する | analyzeResultsOptions.enableCodeInterpreter: true を指定した Query with AI |
| 固定された予測可能なクエリを実行する | Database client を直接使用 |
| AI agent が integration ごとに custom logic でデータを取得する | integration type に attributed された AI function を使用 |
| アップロードされたドキュメントを検索する | Knowledge Bases を使用 |
仕組み
- client prompt がバックエンドに送信され、バックエンドが
executeAiQuery(integrationId, prompt, options)を呼び出します - Squid が integration の schema を読み込み、prompt とともに model に転送します
- (任意)Stage 1: Collection selection。 schema が大きい場合、Squid は model に関連するテーブルまたはコレクションのサブセットを選択するよう依頼します。小規模な schema では、この stage はスキップされます。
- Stage 2: Query generation。 model はデータベースの native dialect(SQL、Mongo aggregation、Elasticsearch DSL など)で query を記述します。Squid がそれを実行します。query に syntax error がある場合、Squid は error を model にフィードバックして再試行します(設定可能な上限まで)。
- Stage 3: Result analysis。 model は raw row を読み取り、自然言語の回答を記述します。任意で、code interpreter 内で Python を実行し、統計を計算したりチャートを描画したりします。
- 完全な response(
answer、executedQueriesなど)がコードに返されます。
クイックスタート
前提条件
squid initで初期化された Squid backend project- Squid application に追加された database connector
- connector 用に構成された schema description(以下の スキーマを構成する を参照)
ステップ 1: スキーマを構成する
Squid は collections、fields、およびそれらの descriptions を model に送信します。description が充実しているほど、model の query はより良くなります。Squid Console で descriptions を構成します。
- Squid Console を開き、Connectors タブをクリックします
- database connector を見つけ、ellipsis (…) メニューをクリックしてから Schema をクリックします
- Rediscover schema をクリックして collection と field の metadata をインポートします
- 各 collection の横にある鉛筆アイコンをクリックして description を追加し、次に各 field の ellipsis (…) をクリックして Edit field を選択し、field-level description を追加します
- 任意で Generate Descriptions with AI をクリックすると、Squid が descriptions を生成します。これにより、データの小さな sample が model に送信されます。model にデータを送信したくない場合は、代わりに descriptions を手動で記述してください。Query with AI 自体は data row ではなく schema のみを model に送信します。
- Save schema をクリックします
ステップ 2: security rule を記述する
Query with AI は connector 内の任意のデータを読み取れるため、security rule で保護する必要があります。SquidService の method に @secureAiQuery を追加します。
- TypeScript
- Python
import { secureAiQuery, SquidService } from '@squidcloud/backend';
export class SecurityService extends SquidService {
@secureAiQuery('postgres')
allowAiQuery(): boolean {
// Only authenticated users can run AI queries against the postgres connector.
return this.isAuthenticated();
}
}
from squidcloud_backend import SquidService, secure_ai_query
class SecurityService(SquidService):
@secure_ai_query('postgres')
def allow_ai_query(self) -> bool:
# Only authenticated users can run AI queries against the postgres connector.
return self.is_authenticated()
decorator に渡す integration ID は、Squid Console 内の connector ID と一致する必要があります。built-in database を保護する場合は、引数を渡さないでください。
ステップ 3: 呼び出しを executable でラップする
- TypeScript
- Python
import { executable, SquidService } from '@squidcloud/backend';
export class DataAiService extends SquidService {
@executable()
async askAboutData(question: string): Promise<string> {
this.assertIsAuthenticated();
const response = await this.squid.ai().executeAiQuery('postgres', question);
if (!response.success) {
throw new Error(response.answer || 'AI query failed');
}
// Log the query for debugging in the Squid Console logs.
for (const executed of response.executedQueries) {
console.log(`Executed: ${executed.query}`);
}
return response.answer;
}
}
from squidcloud_backend import SquidService, executable
class DataAiService(SquidService):
@executable()
async def ask_about_data(self, question: str) -> str:
self.assert_is_authenticated()
response = await self.squid.execute_ai_query('postgres', question)
if not response.get('success'):
raise RuntimeError(response.get('answer') or 'AI query failed')
# Log the query for debugging in the Squid Console logs.
for executed in response.get('executedQueries', []):
print(f"Executed: {executed['query']}")
return response['answer']
TypeScript では method は squid.ai().executeAiQuery() にあります。Python では Squid client 上で直接 squid.execute_ai_query() として利用できます。
ステップ 4: backend を実行または deploy する
squid start
cloud に deploy するには、backend の deploy を参照してください。
ステップ 5: client から呼び出す
const answer = await squid.executeFunction('askAboutData', 'How many orders shipped this week?');
console.log(answer);
Authentication と Security
Query with AI は @secureAiQuery decorator で保護されています。各 call は、現在の request に対して true を返す @secureAiQuery(integrationId) rule と一致する必要があります。一致しない場合、call は UNAUTHORIZED で拒否されます。
decorator は integration ID を引数として受け取ります。built-in database を保護するには、引数を省略してください。
- TypeScript
- Python
import { secureAiQuery, SquidService } from '@squidcloud/backend';
import { AiQueryContext } from '@squidcloud/backend';
export class SecurityService extends SquidService {
@secureAiQuery('postgres')
allowProductionQueries(context: AiQueryContext): boolean {
// The context contains the prompt and options the user submitted.
// Inspect them to apply finer-grained checks.
if (!this.isAuthenticated()) return false;
const userAuth = this.getUserAuth();
return userAuth?.attributes?.['role'] === 'analyst';
}
}
from squidcloud_backend import SquidService, secure_ai_query
class SecurityService(SquidService):
@secure_ai_query('postgres')
def allow_production_queries(self) -> bool:
if not self.is_authenticated():
return False
user_auth = self.get_user_auth()
return (user_auth or {}).get('attributes', {}).get('role') == 'analyst'
Squid security rule と request context の詳細については、security rules を参照してください。
コアコンセプト
3 段階のパイプライン
executeAiQuery の各 call は 3 つの stage を通過します。それぞれを個別に調整できます。
| Stage | 目的 | Option key |
|---|---|---|
| Collection selection | 関連するテーブル/コレクションのサブセットを選択する | selectCollectionsOptions |
| Query generation | native query を記述し、syntax error 時に再試行する | generateQueryOptions |
| Result analysis | row を自然言語の回答に変換する(任意で chart も生成) | analyzeResultsOptions |
schema 全体が model の context に収まるほど小さい場合、Squid は collection selection stage を自動的にスキップします。selectCollectionsOptions.runMode でこれを上書きできます。
サポート対象のデータベース
Query with AI は、Squid が自然言語 query 用にサポートする database connector で動作します。
- Relational SQL: MySQL、PostgreSQL、BigQuery、Snowflake、Oracle、SQL Server、SAP HANA、CockroachDB、ClickHouse、Databricks
- MongoDB および Squid built-in database
- Elasticsearch
Squid が生成する query language は connector type に応じて異なります。relational database には SQL、Mongo には MongoDB aggregation pipeline、Elasticsearch には Elasticsearch query DSL を使用します。
response object
AiQueryResponse には次の fields があります。
| Field | Type | 説明 |
|---|---|---|
answer | string | AI が生成した自然言語の回答 |
explanation | string | undefined | 回答がどのように導出されたかの任意の説明 |
executedQueries | ExecutedQueryInfo[] | Squid が実際に実行した native queries。各 entry には query、purpose、success、rawResult があります。 |
success | boolean | pipeline が正常に完了した場合は true |
usedCodeInterpreter | boolean | undefined | analysis stage が code interpreter を実行した場合は true |
clarificationQuestion | string | undefined | allowClarification が有効で、model が追加情報を必要とする場合に設定されます |
queryMarkdownType | string | undefined | query を render するための markdown language('sql'、'json'、'pure') |
ExecutedQueryInfo fields:
| Field | Type | 説明 |
|---|---|---|
query | string | Squid が実行した native query string |
purpose | string | undefined | この query が取得することを意図した内容 |
success | boolean | この個別の query が正常に実行されたか |
rawResult | AiFileUrl | undefined | raw result file の URL(enableRawResults: true の場合のみ設定) |
1 回の call で複数の executed query が生成されることがあります。call あたりの上限は 5 query です。
Configuration Options
AiQueryOptions では、各 stage の動作を調整できます。
Top-level options
| Option | Type | 説明 |
|---|---|---|
instructions | string | すべての stage に追加される free-form instructions |
enableRawResults | boolean | 各 query の result row を file storage に upload し、executedQueries[].rawResult に URL を返す |
selectCollectionsOptions | AiQuerySelectCollectionsOptions | 以下を参照 |
generateQueryOptions | AiQueryGenerateQueryOptions | 以下を参照 |
analyzeResultsOptions | AiQueryAnalyzeResultsOptions | 以下を参照 |
memoryOptions | AiAgentMemoryOptions | follow-up question 用の conversation memory。agent memory を参照。 |
generateQueriesOnly | boolean | execution と analysis をスキップします。生成された queries のみを返します。 |
validateWithAiOptions | AiQueryValidateWithAiOptions | execution 前に生成された queries を検証するため、2 回目の AI pass を実行します |
Collection selection options
pipeline の Stage 1 を制御します。
| Field | Type | 説明 |
|---|---|---|
collectionsToUse | string[] | query をこの collection のサブセットに制限します。省略時は、Squid が schema 全体を考慮します。 |
runMode | 'default' | 'force' | 'disable' | 'default' では Squid が stage を実行するかどうかを決定します。'force' は常に実行します。'disable' は stage をスキップし、full schema(または collectionsToUse)を Stage 2 に渡します。 |
aiOptions | AiChatOptions | この stage で使用する model と chat options を上書きします |
Query generation options
pipeline の Stage 2 を制御します。
| Field | Type | 説明 |
|---|---|---|
aiOptions | AiChatOptions | この stage で使用する model と chat options を上書きします |
maxErrorCorrections | number | 生成された query に syntax error がある場合の自動 retry pass の最大数。デフォルトは 2。最大 10。 |
agentId | string | この stage に特定の AI agent を使用します |
allowClarification | boolean | prompt が曖昧、または回答不能な場合、推測する代わりに clarificationQuestion を返します |
Analyze results options
pipeline の Stage 3 を制御します。
| Field | Type | 説明 |
|---|---|---|
disabled | boolean | analysis stage を完全にスキップします。response には生成された queries と raw results のみが含まれます。 |
enableCodeInterpreter | boolean | analysis を Python code interpreter で実行します。統計の計算や chart の描画が可能です |
aiOptions | AiChatOptions | この stage で使用する model と chat options を上書きします |
agentId | string | この stage に特定の AI agent を使用します |
コード例
Query with AI を特定のテーブルに制限する
残りの部分を公開せずに、ユーザーがデータベースの 1 つの部分について質問できるようにしたい場合に役立ちます。
- TypeScript
- Python
const response = await this.squid.ai().executeAiQuery('mysql', 'List all people, showing only their ID and height', {
selectCollectionsOptions: {
runMode: 'disable',
collectionsToUse: ['people'],
},
enableRawResults: true,
});
// Download and inspect the raw rows produced by the query.
const url = response.executedQueries[0]?.rawResult?.url;
if (url) {
const fileResponse = await fetch(url);
const rows = await fileResponse.json();
console.log(rows);
}
response = await self.squid.execute_ai_query(
'mysql',
'List all people, showing only their ID and height',
options={
'selectCollectionsOptions': {
'runMode': 'disable',
'collectionsToUse': ['people'],
},
'enableRawResults': True,
},
)
# Download and inspect the raw rows produced by the query.
raw_result = (response.get('executedQueries') or [{}])[0].get('rawResult')
if raw_result:
import httpx
async with httpx.AsyncClient() as http:
file_response = await http.get(raw_result['url'])
rows = file_response.json()
print(rows)
code interpreter で chart を生成する
enableCodeInterpreter が true の場合、analysis stage は Python を実行して summary を計算し、chart を描画できます。これは「X のチャートを表示して」を実現する方法です。
- TypeScript
- Python
const response = await this.squid.ai().executeAiQuery('postgres', 'Plot a bar chart of order volume per region for last quarter.', {
analyzeResultsOptions: {
enableCodeInterpreter: true,
},
});
console.log(response.answer);
console.log('Used code interpreter:', response.usedCodeInterpreter);
response = await self.squid.execute_ai_query(
'postgres',
'Plot a bar chart of order volume per region for last quarter.',
options={
'analyzeResultsOptions': {
'enableCodeInterpreter': True,
},
},
)
print(response['answer'])
print('Used code interpreter:', response.get('usedCodeInterpreter'))
推測する代わりに clarification を求める
- TypeScript
- Python
const response = await this.squid.ai().executeAiQuery('mysql', 'Show me the top users.', {
generateQueryOptions: { allowClarification: true },
});
if (response.clarificationQuestion) {
// Surface this back to the user, then re-call with the refined prompt.
return { needsClarification: response.clarificationQuestion };
}
return { answer: response.answer };
response = await self.squid.execute_ai_query(
'mysql',
'Show me the top users.',
options={
'generateQueryOptions': {'allowClarification': True},
},
)
if response.get('clarificationQuestion'):
# Surface this back to the user, then re-call with the refined prompt.
return {'needsClarification': response['clarificationQuestion']}
return {'answer': response['answer']}
follow-up question 用の memory
- TypeScript
- Python
// First question
await this.squid.ai().executeAiQuery('mysql', 'How many people taller than 6 feet do we have?', {
memoryOptions: { memoryId: 'session-42', memoryMode: 'read-write' },
});
// Follow-up that depends on the prior context
const followUp = await this.squid.ai().executeAiQuery('mysql', 'What are their average ages?', {
memoryOptions: { memoryId: 'session-42', memoryMode: 'read-write' },
});
# First question
await self.squid.execute_ai_query(
'mysql',
'How many people taller than 6 feet do we have?',
options={
'memoryOptions': {'memoryId': 'session-42', 'memoryMode': 'read-write'},
},
)
# Follow-up that depends on the prior context
follow_up = await self.squid.execute_ai_query(
'mysql',
'What are their average ages?',
options={
'memoryOptions': {'memoryId': 'session-42', 'memoryMode': 'read-write'},
},
)
query generation に特定の model を使用する
- TypeScript
- Python
await this.squid.ai().executeAiQuery('mysql', 'How many users signed up yesterday?', {
generateQueryOptions: {
aiOptions: { model: 'claude-sonnet-4-6' },
maxErrorCorrections: 5,
},
validateWithAiOptions: { enabled: true },
});
await self.squid.execute_ai_query(
'mysql',
'How many users signed up yesterday?',
options={
'generateQueryOptions': {
'aiOptions': {'model': 'claude-sonnet-4-6'},
'maxErrorCorrections': 5,
},
'validateWithAiOptions': {'enabled': True},
},
)
Squid Console の testing UI を使用する
Query with AI を試すためにコードを書く必要はありません。schema を構成した後、Squid Console の schema view から Query with AI をクリックし、plain English で質問してください。これは schema description を反復改善する最速の方法です。

Error Handling
一般的なエラー
| Error | 原因 | 解決策 |
|---|---|---|
UNAUTHORIZED | true を返す @secureAiQuery(integrationId) rule がない | integration に一致し、呼び出しユーザーに対して true を返す security rule を追加します |
This integration cannot be used yet | connector に schema が構成されていない | Squid Console で schema descriptions を構成します |
Integration not found | integrationId がどの connector とも一致しない | Squid Console で connector ID を確認します |
| Query syntax errors | 生成された query が database dialect に対して無効 | Squid は maxErrorCorrections 回まで自動的に再試行します。必要に応じて上限を増やしてください。 |
| Mutation rejected | 生成された query が write(INSERT、UPDATE、DELETE、$out、$merge)を試行した | Query with AI は設計上 read-only です。prompt を再構成するか、write には executables を使用してください。 |
| Pipeline succeeded but answer is wrong | schema descriptions が欠落している、または誤解を招く | Squid Console で collection と field の descriptions を改善します |
実行された query を確認する
回答が正しく見えない場合、最初に確認すべきなのは Squid が実際に実行した query です。response.executedQueries を log に記録し、query を直接 database に対して再実行して、何が返されたかを確認します。
- TypeScript
- Python
const response = await this.squid.ai().executeAiQuery('postgres', question);
for (const executed of response.executedQueries) {
console.log(`Purpose: ${executed.purpose}`);
console.log(`Query: ${executed.query}`);
console.log(`Success: ${executed.success}`);
}
response = await self.squid.execute_ai_query('postgres', question)
for executed in response.get('executedQueries', []):
print(f"Purpose: {executed.get('purpose')}")
print(f"Query: {executed['query']}")
print(f"Success: {executed.get('success')}")
ベストプラクティス
- schema descriptions に投資する。 Query with AI の精度は、collection と field の descriptions の品質にほぼ完全に依存します。曖昧な descriptions は曖昧な queries を生成します。
- 必ず
@secureAiQueryrule を追加する。 rule がない場合、その integration に対するexecuteAiQueryの calls は block されます。permissive な rule を使用すると、誰でも connector 内の任意のデータを読み取れます。他の access control surface と同様に扱ってください。 collectionsToUseを使用して queries の scope を限定する。 ユーザーがデータベースの 1 つの領域についてのみ質問する必要がある場合、利用可能な collections を制限することで query を高速化し、hallucinated join の可能性を減らせます。- AI query executable に rate limiting を適用します。各 call には model token と database CPU のコストがかかります。
- read-heavy なユースケースでは prompt ごとに cache する。 同一の prompt は同一の query を生成することがよくあります。client-side caching を使用して再実行を避けます。
- 生成された queries が production data に到達する前に追加チェックが必要な場合は、
validateWithAiOptionsを有効にします。 - 自分でデータを render する必要がある場合(charts、tables、exports)は、
enableRawResultsを有効にします。 result file URL はexecutedQueries[].rawResultに含まれます。
関連項目
- Database connectors - Query with AI の data source を構成する
- Executables - client から呼び出せるように
executeAiQueryをラップする - Security rules -
@secureAiQueryで AI queries を保護する - AI agent - Query with AI を tool として使用する完全な agent を構築する
- AI functions -
executeAiQuery以上の機能を必要とするユースケース向けの custom AI tools