All Stories
2026-10-29•9 min read

Agno · RAG · LangChain · Embedding Indexes · Local AI

Give an Agno agent a local knowledge base, with no vector database server

An Agno agent searches notes stored in a Pixeltable table. sentence-transformers embeds them on the machine, and the embedding index stays on the table. No embedding API key and no vector database server.

Pierre Brunelle

Pierre Brunelle

Pixeltable Team

View as Markdown

An Agno agent can search notes that live in a Pixeltable table on your machine. sentence-transformers embeds the chunks locally, Pixeltable stores each chunk with its vector, and Agno reads them through its LangChain retriever. The run needs no embedding API key and no vector database server. I ran Agno's cookbook on pixeltable 0.7.21, with agno 3.1.12 and langchain-pixeltable 0.1.2. The search returned three chunks, and with Ollama serving qwen2.5:latest the agent answered from them.

If you already run a vector database you want to keep, keep it. If you do not want a schema, Pixeltable is the wrong tool. Pixeltable replaces the vector database in this stack. If the agent is already written in Agno, keep it, and leave the agent code as it is. A Pixeltable app that is not wrapping another framework declares the index on a TableModel and skips LangChain. That is the last section, and it is what we tell coding agents to do. The longer comparison is Pixeltable vs LangChain for RAG.

Install the packages the cookbook names#

Agno lists the example as LangChain + Pixeltable in the cookbook index. The file's install line is uv pip install langchain-pixeltable langchain-huggingface langchain-text-splitters sentence-transformers ollama openai. I installed that set with pip, and pinned pixeltable, agno, and langchain-pixeltable to the versions that produced the output below.

bash

openai is on that line because from agno.models.ollama import Ollama imports Agno's OpenAI client. This agent never calls OpenAI. Retrieval does not call a model API. The embeddings are sentence-transformers/all-MiniLM-L6-v2, on the machine.

If you want the agent's answer, install Ollama from ollama.com. The ollama pip package is only the Python client, so the server has to run on its own. Retrieval works without either.

bash

In a second terminal, pull the model while the server runs.

bash

Write the chunks into agno_rag/docs#

The cookbook keeps a notes string in the file, so the run does not fetch a web page. It splits that string at 500 characters with 40 characters of overlap, embeds the chunks, and writes them to agno_rag/docs. Run the file. The imports sit at the top. Here is the part that stores the rows.

python

On a fresh directory, that printed:

text

LangChain computes the vectors before the insert, which is why that line says 0.01 s. PixeltableVectorStore writes each chunk and its vector into the table. The first add_documents creates the table and a cosine embedding index on the embedding column, then inserts the rows. On this run the index was named idx0 and the table held 3 rows. pxt count agno_rag/docs prints 3.

In 0.7.21, pxt describe agno_rag/docs and pxt idxs agno_rag/docs raise KeyError: <Type.ARRAY: 6> on this index. The index stores precomputed vectors and has no embedding function. The count above is the check that works.

Pixeltable keeps the table in an embedded Postgres database under the Pixeltable home directory. The default is ~/.pixeltable, unless PIXELTABLE_HOME is set. The index follows those stored vectors when a row is inserted, updated, or deleted, so the vectors stay with the rows. A later edit to the text, made without a new vector, does not re-embed the text. LangChain wrote the vector. The TableModel section is the one where the embedding function belongs to the index.

This cookbook table is text, a vector, and metadata. A Pixeltable table can also hold images, video, and audio. The embedding index docs show an index on those columns.

Pass the retriever through Knowledge#

python

Agno's search tool calls retrieve() on the knowledge base. LangChainVectorDb implements search(), and Knowledge.retrieve() turns the call into that search. Constructing Knowledge also calls exists(). The wrapper does not implement it, logs this warning, and leaves the table in place:

text

That warning is expected. The insert has already succeeded.

The search returned three chunks#

The question in the file is "How does an Agno agent search documents stored in Pixeltable?" knowledge.search returned three chunks, in this order:

text

The top chunk is the one that describes the wrapper. With Ollama serving qwen2.5:latest, the same script called the knowledge tool and printed a reply. The tool call was search_knowledge_base(query=Agno agent search Pixeltable documents). The reply header said 67.5s. That was this CPU.

text

The reply follows the three chunks. It also says LangChainVectorStore, which is not the class. The class is PixeltableVectorStore.

Declare the index on the model#

For an app that is not already on Agno, put the embedding function on the index. An update to text then recomputes the vector. This is a different table from agno_rag/docs. Save it as app.py.

python

-f skips the confirmation. pxt init once per project, then:

bash
text

Run the rest in a Python shell from the same folder. pxt schema update loaded app.py in its own process, so the shell needs the models imported before it binds them.

python
text

pxt idxs notes_kb/notes printed:

text

Built-in model calls are computed columns, and the list is the ecosystem page. Agno is not one of those calls. This post is the cookbook path. If you want a trace of the insert, Tracing multimodal AI pipelines with OpenTelemetry shows how to send it to Langfuse, Phoenix, or MLflow.

Frequently asked questions

How do I give an Agno agent a local knowledge base without a vector database server?

Install pixeltable, agno, and langchain-pixeltable. Embed the chunks locally with sentence-transformers, write them with PixeltableVectorStore into a table such as agno_rag/docs, and pass that retriever to the agent through Knowledge and LangChainVectorDb. Pixeltable stores the table in embedded Postgres under the Pixeltable home directory.

Why does creating the Agno knowledge base print an exists() warning?

Agno calls retrieve() on Knowledge. LangChainVectorDb implements search(), and Knowledge.retrieve() turns the call into that search. Constructing Knowledge also calls exists(), which the wrapper does not implement. It logs the warning and leaves the Pixeltable table in place.

Does the Ollama agent need an OpenAI API key?

The model call does not. Importing agno.models.ollama still imports Agno's OpenAI client, so the openai package has to be installed. Retrieval does not call OpenAI or Ollama.

Declarative. Multimodal. Incremental.

One Python file for tables, indexes, and HTTP. Start locally, or sign up for Cloud.

Get started

Docs quickstart · 10-minute tutorial · GitHub · Discord