# Publish your docs as agent knowledge with page storage

> Agno's Knowledge can now sync a documentation site from its llms.txt. Page storage publishes each page's text and vectors together, so a failed refresh keeps the last good version.

- Published: 2026-09-08
- Author: Ashpreet Bedi
- Categories: Changelog
- Canonical: https://www.agno.com/articles/publish-your-docs-as-agent-knowledge-with-page-storage
- Markdown: https://www.agno.com/articles/publish-your-docs-as-agent-knowledge-with-page-storage.md

Agno's `Knowledge.sync_pages` takes a site's `llms.txt` URL, discovers the pages, fetches their Markdown, embeds them, and publishes each page's text, catalog entry and vectors in one transaction. Page storage lives in `agno.knowledge.page`, and `Knowledge` needs a `page_store` to use it.

<Video
  src="/videos/changelog-page-storage-terminal.mp4"
  controls
  preload="metadata"
  aria-label="A terminal recording of Knowledge.sync_pages publishing llmstxt.org from its llms.txt, then reporting the site unchanged on a second sync"
/>

Keeping an agent in step with your docs usually means a crawler, a chunker and a vector table that drift apart. A refresh dies halfway through, and now the agent serves new text against old vectors. Page storage treats each page as one unit that either publishes whole or stays as it was.

```python
from agno.db.postgres import PostgresDb
from agno.fs import FileSystem
from agno.knowledge import Knowledge
from agno.knowledge.embedder.openai import OpenAIEmbedder
from agno.vectordb.pgvector import PgVector

db = PostgresDb(db_url="postgresql+psycopg://ai:ai@localhost:5532/ai")
knowledge = Knowledge(
    content_db=db,
    page_store=FileSystem(db=db, namespace="product-docs"),
    vector_db=PgVector(
        db=db,
        table_name="product_doc_vectors",
        embedder=OpenAIEmbedder(id="text-embedding-3-small"),
    ),
)
knowledge.setup()
report = knowledge.sync_pages(url="https://docs.agno.com/llms.txt")
print(report.status, report.updated, report.deleted, report.failed)
```

The report from `sync_pages` lists every failed and removed page, and Agno reuses unchanged pages without re-embedding them.

![A page sync: llms.txt is discovered, each page is fetched, chunked and embedded, then its text, catalog entry and vectors are published in one transaction. If a page fails, its previous published version stays live.](https://www.agno.com/images/v3-0-7-page-storage-sync.png)

### What can an agent do with published pages?

An agent can search the published pages, read the full page behind a result at the same revision, list pages under a path, and grep for literal text. Every page call has an async counterpart and bounded output.

```python
result = knowledge.search_pages("How do agents use tools?")
hit = result.results[0]
page = knowledge.read_page(hit.path, revision=hit.revision)
```

Install page storage with `pip install "agno[pages]"`, and learn more about [published pages](https://docs.agno.com/knowledge/published-pages) in the documentation. For a production example, see [how we built the Agno Docs Agent](https://docs.agno.com/use-cases/documentation-agents/how-we-built-it).
