Pixeltable + LangGraph
LangChain and LangGraph run the agent loop. Pixeltable is the data plane: media, computed columns, embedding indexes, and HTTP in one Python file. They are not the same job. Use both, or drop the extra store if Pixeltable already holds the chunks.
pip install 'pixeltable[serve]'Different layers
| Side | Pixeltable | LangChain |
|---|---|---|
| At a glance |
|
|
Data plane vs agent runtime
Pixeltable stores multimodal rows and keeps indexes in sync. LangGraph owns graphs, tools, and tracing. Pixeltable does not replace LangSmith. That split is agent graph vs table — the AI automation workflow category.
| Feature | Pixeltable | LangChain |
|---|---|---|
| What it is | Multimodal tables + incremental compute + serving | LLM application SDK; LangGraph is the agent runtime |
| Where the bytes live | Native Document, Image, Video, Audio columns | You bring a store: Postgres, Chroma, S3, a checkpointer |
| Chunking and embeddings | document_splitter view + EmbeddingIndex; insert keeps them current | Loaders and splitters you re-run; vectors upserted elsewhere |
| Agent graphs | Tool-calling columns and @pxt.udf tools; no graph runtime | LangGraph: StateGraph, ToolNode, human-in-the-loop, checkpointers |
| Tracing and eval | Per-cell errormsg / errortype; no LangSmith | LangSmith, callbacks, and the tracing ecosystem |
| Multimodal RAG | One schema for PDFs and images; CLIP and text indexes together | Possible; separate loaders, embedders, and stores per modality |
| Team already using it | Python tables; agents learn TableModel from the skill | Default generated stack; LangGraph Platform if you already pay for it |
RAG that stays in sync
Pixeltable: the schema is chunking, the index, and a tool-calling assistant. LangGraph: you still own the store. Apply Pixeltable with pxt schema update app.py app.
Pixeltable
import pixeltable as pxtfrom pixeltable.functions.document import document_splitterfrom pixeltable.functions.huggingface import sentence_transformer, clipfrom pixeltable.functions.openai import chat_completions, invoke_toolsTableModel = pxt.model_base()embed = sentence_transformer.using(model_id='sentence-transformers/all-MiniLM-L6-v2')visual = clip.using(model_id='openai/clip-vit-base-patch32')class Docs(TableModel, name='docs'):document: pxt.Documentimage: pxt.Imagetitle: pxt.String__indexes__ = [pxt.EmbeddingIndex(image, embedding=visual)]class Chunks(TableModel,name='chunks',base=Docs,iterator=document_splitter(Docs.document, separators='sentence', limit=512),):__indexes__ = [pxt.EmbeddingIndex(text, embedding=embed)]@pxt.udfdef search_docs(question: str) -> str:chunks = pxt.get_table('app.chunks')sim = chunks.text.similarity(string=question)rows = (chunks.order_by(sim, asc=False).limit(5).select(chunks.text).collect())return '\n'.join(r['text'] for r in rows)tools = pxt.tools(search_docs)class Assistant(TableModel, name='assistant'):message: pxt.Stringresponse = chat_completions(messages=[{'role': 'user', 'content': message}],model='gpt-4o-mini',tools=tools,)tool_output = invoke_tools(tools, response)# pxt schema update app.py app
LangChain
from langchain_community.document_loaders import PyPDFLoaderfrom langchain_text_splitters import RecursiveCharacterTextSplitterfrom langchain_openai import ChatOpenAI, OpenAIEmbeddingsfrom langchain_community.vectorstores import Chromafrom langchain_core.tools import toolfrom langgraph.prebuilt import create_react_agentdocs = PyPDFLoader('handbook.pdf').load()chunks = RecursiveCharacterTextSplitter(chunk_size=512, chunk_overlap=50).split_documents(docs)store = Chroma.from_documents(chunks, OpenAIEmbeddings(model='text-embedding-3-small'))@tooldef search_handbook(question: str) -> str:hits = store.similarity_search(question, k=5)return '\n'.join(d.page_content for d in hits)agent = create_react_agent(ChatOpenAI(model='gpt-4o-mini'), tools=[search_handbook])agent.invoke({'messages': [('user', 'What is the refund policy?')]})# Images, versioning, and re-chunking on insert are still yours.
When each belongs
Use Pixeltable when
- The data layer is the product
PDFs, images, video, embeddings, and retrieval that must stay current when a row is inserted. One schema, not a loader plus a vector store plus a re-index job.
- You want retrieval without a second database
EmbeddingIndex on the column. similarity(string=query) then order_by. LangGraph can call that as a tool.
Use LangChain when
- The agent loop is the product
Multi-agent graphs, interrupts, checkpointers, and LangSmith traces. Pixeltable does not ship that runtime.
- The team already writes LangGraph
Keep the graph. Point tools at Pixeltable tables instead of standing up Chroma for every prototype.
Making the right choice
Complementary, not a wipe
- Pixeltable replaces the RAG data path: chunking, embeddings, persistence, incremental insert.
- LangGraph still fits when the application is a graph. Call Pixeltable from a tool.
- LlamaIndex is the same split: index/query engine vs tables. No separate vs page.
- Category page (agent graph vs table): https://pixeltable.com/blog/ai-automation-workflow
- Longer write-up (notebook-era snippets): https://pixeltable.com/blog/pixeltable-vs-langchain-rag-comparison
Frequently asked questions
One file for the data plane.
Declare tables, indexes, and retrieval. Apply with pxt schema update. LangGraph can still run the agent loop.