Knowledge Bases
Store searchable context for your AI agents, and manage it with metadata schemas, automatic extraction, and query-time filtering.
Why Use a Knowledge Base
A knowledge base stores the context your AI agents pull from when answering questions, and is the same as the Knowledge Base ability in the Agent Studio. Adding context allows an agent to provide relevant answers on specific topics that may not be part of the underlying AI model.
The following are simple code examples, though the context you add can be much more complex. Some good examples of context include resources like code documentation, product manuals, business operations (e.g., store hours) and user-specific data. You can mix and match context types to create a robust knowledge base for your AI agent, ensuring that it can provide any information your users will need.
Creating a Knowledge Base
To add or update agent context, you must first create and connect a knowledge base.
First, create the new knowledge base with an embedding model that we provide out of the box:
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: [],
});
Or, you can use an integration-based embedding model by passing an object with the connector ID, model name, and dimensions. See the OpenAI Compatible Embedding connector for setup instructions.
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: [],
});
Upserting Context
To add context to the knowledge base, use the upsertContext() method, passing the context and its type.
The upsertContext() method accepts a context ID. Providing a context ID allows you to more easily access context later for when you want to make changes.
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',
});
Alternatively, use upsertContexts() to upsert an array of contexts.
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',
},
]);
Connecting to an Agent
A knowledge base only affects an agent's answers once it is connected to that agent. To connect a knowledge base and configure how the agent uses it, see Connect a Knowledge Base to an Agent.
Context Types
Two types of contexts are supported: text and file.
Text context is created with a string that contains the 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 is created by providing a File object as a second parameter to the upsertContext() method. The file is then uploaded to Squid and the context is created from the file contents.
const file = new File([contextBlob], 'CreditCardList.pdf', { type: 'application/pdf' });
await squid.ai().knowledgeBase('banking-knowledgebase').upsertContext(
{
type: 'file',
contextId: 'credit-cards',
},
file
);
Your context can be as long as you like; however since there are character limits to LLM prompts, only a portion of your context may actually be included alongside the user's inquiry. When constructing a prompt, Squid decides which portions of the supplied context are most relevant to the user's question.
Getting Context
To get a list of all contexts, use the listContexts() method. This method returns an array of agent context objects, which includes the contextId:
await squid.ai().knowledgeBase('banking-knowledgebase').listContexts();
To get a specific context item, use the getContext() method, passing the context ID:
await squid.ai().knowledgeBase('banking-knowledgebase').getContext('credit-cards');
Deleting Context
To delete a context entry, use the deleteContext() method:
await squid.ai().knowledgeBase('banking-knowledgebase').deleteContext('credit-cards');
This method results in an error if an entry has not yet been created for the context ID provided.
Context Metadata
When adding or updating the context of an AI knowledge base, you can optionally provide context metadata. Metadata is an object where keys can have a type of string, number, or boolean. Adding metadata provides additional information about the context that can then be used when interacting with your agent. The following example shows adding a PDF as context and providing two key/value pairs as metadata:
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
);
You can then use metadata when chatting with your AI agent, as shown in the filtering context with metadata section.
Defining a metadata schema
Declaring a metadata schema on the knowledge base makes metadata structured and self-maintaining. Pass field definitions in metadataFields when upserting the knowledge base:
- 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.'},
],
)
Each field definition has:
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Letters, numbers, and underscores only. Reserved names such as text and contextId are rejected. |
dataType | 'string' | 'number' | 'boolean' | 'date' | Yes | Used for validation and filtering. date values are normalized to epoch milliseconds so range filters work. |
required | boolean | Yes | A hint surfaced to the agent alongside the field; it does not affect extraction or ingestion — a context still ingests even when a required value cannot be found. |
description | string | No | Used to extract the value from documents and to guide agents when they construct metadata filters. |
The TypeScript type also declares an 'array' data type; it is not yet supported and is rejected when the knowledge base schema is saved.
Declaring a schema enables three things: validation of supplied metadata (a value with the wrong type rejects only that context), automatic extraction of missing values, and agent-driven filtering.
Automatic metadata extraction
When a context is upserted without values for declared fields, Squid fills them in automatically, whether or not the fields are marked required. For file uploads, document properties are used first: fields named after well-known properties (title/docTitle, author/docAuthor, createdAt/docCreatedAt, modifiedAt/docModifiedAt, and docType) are filled from PDF and Office document properties, markdown front matter, and HTML metadata. An LLM pass over the document text handles all remaining fields, guided by each field's description. Values you supply always win and are never overwritten, with one exception: an empty string counts as no value and stays eligible for extraction. The names of extracted fields are recorded on the stored context in autoExtractedMetadataFields, and extraction is best-effort: a value that cannot be found stays absent without failing the upload.
To have Squid write field descriptions for you based on the values already stored in the knowledge base, call generateMetadataFieldDescriptions(). It returns the generated descriptions without saving them; review and save them onto the knowledge base with upsertKnowledgeBase():
const { fields } = await squid.ai().knowledgeBase('banking-knowledgebase').generateMetadataFieldDescriptions({ overwriteExisting: false });
Filtering Knowledge Base Context with Metadata
When you have added metadata to your context, you can use the contextMetadataFilterForKnowledgeBase chat option to instruct the AI agent to only consult specific contexts. Only contexts that meet the filter requirement will be used to respond to the client prompt.
The following example filters contexts to only include those with a metadata value of "company" that is equal to "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' } },
},
});
The following metadata filters are supported:
| Filter | Description | Supported types |
|---|---|---|
| $eq | Matches vectors with metadata values that are equal to a specified value | number, string, boolean |
| $ne | Matches vectors with metadata values that are not equal to a specified value | number, string, boolean |
| $gt | Matches vectors with metadata values that are greater than a specified value | number |
| $gte | Matches vectors with metadata values that are greater than or equal to a specified value | number |
| $lt | Matches vectors with metadata values that are less than a specified value | number |
| $lte | Matches vectors with metadata values that are less than or equal to a specified value | number |
| $in | Matches vectors with metadata values that are in a specified array | string, number |
| $nin | Matches vectors with metadata values that are not in a specified array | string, number |
| $exists | Matches vectors with the specified metadata field | boolean |
A bare scalar value is shorthand for $eq, so { company: 'Bank of America' } and { company: { $eq: 'Bank of America' } } are equivalent. Filters can also be combined with $and 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}}],
},
},
},
)
Fields declared with dataType: 'date' are stored as epoch milliseconds, so pass numeric values (for example Date.parse('2026-01-01')) in range filters.
Agent-driven metadata filtering
When a knowledge base declares a metadata schema, connected agents can construct metadata filters on their own. The knowledge base search tool gains a filter parameter, and the model fills it in based on the user's question, guided by each field's description and a small set of sample values shown in the tool description.
Filters you set with contextMetadataFilterForKnowledgeBase always apply and are combined with the agent's filter using AND. The agent can narrow the allowed scope but can never widen it, so the app-level filter remains a security boundary.
Setting enableMetadataInspection: true on the connected knowledge base additionally gives the agent an inspection tool that enumerates and searches a field's stored values on demand, which helps it construct accurate filters. Values are sampled from the most recently updated documents, so the absence of a value in the sample does not prove it never occurs.
Best Practices
- Split large documents into focused knowledge bases by topic. This gives the agent better signal for choosing the right context.
- Add metadata to your contexts to enable filtering at query time, reducing noise in responses.