Knowledge
On this page
Master switch. The Knowledge section (an agent’s Behaviour group) is gated by the per-agent
knowledgeEnabledflag, the Document retrieval switch at the top of this tab. The default is off, as it is for memory. When the flag is off, thesearchKnowledge,getKnowledgeandwriteKnowledgetools are filtered out at turn time by category: theirinstance_toolsrows survive, so turning the flag back on restores the previous tool set exactly, but the assistant cannot reach the knowledge base while it is off.
The Knowledge tab holds files the assistant can search and retrieve at runtime. Knowledge differs from memory in two ways:
| Aspect | Memory | Knowledge |
|---|---|---|
| Source | Extracted from conversations. | Authored by operators. |
| Granularity | Short factual statements. | Whole documents (Markdown, text, JSON). |
| Lifecycle | Auto-extracted, occasionally curated. | Curated and versioned by hand. |
| Tools | saveMemory, searchMemory. | searchKnowledge, getKnowledge, writeKnowledge. |
Tool access
Managed services. The access level is available with Polyant managed services.
With retrieval on, Tool access sits under the switch and decides how much of the knowledge base tool code may use: the agent’s own knowledge tools and every plugin tool of the turn alike. The levels are nested.
| Level | What tools may do |
|---|---|
| Read only (default for a new agent) | Search and read the documents, without changing them. |
| Read and write | Also create and update the documents they wrote themselves. Documents uploaded from this tab stay untouched. |
| Full management | Also delete and re-index any document, including the ones uploaded here. |
writeKnowledge goes through the same level. At Read only it refuses to write. At Read and write, writing or appending to a document the agent did not write (one uploaded from this tab, for example) answers DOCUMENT_NOT_OWNED. An agent that maintains such a document needs Full management, or the document re-created by the agent itself. The switch and the level are saved together with the page’s Save.
Adding files
Two routes add a document, and they accept different things.
Managed services. File upload, and with it the reading of PDF and Word files, is available with Polyant managed services. The open-source build adds documents as text only.
Upload file reads the document for you and is where PDFs and Word files go:
| Format | Extension |
|---|---|
| PDF with a text layer | .pdf |
| Word | .docx |
| Markdown | .md, .markdown |
| Plain text | .txt, .text |
An unsupported extension is refused before anything is stored, so it never appears as a document that failed to process. A PDF with no text layer is a scan and is refused too, with a message that says so - ingesting it would produce a document that indexes to zero chunks and then fails silently at answer time, weeks later. OCR, images, spreadsheets and table extraction are deliberately out of scope.
PDF and Word files are read in a separate worker with its own memory limit (512 MB) and a 60-second deadline, at most two at a time across the engine, so a file that exhausts the parser fails its own upload instead of the engine. A Word file that declares more than 64 MB uncompressed, and a PDF over 2,000 pages, are refused before extraction starts.
Paste text (the JSON route, labelled Upload in the open-source build) takes text you already have, with a filename, and still accepts .html alongside Markdown and plain text; anything else it is given is stored as text/plain.
Either way the text is split into overlapping chunks, embedded with the agent’s configured embedder, and stored in PostgreSQL across knowledge_documents (raw content + metadata) and knowledge_chunks (chunk text + vector column + tsvector). Filenames must be unique within an agent.
The embedder is chosen per instance in the Model section, under Embeddings, from the embedders this server serves: OpenAI text-embedding-3-small and Amazon Titan Text Embeddings v2 in every build, plus TensorX and Regolo.ai (Qwen3-Embedding-8B, 1024 dimensions) with managed services. Each row stores the vector in the column matching that embedder’s dimension (1024 or 1536). An embedder name the server does not know fails instead of falling back to OpenAI, and an agent import naming one is refused. See Model → Embeddings.
Switching the embedder deletes the knowledge base. Vectors are not converted between providers: changing the embedder drops every document and chunk for the instance, raw content included. Re-upload afterwards.
Editing files
Click a file to open the inline editor. Save commits the change. Edits are not versioned - keep external version control if you need history.
Shared libraries
Managed services.
A document no longer has to belong to one agent. It belongs to exactly one of three owners - an agent, a workspace, or an organization - and the database enforces the “exactly one” rather than trusting every query to narrow correctly.
An organization’s library is the widest: filled once, and then lent outward in two steps.
- The organization assigns the document to a workspace. Without this, no agent in that workspace can reach it.
- An agent in that workspace switches the document on. This is per agent, so being reachable is not the same as being consulted.
A workspace’s own library skips the first step - it is already inside the workspace - and still needs the per-agent switch. It is listed only to callers who may reach that workspace. Both halves fail closed: an agent that cannot resolve its own tenancy searches only its own documents and says nothing about it, which is the safe answer.
A shared library is embedded once, with the organization’s own embedder, and vectors are not portable across providers or dimensions. An agent whose embedder differs from the organization’s therefore reads none of those documents. That failure is reported rather than hidden: the panel lists the documents and marks them unusable, because “why does my agent not see the documents I can see” is the worst question to answer from a distance. The organization’s embedder defaults to what a brand-new agent gets (openai), so an installation that never touches the setting is consistent by default. A shared library embeds only on a provider the organization is admitted to.
The library embedder
The provider and dimension that the organization’s library and every workspace library are indexed with are set on Settings → Organization → Knowledge (/organizations/{org}/settings/organization/knowledge, where the organization’s library is administered too), in the Embedder card, or through GET and PUT /api/organizations/{orgSlug}/knowledge/embedder with a body of provider and dimensions. This is a different setting from an agent’s own embedder, which stays on the agent.
- Who may see and change it. Reading needs
org.secret:readand changing it needsorg.secret:write, the keys that govern the organization’s provider connections: the embedder decides which provider receives every shared document and which organization connection pays for it. Filling a library (org.knowledge:write) does not include this. A caller who may only read sees the card with its selects disabled; withoutorg.secret:readthe card is not shown. - What it may be set to. Only an embedder this deployment serves, at a dimension that embedder can emit; anything else is refused with
400, naming what is available. - When it can change. Only while no shared document exists in the organization or any of its workspaces. Otherwise the change is refused with
409, because those documents’ vectors belong to the current embedder, and the card shows it locked with the number of documents. Remove them from the organization’s library and from every workspace’s library first; nothing re-indexes them for you. - Credentials. Shared documents are embedded with the provider connection bound to the organization’s
library_embeddingrole, which the card binds with a picker of the organization’s connections that can embed. It must be for the embedder’s provider. The answer carriesreadyand, when not ready, theproblemsentence of the same resolution an upload performs: no connection bound, a connection for another provider, a provider not admitted, or a Bedrock connection without a key in an organization not granted the deployment’s AWS identity. Saving the embedder does not require a connection, but uploads are refused until it can index. - Workspaces. A workspace’s library, and the shared half of a search by an agent in that workspace, use the library connection only where it is lent to that workspace. Elsewhere an upload is refused with that reason, the workspace’s knowledge page says why, and the shared half of a search is skipped and reported on the agent’s Status section.
Each change is written to the management audit trail as knowledge.library_embedder_update, with the old and new provider and dimension. Writing the pair it already has records nothing.
Four permissions govern this. The key that lifts a ceiling is organization-tier on purpose - the people subject to an allow-list must not be able to lift it - while filling a workspace’s own library is workspace-tier, so a team can carry its own material without going up a level:
| Permission | What it allows | Held by |
|---|---|---|
org.knowledge:read | listing a library’s documents | every system role |
org.knowledge:write | filling the organization’s library | Owner, Admin |
workspace.knowledge:manage | deciding which workspaces may draw on a shared document | Owner, Admin |
workspace.knowledge:write | filling a workspace’s own library | Owner, Admin, per workspace |
Reading is a separate key from org:read because org:read is the membership floor that every role holds, and a library lists what an organization has written down.
Nothing changes on upgrade. Every document that existed stays agent-owned and is selected by exactly the queries that selected it before; the shared libraries start empty and a workspace starts with no assignment.
How the assistant uses knowledge
Knowledge is exposed to the assistant through three tools, all gated by the per-instance knowledgeEnabled flag (see the Document retrieval switch above):
| Tool | Purpose |
|---|---|
searchKnowledge | Semantic + keyword hybrid search over chunks. Returns ranked snippets with scores. |
getKnowledge | Fetch the full raw content of one document by filename. |
writeKnowledge | Create, overwrite or append a document programmatically (audited). With managed services, only within the tool access level. |
When knowledgeEnabled is on, the three tools are registered as normal tools alongside everything else; there is no special wiring in the Skills prompt section. The LLM picks searchKnowledge based on the tool’s own description (services, procedures, costs, FAQs, anything that may live in documents) and decides per turn whether the user’s question warrants a lookup - there is no automatic injection of knowledge into the prompt.
The typical flow:
- The user asks something that sounds document-shaped.
- The model emits a
searchKnowledgecall with a query (it may rephrase if results are poor). - The tool returns the top-N matching chunks (
content,score,source,chunkIndex) - already enough to ground most answers. - Only if the model needs the broader context of a specific file does it follow up with
getKnowledge({ filename }).
Retrieval - hybrid search with RRF
searchKnowledge is not keyword-only. It runs two backends in parallel and fuses them with Reciprocal Rank Fusion (k=60):
- pgvector cosine similarity against the chunk embeddings.
- PostgreSQL full-text search on the same chunks (
tsvectorwithsimpleconfig, no language-specific stopwords, so it works across languages).
The same pattern is used by the memory layer. The vector branch needs the credentials of the instance’s configured embedder - without them the search degrades to FTS-only rather than failing outright.
Limits
-
Per-file size - 20 MB for an uploaded file, and 5 MB for the text recovered from it. The second is the one that binds on a text document; the first exists because a PDF carries far more bytes than the words in it. The JSON route caps the text it is given at 5 MB. Beyond either, the upload is refused.
-
Files per agent - an entitlement of the organization, not of the deployment. An organization that sets its own cap uses that, higher or lower, without a redeploy; one that sets none gets 500. Beyond the cap, new uploads return
400until older docs are deleted. With managed services the same number also caps the organization’s shared documents as a whole, counted apart from each agent’s own.The cap is the column
organizations.knowledge_max_docs_per_agent. This release has no console field for it, so a different value is set by SQL. The default of 500 is a constant, never a ceiling, and it is also the answer when the agent cannot be resolved - a cap fails closed to a number, never to “no limit”. -
Indexing latency - ingestion is asynchronous (chunk → embed → upsert). A document moves
uploading→processing→ready, orerror; there is nopending. Until it reachesreadyits chunks are not searchable. A document stuck inprocessing, or one that reportsreadywith no chunks indexed, is reported on the agent’s Status section. -
Versioning - none. Edits overwrite the chunks for that filename; keep external version control if you need history.