ナレッジベース
AI エージェント用の検索可能なコンテキストを保存し、メタデータスキーマ、自動抽出、クエリ時フィルタリングで管理します。
ナレッジベースを使用する理由
ナレッジベースには、AI エージェントが質問への回答時に参照するコンテキストが保存されます。これは Agent Studio の Knowledge Base 機能と同じものです。コンテキストを追加すると、基盤となる AI モデルには含まれていない可能性がある特定のトピックについて、エージェントが関連性の高い回答を提供できるようになります。
以下はシンプルなコード例ですが、追加できるコンテキストははるかに複雑にできます。コンテキストの適切な例には、コードドキュメント、製品マニュアル、ビジネス運用情報(例: 営業時間)、ユーザー固有データなどのリソースがあります。コンテキストのタイプを組み合わせることで、AI エージェント向けの堅牢なナレッジベースを作成し、ユーザーが必要とするあらゆる情報を提供できるようにします。
ナレッジベースの作成
エージェントのコンテキストを追加または更新するには、まずナレッジベースを作成して接続する必要があります。
まず、標準で提供される embedding model を使用して新しいナレッジベースを作成します。
await squid.ai().knowledgeBase('banking-knowledgebase').upsertKnowledgeBase({
description: 'This Knowledge Base contains information on card data',
embeddingModel: 'text-embedding-3-small',
chatModel: 'gpt-5.5',
metadataFields: [],
});
または、connector ID、モデル名、dimensions を含むオブジェクトを渡して、integration ベースの embedding model を使用できます。設定手順については、OpenAI Compatible Embedding connectorを参照してください。
await squid
.ai()
.knowledgeBase('banking-knowledgebase')
.upsertKnowledgeBase({
description: 'This Knowledge Base contains information on card data',
embeddingModel: {
integrationId: 'my-embeddings',
model: 'text-embedding-3-small',
dimensions: 1536,
},
chatModel: 'gpt-5.5',
metadataFields: [],
});
ナレッジベースは、'mongoAtlas' または 'postgres' のいずれかのバックエンドに vectors を保存します。'mongoAtlas' はネイティブ hybrid fusion、ランク付けされた keyword search(Keyword searchを参照)、およびknowledge graph searchをサポートします。一方、'postgres' はこれらをサポートしません。vectorDbType を省略するとサーバーのデフォルトが使用され、その値はアプリケーションの実行先デプロイメントに依存します。アプリケーションが特定のバックエンドに依存する場合は明示的に渡してください。バックエンドは作成後に変更できません。getKnowledgeBase() で取得できます。
await squid.ai().knowledgeBase('banking-knowledgebase-atlas').upsertKnowledgeBase({
description: 'This Knowledge Base contains information on card data',
embeddingModel: 'text-embedding-3-small',
chatModel: 'gpt-5.5',
metadataFields: [],
vectorDbType: 'mongoAtlas',
});
const kb = await squid.ai().knowledgeBase('banking-knowledgebase-atlas').getKnowledgeBase();
console.log(kb?.vectorDbType); // 'mongoAtlas'
getKnowledgeBase() は保存済みのナレッジベースレコード(vectorDbType を含む)を返します。指定した ID のナレッジベースが存在しない場合は undefined を返します。既存のナレッジベースに異なる vectorDbType を指定して upsert すると、バックエンドを変更するのではなくエラーが発生します。
バックエンドは作成時に固定されるため、knowledge graph searchを有効化できるかどうかも決まります。'postgres' 上に作成されたナレッジベースには graph を追加できません。将来的に graph が必要になる可能性がある場合は、サーバーのデフォルトに依存せず vectorDbType: 'mongoAtlas' を渡してください。
コンテキストの Upsert
ナレッジベースにコンテキストを追加するには、コンテキストとそのタイプを渡して upsertContext() メソッドを使用します。
upsertContext() メソッドは context ID を受け取ります。context ID を指定すると、後で変更したいときにコンテキストへより簡単にアクセスできます。
const data = `Platinum Mastercard® Fair Credit, No annual fee. Flexible due dates...`;
await squid.ai().knowledgeBase('banking-knowledgebase').upsertContext({
type: 'text',
title: 'Credit Card Info',
text: data,
contextId: 'credit-cards',
});
あるいは、upsertContexts() を使用してコンテキストの配列を upsert できます。
const creditCard1 = `Platinum Mastercard® Fair Credit, No annual fee. Flexible due dates...`;
const creditCard2 = `Gold Mastercard®, $50 annual fee. Due dates once a month...`;
await squid
.ai()
.knowledgeBase('banking-knowledgebase')
.upsertContexts([
{
type: 'text',
title: 'Credit Card 1 Info',
text: creditCard1,
contextId: 'credit-cards1',
},
{
type: 'text',
title: 'Credit Card 2 Info',
text: creditCard2,
contextId: 'credit-cards2',
},
]);
個々のコンテキストが拒否された場合でも、upsertContexts() は完了します。各拒否は
failures に一覧表示されます。拒否には errorMessage が含まれ、機械可読な分類が
適用される場合は errorCode も含まれます。
errorCode | 意味 | 対処方法 |
|---|---|---|
DUPLICATE_CONTENT | リクエストで contextId が省略され、そのコンテンツがナレッジベース内の既存コンテキストと byte-identical です。 | 失敗ではありません。duplicateOf が既存のコンテキストを指すため、元の場所をユーザーに表示できます。 |
EMBEDDING_FAILED | 抽出には成功しましたが、コンテキストの chunks の embedding に失敗しました。何も書き込まれず、上書き対象は以前のコンテンツを維持します。 | リクエストをそのまま再試行してください。変更なしで安全に再実行できます。 |
エージェントへの接続
ナレッジベースはエージェントに接続されるまで、そのエージェントの回答に影響しません。ナレッジベースを接続し、エージェントでの使用方法を設定するには、Connect a Knowledge Base to an Agentを参照してください。
コンテキストのタイプ
サポートされるコンテキストタイプは text と file の 2 種類です。
Text context は、コンテキストを含む文字列で作成します。
const data = `Platinum Mastercard® Fair Credit, No annual fee. Flexible due dates...`;
await squid.ai().knowledgeBase('banking-knowledgebase').upsertContext({
type: 'text',
title: 'Credit Card Info',
text: data,
contextId: 'credit-cards',
});
File context は、upsertContext() メソッドの第 2 引数として File オブジェクトを指定して作成します。ファイルは Squid にアップロードされ、その内容からコンテキストが作成されます。File context では、ドキュメントの抽出方法を選択する preferredExtractionMethod フィールドをコンテキストオブジェクト(upsertContext() の第 1 引数)に指定することもできます。たとえば legacy_with_llm(Console では Basic + page understanding と表示)は、テキストに加えて各ページの AI description を追加します。詳細については、Extraction methods を参照してください。
const file = new File([contextBlob], 'CreditCardList.pdf', { type: 'application/pdf' });
await squid.ai().knowledgeBase('banking-knowledgebase').upsertContext(
{
type: 'file',
contextId: 'credit-cards',
preferredExtractionMethod: 'legacy_with_llm',
},
file
);
コンテキストの長さに制限はありません。ただし、LLM prompts には文字数制限があるため、ユーザーの問い合わせとともに実際に含められるのはコンテキストの一部だけになることがあります。prompt を構築する際、Squid は提供されたコンテキストのうち、ユーザーの質問との関連性が最も高い部分を判断します。
スプレッドシートファイル
file context としてアップロードされたスプレッドシートファイル(.csv、.tsv、.xlsx、.xlsm、.xls、.xlsb)は、専用の ingestion pipeline で処理されます。Squid は未加工のセルテキストを chunking する代わりに、workbook の構造(sheet 名とサイズ、header rows、非表示 sheets、ファイル形式で提供される場合は charts と pivot tables)を抽出し、workbook 全体の生成済みサマリーを embedding します。したがって、スプレッドシートコンテキストの検索結果は、セルデータの断片を返すのではなく、workbook に含まれる内容を説明します。
サマリーはプレビューであり、エージェントは正確な数値を得るために依存しません。接続されたナレッジベースにスプレッドシートコンテキストが含まれる場合、エージェントは sandbox 内で Python を実行し、実際にアップロードされたファイルに対して質問へ回答する querySpreadsheetsWithAi tool を自動的に取得します。
- 正確な値: 件数、合計、平均、特定 row または cell の lookup、filtering、sorting。
- 複数の workbook にまたがる質問。たとえば、単一の呼び出しでファイル間のデータを join または比較する場合。
- 構造と provenance に関する質問。sheet に実際に何が含まれているか、どの sheets がライブ計算に入力されるか、どの cells が formula でどれが hardcoded inputs か。formula と dependency の検査は
.xlsx/.xlsmで最も充実しており、.xlsでは部分的、.xlsb(cell values のみ)および CSV/TSV(formula metadata なし)では利用できません。
設定は必要ありませんが、専用 pipeline と agent tool は保持された元のファイルに依存します。discardOriginalFile: true(upsertContext() の file option。デフォルトは false。再処理および download 用に保持するのではなく、text extraction 後に保存済みの元ファイルを Squid が破棄するよう指示します)を指定してコンテキストをアップロードすると、スプレッドシートは抽出されたプレーンテキストとして ingestion され、querySpreadsheetsWithAi は提供されません。
コンテキストの取得
すべてのコンテキストのリストを取得するには、listContexts() メソッドを使用します。このメソッドは、contextId を含む agent context objects の配列を返します。
await squid.ai().knowledgeBase('banking-knowledgebase').listContexts();
特定のコンテキスト項目を取得するには、context ID を渡して getContext() メソッドを使用します。
await squid.ai().knowledgeBase('banking-knowledgebase').getContext('credit-cards');
コンテキストのページ一覧
listContexts() はナレッジベース内のすべてのコンテキストを返します。ナレッジベースに数千件のエントリが含まれるようになると扱いにくくなります。代わりに listContextsPage() を使用してページングし、ID または title で検索してください。
- TypeScript
- Python
const page = await squid
.ai()
.knowledgeBase('banking-knowledgebase')
.listContextsPage({
offset: 0,
limit: 50,
// Truncates each entry's text so a listing stays small.
truncateTextAfter: 500,
// Case-insensitive substring match on context ID and title only, not on the text.
search: 'credit',
});
page = await squid.ai().knowledge_base('banking-knowledgebase').list_contexts_page(
offset=0,
limit=50,
search='credit',
)
すべての option は任意です。response には要求された contexts に加え、offset と limit を無視した totalCount が含まれます。そのため、2 回目の呼び出しなしにページ数を表示できます。
search は context ID と title のみを対象に一致するため、コンテンツによってエントリを検索するには検索を使用してください。truncateTextAfter は TypeScript client でのみ利用できます。
コンテキストの削除
コンテキストエントリを削除するには、deleteContext() メソッドを使用します。
await squid.ai().knowledgeBase('banking-knowledgebase').deleteContext('credit-cards');
指定した context ID のエントリがまだ作成されていない場合、このメソッドはエラーになります。
コンテキストメタデータ
AI ナレッジベースのコンテキストを追加または更新するとき、任意で context metadata を指定できます。metadata は、キーに string、number、または boolean の型を持たせられるオブジェクトです。metadata を追加するとコンテキストに関する追加情報が提供され、それをエージェントとのやり取りで使用できます。次の例では、PDF をコンテキストとして追加し、metadata として 2 つの key/value pairs を指定しています。
const file = new File([contextBlob], 'CreditCardList.pdf', { type: 'application/pdf' });
await squid
.ai()
.knowledgeBase('banking-knowledgebase')
.upsertContext(
{
contextId: 'credit-cards',
type: 'file',
metadata: { company: 'Bank of America', year: 2023 },
},
file
);
その後、metadata でコンテキストをフィルタリングするセクションに示すように、AI エージェントとの chat で metadata を使用できます。
メタデータスキーマの定義
ナレッジベースで metadata schema を宣言すると、metadata は構造化され、自己管理されます。ナレッジベースの upsert 時に metadataFields で field definitions を渡します。
- TypeScript
- Python
await squid
.ai()
.knowledgeBase('banking-knowledgebase')
.upsertKnowledgeBase({
description: 'This Knowledge Base contains information on card data',
embeddingModel: 'text-embedding-3-small',
chatModel: 'gpt-5.5',
metadataFields: [
{ name: 'author', dataType: 'string', required: true, description: 'The full name of the person who wrote the document.' },
{ name: 'publishedAt', dataType: 'date', required: false, description: 'The date the document was published.' },
{ name: 'category', dataType: 'string', required: false, description: 'The document category, for example report, memo, or guide.' },
],
});
await squid.ai().knowledge_base('banking-knowledgebase').upsert(
description='This Knowledge Base contains information on card data',
embedding_model='text-embedding-3-small',
chat_model='gpt-5.5',
metadata_fields=[
{'name': 'author', 'dataType': 'string', 'required': True, 'description': 'The full name of the person who wrote the document.'},
{'name': 'publishedAt', 'dataType': 'date', 'required': False, 'description': 'The date the document was published.'},
{'name': 'category', 'dataType': 'string', 'required': False, 'description': 'The document category, for example report, memo, or guide.'},
],
)
各 field definition には、次の項目があります。
| Field | Type | 必須 | 説明 |
|---|---|---|---|
name | string | はい | 英字、数字、underscore のみ使用できます。text や contextId などの予約済みの名前は拒否されます。 |
dataType | 'string' | 'number' | 'boolean' | 'date' | はい | validation および filtering に使用します。range filters が機能するよう、date 値は epoch milliseconds に正規化されます。 |
required | boolean | はい | field とともにエージェントへ提示されるヒントです。extraction や ingestion には影響しません。必須の値が見つからない場合でも、コンテキストは ingestion されます。 |
description | string | いいえ | ドキュメントからの値の抽出、およびエージェントが metadata filters を構築する際のガイドに使用されます。 |
TypeScript type では 'array' data type も宣言されていますが、まだサポートされておらず、ナレッジベーススキーマの保存時に拒否されます。
スキーマを宣言すると、次の 3 つが有効になります。提供された metadata の validation(誤った型の値がある場合はそのコンテキストのみ拒否)、不足している値の自動 extraction、およびエージェント主導の filteringです。
自動メタデータ抽出
宣言済み fields の値なしでコンテキストを upsert すると、fields が required とマークされているかどうかにかかわらず、Squid が自動的に値を補完します。ファイルアップロードの場合、まず document properties が使用されます。well-known properties に対応する名前(title/docTitle、author/docAuthor、createdAt/docCreatedAt、modifiedAt/docModifiedAt、docType)の fields は、PDF および Office document properties、markdown front matter、HTML metadata から補完されます。残りのすべての fields は、各 field の description に基づき、document text に対する LLM pass で処理されます。指定した値は常に優先され、上書きされることはありません。ただし例外として、空文字列は値なしと見なされ、extraction の対象になります。抽出された fields の名前は、保存済みコンテキストの autoExtractedMetadataFields に記録されます。extraction は best-effort で行われます。値が見つからない場合は、アップロードを失敗させずに値なしのままとなります。
ナレッジベースにすでに保存されている値に基づいて Squid に field descriptions を作成させるには、generateMetadataFieldDescriptions() を呼び出します。このメソッドは生成された descriptions を保存せずに返します。確認してから、upsertKnowledgeBase() を使用してナレッジベースに保存してください。
const { fields } = await squid.ai().knowledgeBase('banking-knowledgebase').generateMetadataFieldDescriptions({ overwriteExisting: false });
メタデータによるナレッジベースコンテキストのフィルタリング
コンテキストに metadata を追加した場合は、contextMetadataFilterForKnowledgeBase chat option を使用して、AI エージェントに特定のコンテキストだけを参照するよう指示できます。filter の条件を満たすコンテキストだけが、client prompt への応答に使用されます。
次の例では、"company" の metadata 値が "Bank of America" と等しいコンテキストだけを含めるようフィルタリングします。
await squid
.ai()
.agent('banking-copilot')
.ask('Which Bank of America credit card is best for students?', {
contextMetadataFilterForKnowledgeBase: {
['banking-knowledgebase']: { company: { $eq: 'Bank of America' } },
},
});
次の metadata filters がサポートされています。
| Filter | 説明 | サポートされる型 |
|---|---|---|
| $eq | 指定値と等しい metadata 値を持つ vectors に一致します | number、string、boolean |
| $ne | 指定値と等しくない metadata 値を持つ vectors に一致します | number、string、boolean |
| $gt | 指定値より大きい metadata 値を持つ vectors に一致します | number |
| $gte | 指定値以上の metadata 値を持つ vectors に一致します | number |
| $lt | 指定値より小さい metadata 値を持つ vectors に一致します | number |
| $lte | 指定値以下の metadata 値を持つ vectors に一致します | number |
| $in | 指定された array 内にある metadata 値を持つ vectors に一致します | string、number |
| $nin | 指定された array 内にない metadata 値を持つ vectors に一致します | string、number |
| $exists | 指定された metadata field を持つ vectors に一致します | boolean |
$underPath による folder へのスコープ設定
$underPath は、ドキュメントの folderPath などの階層的 string field を subtree と照合します。値が operand と完全に一致する場合、または operand の後に / が続く場合に一致します。
await squid
.ai()
.agent('banking-copilot')
.ask('What changed in the 2023 reports?', {
contextMetadataFilterForKnowledgeBase: {
['banking-knowledgebase']: { folderPath: { $underPath: 'reports/2023' } },
},
});
この filter は reports/2023 および reports/2023/q1/deck を許可しますが、兄弟フォルダの reports/2023 drafts は許可しません。/ separator により、raw prefix match では得られない segment boundary が提供されます。そのため、subtree scoping が単に prefix を共有するフォルダへ漏れることはありません。
留意すべき詳細:
- operand の先頭および末尾の slash は無視されるため、
reports/2023/とreports/2023は同じ subtree を指定します。 - 空の operand は、その field を持つすべてのコンテキストに一致します。
- matching は case-sensitive です。
Reportsとreportsは別の folders です。 folderPathは予約済みではなく、通常の metadata key です。POSIX/separators を使用し、先頭または末尾の slash なしで記述してください。upload root にあるファイルには、値なしではなく空文字列を使用します。$underPathはナレッジベースにのみ適用されます。metrics tag filters や matchmaking では受け付けられず、未知の operators として拒否されます。
bare scalar value は $eq の省略形です。したがって、{ company: 'Bank of America' } と { company: { $eq: 'Bank of America' } } は同じ意味です。filters は $and および $or で組み合わせることもできます。
- TypeScript
- Python
await squid
.ai()
.agent('banking-copilot')
.ask('Summarize recent card reports', {
contextMetadataFilterForKnowledgeBase: {
['banking-knowledgebase']: {
$and: [{ category: 'report' }, { publishedAt: { $gt: Date.parse('2026-01-01') } }],
},
},
});
await squid.ai().agent('banking-copilot').ask(
'Summarize recent card reports',
options={
'contextMetadataFilterForKnowledgeBase': {
'banking-knowledgebase': {
# 1767225600000 is 2026-01-01 as epoch milliseconds
'$and': [{'category': 'report'}, {'publishedAt': {'$gt': 1767225600000}}],
},
},
},
)
dataType: 'date' で宣言された fields は epoch milliseconds として保存されます。そのため、range filters には数値(例: Date.parse('2026-01-01'))を渡してください。
エージェント主導のメタデータフィルタリング
ナレッジベースがmetadata schema を宣言している場合、接続されたエージェントは自身で metadata filters を構築できます。ナレッジベース search tool に filter parameter が追加され、モデルは各 field の description と tool description に表示される少数の sample values に基づき、ユーザーの質問に応じてこれを設定します。
contextMetadataFilterForKnowledgeBase で設定した filters は常に適用され、AND を使用して agent の filter と組み合わされます。エージェントは許可された scope を狭めることはできますが、広げることはできません。そのため、app-level filter は security boundary として維持されます。
接続されたナレッジベースで enableMetadataInspection: true を設定すると、さらにエージェントに inspection tool が提供されます。この tool は必要に応じて field の保存済み values を列挙および検索するため、正確な filters の構築に役立ちます。values は最も最近更新された documents から sampling されるため、sample に value が存在しないことは、その value が一度も発生しないことの証明にはなりません。
ソース権限の尊重
connector から index 化されたコンテンツには、通常、それぞれ独自の access rules があります。SharePoint document、Confluence page、Slack conversation は、組織内の一部のユーザーには表示され、他のユーザーには表示されません。ナレッジベースはこれらの rules を尊重できるため、エージェントはチャットしているユーザーに閲覧権限があるコンテンツだけを根拠として回答します。
同じエージェントに同じ質問をする 2 人のユーザーは、それぞれが source system で開ける documents のみから作成された回答を受け取ります。ユーザーがアクセスできないコンテンツが取得されること、モデルに到達すること、citations に表示されることはありません。
これは、質問者ではなく topic または attribute で結果を絞り込むmetadata filteringとは別の機能です。両者は組み合わせて使用でき、permissions は常に適用されます。
ユーザーの authentication は引き続きアプリケーションの責任です。Squid は、アプリケーションが確立した authenticated user identity の permissions を適用します。設定についてはAuthenticationを参照してください。
ナレッジベースの検索
search() メソッドを使用すると、ナレッジベースを直接 query し、一致する chunks を取得できます。
- TypeScript
- Python
const chunks = await squid.ai().knowledgeBase('banking-knowledgebase').search({
prompt: 'Which credit cards have no annual fee?',
});
chunks = await squid.ai().knowledge_base('banking-knowledgebase').search(
'Which credit cards have no annual fee?',
)
Keyword search
semantic (vector) search は、identifiers、error codes、SKUs、file names のような正確な tokens が重要な場面で最も弱くなります。任意の searchMode option で、一致の検出方法を選択できます。各 mode の動作は、ナレッジベースの search backend に依存します。これはナレッジベースの作成時に固定され、getKnowledgeBase() で読み取れる vectorDbType('mongoAtlas' または 'postgres')です。
| Mode | 説明 |
|---|---|
'hybrid' | graph のないナレッジベースでのデフォルトです。'mongoAtlas' では semantic candidates と keyword candidates をネイティブに融合し、'postgres' では semantic search に fallback します。 |
'vector' | semantic similarity のみです。 |
'keyword' | embedding を使用しない lexical search です。'mongoAtlas' では ranked full-text (BM25) matching が使用され、partial match でも最適な結果が返されます。'postgres' では unranked filter となり、whitespace-separated の各 term が chunk 内に literal かつ case-insensitive substring として存在する必要があります。 |
'graph' | entity graph に対する multi-hop retrieval であり、hybrid search と融合されます。graph が有効な 'mongoAtlas' ナレッジベースでのみ利用でき、その場合はデフォルトになります。Knowledge Graph Searchを参照してください。 |
- TypeScript
- Python
const chunks = await squid.ai().knowledgeBase('banking-knowledgebase').search({
prompt: 'ERR_0000_4F2A',
searchMode: 'keyword',
});
chunks = await squid.ai().knowledge_base('banking-knowledgebase').search(
'ERR_0000_4F2A',
options={'searchMode': 'keyword'},
)
接続されたエージェントは自身で search mode を選択します。ナレッジベース search tool は backend がサポートする modes を提供し、質問が exact tokens を対象とする場合、エージェントは keyword search に切り替えます。knowledge graphを持つナレッジベースでは、追加で 'graph' mode が提供され、searchMode を省略した場合のデフォルトになります。
grep による literal scan
上記のすべての search modes は chunks を対象とします。chunks は ingestion がテキストを分割・処理した後に生成されます。一方、grep() は chunking 前の raw extracted text を scan し、各 matching line とその出所ファイルを返します。意味ではなく文字を必要とする場合や、price list で特定の SKU を探す、spreadsheet row の値を探すなど、周囲の行が重要な場合に使用してください。
const result = await squid
.ai()
.knowledgeBase('banking-knowledgebase')
.grep('ERR_0000_4F2A', {
// Scopes the scan to matching contexts before any text is read.
metadataFilter: { category: 'runbooks' },
maxMatches: 100,
});
for (const match of result.matches) {
// e.g. "CreditCardList.pdf, page 4, line 12: ..."
console.log(`${match.fileName}, ${match.part}, line ${match.lineNumber}: ${match.line}`);
}
どちらの option も任意です。
| Option | Type | 説明 |
|---|---|---|
metadataFilter | object | $underPathを含む $and、$or、metadata filteringと同じ grammar を使用して、metadata が一致するコンテキストに scan を限定します。テキストの matching 前に適用されます。 |
maxMatches | number | 返す matches の最大数です。デフォルトは 50、上限は 200 です。 |
各 match には、出所の contextId と fileName、part(extractor が提供する場合は sheet または section title、それ以外は page N)、1-based の lineNumber、一致した line、および一致行と周囲の少数行を含む context が含まれます。
留意すべき動作:
- pattern は常に literal です。 Regular expression metacharacters は escape されるため、punctuation と symbols はそれ自体に一致します。pattern は lines にまたがることができます。
- matching は ASCII letters に対してのみ case-insensitive です。
acmeはACMEを検出しますが、caféはCAFÉを検出しません。ASCII 以外のテキストでは正確な casing で検索してください。
空の matches array は、response に limitation がない場合に限り、文字列が存在しないことを証明します。要求した scope に達しなかった scan では、次のいずれかに limitation が設定されます。空の結果から結論を出す前に確認してください。
| Limitation | 意味 |
|---|---|
timedOut | scan が server-side deadline に達しました。大きなナレッジベースでは通常発生し、pattern が存在するかどうかは示しません。 |
noIndexedText | scope 内に保存済み text がありません。literal search が存在する前に ingestion された contexts は、再 ingestion されるまでここに該当します。 |
filterMatchedNoContexts | metadataFilter が許可した contexts がないため、何も読み取られませんでした。 |
scopeTruncated | metadataFilter が 1 回の scan でカバーできる数を超える contexts を許可したため、一部のみ検索されました。filter を狭めてください。 |
partsCapReached | scan が matching pages または sheets に対する per-call budget を使い切ったため、さらに一致する箇所が存在します。 |
partialCoverage | scope 内の一部 contexts に保存済み text がありません。unscannedContextCount で件数を確認できます。 |
truncatedContent | scope 内の一部 text は ingestion 時に切り詰められ、検索対象になることはありませんでした。truncatedContentFileNames は影響を受けた files の sample を示します。 |
coverageUnknown | scan は成功しましたが、scope 内で保存済み text が占める範囲を判断できませんでした。 |
別の truncated flag は、返されたリストが maxMatches で停止し、さらに matches が存在することだけを意味します。
ナレッジベースに接続されたエージェントは、この scan を grepKnowledgeBase tool として取得します。また実行中にはstatus updatesを broadcast します。grepKnowledgeBase は Searching Knowledge Base Text title を報告し、ranked retrieval の Accessing Knowledge Base title とは区別されます。
grep() は TypeScript client で利用できます。Python または REST の同等機能はありません。
Bulk Ingestion
upsertContexts() は inline で ingestion し、contexts が検索可能になった時点で完了します。これは数十件の documents に適しています。数千件の場合は、AI provider の batch APIs を通じて contexts を処理する durable かつ asynchronous な lane、bulk ingestion を使用してください。
重要な違いは return contract です。bulkUpsertContexts() は ingestion の完了時ではなく、リクエストがstaged された時点で完了します。そのため、返された job を別途追跡します。
CLI による directory の ingestion
最も手早い方法は CLI です。directory を走査し、files を batch 化して upload し、各 job が完了するまで polling します。
squid kb-upload --dir ./docs --knowledgeBase banking-knowledgebase
| Option | 説明 |
|---|---|
--dir | 必須です。再帰的に走査する local directory。 |
--knowledgeBase | 必須です。ingestion 先のナレッジベース。 |
--extensions | Comma-separated allow-list。デフォルトは pdf、docx、txt、md、html、csv、xlsx、xls、xlsm、xlsb、pptx。 |
--batchSize | job ごとに staged する files。デフォルトは 200、最大 1000。 |
--dryRun | upload される files を一覧表示し、server に接続せず終了します。 |
--timeoutMinutes | server-side で job がまだ実行中であることを報告して次へ進むまでの待機時間。デフォルトは 120。 |
--appId、--apiKey、--region、--environmentId は、SQUID_APP_ID、SQUID_API_KEY、SQUID_REGION、SQUID_ENVIRONMENT_ID に fallback します。Ctrl-C を押すと、実行中の job が cancel されます。
コードからコンテキストを staging
bulk ingestion には API key が必要なため、backend code から実行してください。
const { jobId, contextIds, duplicates } = await this.squid
.ai()
.knowledgeBase('banking-knowledgebase')
.bulkUpsertContexts(contexts, files);
contextIds は、渡した contexts と index-aligned です。content duplicate として拒否された context も slot を占有するため、実際に staged されたものを確認するには context ID で duplicates を cross-reference してください。duplicate とは、ナレッジベースがすでに保持している content、または同じ call のより前の context が追加した content です。
duplicates は text contexts と、call に bytes を渡した files を対象とします。これらは staging 時に利用可能であるためです。stagedObjectKey によって staged された file は例外です。その bytes は deferred extraction pass によって初めて読み取られるため、duplicate は後で job の per-file statuses に errorCode: 'DUPLICATE_CONTENT' を伴う failed file として現れます。ナレッジベースにはすでに content があるため、この code は failure ではなく skip として扱ってください。通常の failures には errorCode がありません。
Job の追跡
const kb = squid.ai().knowledgeBase('banking-knowledgebase');
// Poll for the job's current state.
const status = await kb.getBulkIngestionJob(jobId);
console.log(status.state, status.counts);
// Or subscribe to server-side updates.
kb.observeBulkIngestionJob(jobId).subscribe((update) => {
console.log(update.state, update.counts);
});
// Already-finalized contexts are kept when a job is cancelled.
await kb.cancelBulkIngestionJob(jobId);
observeBulkIngestionJob() は、job が completed、failed、または cancelled に到達すると complete します。terminal failed または cancelled state は error ではなく通常の emitted value として届くため、next callback で処理してください。observable が error になるのは transport failure の場合だけです。
計画時に考慮すべき詳細:
- observable は cold であるため、各 subscription は独自の server-side subscription を登録します。複数の consumers が 1 つの job を監視する場合は、たとえば RxJS
share()を使用して共有してください。 - application または knowledge base が job の実行中に削除された場合、job record は final update なしに purge され、observable は complete しません。この可能性がある場合は、RxJS
timeout()で制限してください。
大規模なファイルセットのアップロード
files を bulkUpsertContexts() に直接渡すと、Squid を経由して送信されます。Squid は request を memory に buffer するため、1 回の call は 最大 50 files、合計 256 MB に制限されます。これを超える場合は、presigned URLs を作成して storage に直接 upload してください。この方法にはどちらの上限もありません。
const kb = this.squid.ai().knowledgeBase('banking-knowledgebase');
// At most 500 file names per call.
const { uploads } = await kb.createBulkUploadUrls(['statement-2026-01.pdf', 'statement-2026-02.pdf']);
for (const upload of uploads) {
await fetch(upload.uploadUrl, {
method: 'PUT',
body: fileBytesFor(upload.fileName),
// Required headers are empty on S3, but Azure Blob rejects the PUT without them.
headers: upload.requiredHeaders,
});
}
// Reference the staged objects instead of sending bytes through Squid.
const staged = uploads.map(upload => ({
type: 'file' as const,
contextId: upload.fileName,
stagedObjectKey: upload.stagedObjectKey,
}));
await kb.bulkUpsertContexts(staged);
presigned URLs は作成後すぐに expire するため、すべてを事前に作成するのではなく、各 wave を速やかに upload してください。
ベストプラクティス
- 大きな documents は topic ごとに焦点を絞ったナレッジベースへ分割してください。これにより、エージェントは適切なコンテキストを選ぶためのより良い signal を得られます。
- コンテキストに metadata を追加し、query 時の filtering を有効にして、responses のノイズを減らしてください。