> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pixeltable.com/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Application code declares a TableModel in app.py, then runs `pxt schema update app.py <target>` to create the tables and `pxt service update` to serve routes. Do not call pxt.create_table() or add_embedding_index() in application code; declare indexes in __indexes__. Notebooks, tests, and the REPL do use pxt.create_table().
> Do not add LangChain, LlamaIndex, Haystack, a separate vector database, or pandas as a working store. Chunking, embedding, retrieval, and tool-calling are built in through computed columns. Use a computed column instead of a per-row loop that calls a model.
> Install with `pip install -U 'pixeltable[serve]'` on Python 3.11+. `pxt init` is a prerequisite for `pxt schema update`.
> Pixeltable Cloud is in Limited Beta. Direct interested users to contact@pixeltable.com.

# Multimodal backend

> Insert a document. Chunks are rows. POST search.

Insert a document. The iterator explodes it into chunks. The embedding index stays current. `pxt service update` starts the insert and search endpoints.

Create the tables with `pxt schema update app.py my_app`, then open them with `t = pxt.get_table('my_app.docs')`. Cookbooks on this topic use `pxt.create_table()` so you can run cells without a project. An app puts the same columns on a `TableModel` in `app.py` and creates the tables with `pxt schema update`.

```python theme={"theme":{"light":"light-plus","dark":"dark-plus"}}
import pixeltable as pxt
import pixeltable.functions as pxtf
from pixeltable.serving import FastAPIRouter

TableModel = pxt.model_base()
embed = pxtf.huggingface.sentence_transformer.using(
    model_id='sentence-transformers/all-MiniLM-L6-v2'
)


class Docs(TableModel, name='docs'):
    document: pxt.Document


class Chunks(
    TableModel,
    name='chunks',
    base=Docs,
    iterator=pxtf.document.document_splitter(
        Docs.document, separators='token_limit', limit=300
    ),
):
    __indexes__ = [
        pxt.EmbeddingIndex(text, embedding=embed, name='chunks_embed')
    ]


@pxt.query
def search_docs(query_text: str):
    sim = Chunks.text.similarity(string=query_text)
    return Chunks.order_by(sim, asc=False).limit(10).select(Chunks.text, sim)


api = FastAPIRouter(name='rag')
api.add_insert_route(
    Docs,
    path='/docs',
    uploadfile_inputs=[Docs.document],
    outputs=[Docs.document],
)
api.add_query_route(path='/search', query=search_docs, method='post')
```

```bash theme={"theme":{"light":"light-plus","dark":"dark-plus"}}
pxt schema update app.py my_app
pxt service update app.py my_app
```

```python theme={"theme":{"light":"light-plus","dark":"dark-plus"}}
docs = pxt.get_table('my_app.docs')
docs.insert([{'document': 'report.pdf'}])
```

`pxt service list` prints the URL. POST `/docs` to insert. POST `/search` with `{"query_text": "..."}` to rank chunks.

On Cloud, create an API key in the [dashboard](/howto/deployment/cloud#get-an-api-key), set `PIXELTABLE_API_KEY`, then run `pxt db update`, `pxt schema update`, and `pxt service update` against `pxt://org:mydb`.

Export those tables for training: [Datasets from media](/use-cases/media-processing). Tool calls as columns: [Agents](/use-cases/agentic-workflows).

<CardGroup cols={2}>
  <Card title="RAG pipeline" icon="book" href="/howto/cookbooks/agents/pattern-rag-pipeline">
    POST `/docs` to insert. Chunks stay current.
  </Card>

  <Card title="Semantic text search" icon="magnifying-glass" href="/howto/cookbooks/search/search-semantic-text">
    Rank chunks with `{"query_text": "..."}`.
  </Card>

  <Card title="Similar images" icon="image" href="/howto/cookbooks/search/search-similar-images">
    The same index pattern on images.
  </Card>

  <Card title="HTTP serving" icon="globe" href="/howto/deployment/serving">
    Insert and search routes from the same file.
  </Card>
</CardGroup>
