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 が計画、生成、実行、説明まで行います。
Overview
Query with AI は、自然言語の prompt と database connector を受け取り、3 段階のパイプラインを実行します。
- Collection selection で、スキーマから関連するテーブルまたはコレクションを選択します
- Query generation で、データベース固有の dialect でネイティブクエリを作成し、構文エラー時には自動リトライします
- Result analysis で、生の行データを自然言語の回答に変換します
回答、使用したクエリ、そして(必要に応じて)生の結果行を返します。
Query with AI を使うべき場面
| Use Case | Recommendation |
|---|---|
| データベースについて自然言語で質問できるようにする | Query with AI |
| データからチャートやグラフを生成する | analyzeResultsOptions.enableCodeInterpreter: true を指定した Query with AI |
| 固定で予測可能なクエリを実行する | Database client を直接使用する |
| integration ごとのカスタムロジックで AI agent にデータ取得させる | integration type に紐づいた AI function を使う |
| アップロードされたドキュメントを検索する | Knowledge Bases を使う |
仕組み
- クライアントの prompt はバックエンドに送信され、
executeAiQuery(integrationId, prompt, options)が呼び出されます - Squid は integration のスキーマを読み込み、prompt とともにモデルへ渡します
- (任意)Stage 1: Collection selection. スキーマが大きい場合、Squid は関連するテーブルまたはコレクションのサブセットを選ぶようモデルに依頼します。スキーマが小さい場合、この段階はスキップされます
- Stage 2: Query generation. モデルはデータベース固有の dialect(SQL、Mongo aggregation、Elasticsearch DSL など)でクエリを書きます。Squid がそれを実行します。クエリに構文エラーがある場合、Squid はそのエラーをモデルに返してリトライします(設定可能な上限まで)
- Stage 3: Result analysis. モデルは生の行データを読み取り、自然言語の回答を書きます。必要に応じて、code interpreter 内で Python を実行して統計計算やチャート描画を行います
- 完全なレスポンス(
answer、executedQueriesなど)がコードに返されます
Quick Start
Prerequisites
squid initで初期化された Squid backend project- Squid application に追加された database connector
- connector 用に設定された schema descriptions(以下の Configure your schema を参照)
Step 1: スキーマを設定する
Squid は、コレクション、フィールド、およびそれらの説明をモデルに送信します。説明が充実しているほど、モデルのクエリ品質は高くなります。説明は Squid Console で設定します。
- Squid Console を開き、Connectors タブをクリックします
- 対象の database connector を見つけて ellipsis (…) メニューをクリックし、Schema を選択します
- Rediscover schema をクリックして、collection と field の metadata を取り込みます
- 各 collection の横にある鉛筆アイコンをクリックして説明を追加し、各 field の ellipsis (…) をクリックして Edit field を選択し、field レベルの説明を追加します
- 必要に応じて Generate Descriptions with AI をクリックすると、Squid が説明を自動生成します。この処理ではデータの小さなサンプルがモデルに送信されます。モデルにデータを一切送信したくない場合は、代わりに手動で説明を書いてください。Query with AI 自体はデータ行をモデルに送信せず、送信するのはスキーマのみです
- Save schema をクリックします
Step 2: security rule を書く
Query with AI は connector 内のあらゆるデータを読み取れるため、security rule で保護する必要があります。SquidService 上のメソッドに @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 を保護する場合は、引数を渡さないでください。
Step 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 では、このメソッドは squid.ai().executeAiQuery() にあります。Python では、Squid client 上の squid.execute_ai_query() として直接提供されています。
Step 4: backend を実行またはデプロイする
squid start
クラウドへデプロイする場合は、deploying your backend を参照してください。
Step 5: client から呼び出す
const answer = await squid.executeFunction('askAboutData', 'How many orders shipped this week?');
console.log(answer);
Authentication and Security
Query with AI は @secureAiQuery decorator によって保護されます。各呼び出しは、現在のリクエストに対して true を返す @secureAiQuery(integrationId) ルールに一致する必要があります。一致しない場合、その呼び出しは 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 rules と request context の詳細については、security rules を参照してください。
Core Concepts
3 段階のパイプライン
executeAiQuery の各呼び出しは 3 つの段階を通って処理され、それぞれを個別に調整できます。
| Stage | Purpose | Option key |
|---|---|---|
| Collection selection | 関連するテーブル/コレクションのサブセットを選ぶ | selectCollectionsOptions |
| Query generation | ネイティブクエリを書き、構文エラー時にリトライする | generateQueryOptions |
| Result analysis | 行データを自然言語の回答に変換する(必要に応じて chart 化) | analyzeResultsOptions |
スキーマが十分に小さく、全体がモデルの context に収まる場合、Squid は collection selection 段階を自動的にスキップします。この挙動は selectCollectionsOptions.runMode で上書きできます。
サポートされるデータベース
Query with AI は、Squid が自然言語クエリに対応している database connector で利用できます。
- Relational SQL: MySQL、PostgreSQL、BigQuery、Snowflake、Oracle、SQL Server、SAP HANA、CockroachDB、ClickHouse、Databricks
- MongoDB と Squid built-in database
- Elasticsearch
Squid が生成するクエリ言語は connector type に依存します。relational database では SQL、Mongo では MongoDB aggregation pipeline、Elasticsearch では Elasticsearch query DSL を生成します。
response object
AiQueryResponse には以下のフィールドがあります。
| Field | Type | Description |
|---|---|---|
answer | string | AI が生成した自然言語の回答 |
explanation | string | undefined | 回答がどのように導かれたかについての任意の説明 |
executedQueries | ExecutedQueryInfo[] | Squid が実際に実行したネイティブクエリ。各要素は query、purpose、success、rawResult を持ちます。 |
success | boolean | パイプラインが正常に完了した場合は true |
usedCodeInterpreter | boolean | undefined | analysis 段階で code interpreter が実行された場合は true |
clarificationQuestion | string | undefined | allowClarification が有効で、モデルが追加情報を必要とする場合に設定されます |
queryMarkdownType | string | undefined | クエリ表示に使う markdown language('sql'、'json'、'pure') |
ExecutedQueryInfo のフィールド:
| Field | Type | Description |
|---|---|---|
query | string | Squid が実行したネイティブクエリ文字列 |
purpose | string | undefined | このクエリが取得しようとしていた内容 |
success | boolean | この個別クエリが正常に実行されたかどうか |
rawResult | AiFileUrl | undefined | 生の結果ファイルへの URL(enableRawResults: true の場合のみ設定) |
1 回の呼び出しで複数の executed query が生成されることがあります。1 回あたりの上限は 5 クエリです。
Configuration Options
AiQueryOptions では、各段階の挙動を調整できます。
Top-level options
| Option | Type | Description |
|---|---|---|
instructions | string | すべての段階に追加される自由形式の instructions |
enableRawResults | boolean | 各クエリの結果行を file storage にアップロードし、その URL を executedQueries[].rawResult に返します |
selectCollectionsOptions | AiQuerySelectCollectionsOptions | 下記を参照 |
generateQueryOptions | AiQueryGenerateQueryOptions | 下記を参照 |
analyzeResultsOptions | AiQueryAnalyzeResultsOptions | 下記を参照 |
memoryOptions | AiAgentMemoryOptions | follow-up question 用の conversation memory。詳細は agent memory を参照してください |
generateQueriesOnly | boolean | 実行と analysis をスキップし、生成されたクエリだけを返します |
validateWithAiOptions | AiQueryValidateWithAiOptions | 実行前に、生成されたクエリを検証するための 2 回目の AI pass を実行します |
Collection selection options
パイプラインの Stage 1 を制御します。
| Field | Type | Description |
|---|---|---|
collectionsToUse | string[] | クエリ対象をこの collection のサブセットに限定します。省略した場合、Squid はスキーマ全体を対象にします |
runMode | 'default' | 'force' | 'disable' | 'default' はこの段階を実行するかどうかを Squid に任せます。'force' は常に実行します。'disable' はこの段階をスキップし、完全なスキーマ(または collectionsToUse)を Stage 2 に渡します |
aiOptions | AiChatOptions | この段階で使用する model と chat options を上書きします |
Query generation options
パイプラインの Stage 2 を制御します。
| Field | Type | Description |
|---|---|---|
aiOptions | AiChatOptions | この段階で使用する model と chat options を上書きします |
maxErrorCorrections | number | 生成されたクエリに構文エラーがある場合の自動リトライ回数の上限です。デフォルトは 2。最大 10。 |
agentId | string | この段階で特定の AI agent を使います |
allowClarification | boolean | prompt が曖昧または回答不可能な場合に、推測する代わりに clarificationQuestion を返します |
Analyze results options
パイプラインの Stage 3 を制御します。
| Field | Type | Description |
|---|---|---|
disabled | boolean | analysis 段階を完全にスキップします。response には生成されたクエリと raw results のみが含まれます |
enableCodeInterpreter | boolean | analysis を Python code interpreter 経由で実行し、統計計算や chart 描画を可能にします |
aiOptions | AiChatOptions | この段階で使用する model と chat options を上書きします |
agentId | string | この段階で特定の AI agent を使います |
Code Examples
Query with AI を特定のテーブルに制限する
データベース全体を公開せず、一部分についてだけユーザーに質問させたい場合に便利です。
- 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 でチャートを生成する
enableCodeInterpreter が true の場合、analysis 段階で Python を実行してサマリー計算やチャート描画ができます。これは「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 を試すのにコードを書く必要はありません。スキーマを設定したら、Squid Console の schema view から Query with AI をクリックし、プレーンな英語で質問してください。これは schema descriptions を改善しながら素早く試行錯誤する最速の方法です。

Error Handling
よくあるエラー
| Error | Cause | Solution |
|---|---|---|
UNAUTHORIZED | @secureAiQuery(integrationId) ルールで true を返すものが存在しない | 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 | 生成されたクエリが database dialect に対して無効 | Squid は自動的に maxErrorCorrections 回までリトライします。必要なら上限を増やしてください |
| Mutation rejected | 生成されたクエリが書き込みを試みた(INSERT, UPDATE, DELETE, $out, $merge) | Query with AI は設計上 read-only です。prompt を見直すか、書き込みには executables を使用してください |
| Pipeline succeeded but answer is wrong | schema descriptions が不足しているか、誤解を招く内容になっている | Squid Console で collection と field の descriptions を改善してください |
実行されたクエリを確認する
回答がおかしく見える場合、最初に確認すべきなのは Squid が実際に実行したクエリです。response.executedQueries をログに出し、クエリをデータベースに対して直接再実行して、何が返ってきたかを確認してください。
- 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')}")
Best Practices
- schema descriptions に投資する。 Query with AI の精度は、ほぼ完全に collection と field の説明の質に依存します。曖昧な説明は曖昧なクエリを生みます。
- 必ず
@secureAiQueryルールを追加する。 これがないと、その integration に対するexecuteAiQuery呼び出しはブロックされます。逆に、過度に緩いルールだと、誰でも connector 内のあらゆるデータを読めてしまいます。他のアクセス制御面と同様に慎重に扱ってください。 - クエリの範囲指定に
collectionsToUseを使う。 ユーザーがデータベースの一部だけを質問できればよい場合、利用可能な collection を制限することでクエリが高速化し、hallucinated joins の可能性も減らせます。 - AI query executable には rate limiting を適用する。 各呼び出しには model tokens と database CPU のコストがかかります。
- 読み取り中心のユースケースでは prompt 単位でキャッシュする。 同一の prompt は同一のクエリを生成することがよくあります。client-side caching を利用して再実行を避けてください。
- 本番データに当てる前に追加確認が必要なら
validateWithAiOptionsを有効にする。 生成されたクエリに対する追加の検証を行えます。 - 自分でデータを描画したい場合は
enableRawResultsを有効にする。(charts、tables、exports など)結果ファイルの URL はexecutedQueries[].rawResultに含まれます。
See Also
- Database connectors - Query with AI のデータソースを設定する
- Executables - client から呼び出せるように
executeAiQueryをラップする - Security rules -
@secureAiQueryを使って AI query を保護する - AI agent - Query with AI をツールとして使うフル機能の agent を構築する
- AI functions -
executeAiQuery以上のことが必要なユースケース向けのカスタム AI tools