{
  "schema_version": 2,
  "id": "ai-agent-resources",
  "title": "AI Agent Resources",
  "url": "https://redis.io/docs/latest/ai-agent-resources/",
  "summary": "Learn how to develop with Redis as an AI agent",
  "tags": [],
  "last_updated": "2026-10-05T16:11:44+01:00",
  "page_type": "content",
  "content_hash": "00e53da3341149d5079f8ed4178dc518c71cf51ded5fa8024e3080fa20b87198",
  "sections": [
    {
      "id": "llmstxt-index-of-documentation",
      "title": "`llms.txt` index of documentation",
      "role": "overview",
      "text": "Redis provides a comprehensive index of all documentation in Markdown format at [llms.txt](https://redis.io/llms.txt). This index is specifically designed for AI agents to discover available documentation."
    },
    {
      "id": "markdown-documentation-format",
      "title": "Markdown documentation format",
      "role": "content",
      "text": "All documentation pages are available in Markdown format via the same URL as\nthe main doc page but with `index.html.md` added. For example, the Markdown version of\nthis page is available at\n[ai-agent-resources/index.html.md](https://redis.io/docs/latest/ai-agent-resources/index.html.md)."
    },
    {
      "id": "bulk-downloads",
      "title": "Bulk downloads",
      "role": "content",
      "text": "To take whole products at once rather than page by page, use the **Download documentation**\nbutton in the sidebar of any documentation page. Choose the products you want, a version for\neach, and a format, and you get a single `.tar.gz`.\n\nThe archives are also plain files, so you can fetch them directly:\n\n[code example]\n\nFor example, `redis-software-latest-md.tar.gz` or `commands-latest-json.tar.gz`. Formats are\n`md` (one Markdown file per page), `md-single` (a product in one Markdown file), `html`, and\n`json`. Products are `develop`, `integrations`, `redisvl`, `redis-software`, `redis-cloud`, `redis-kubernetes`, `redis-open-source`, `redis-iris`, `redis-feature-form`, `redis-insight`, `redis-data-integration`, `glossary`, and `commands`."
    },
    {
      "id": "json-documentation-feeds",
      "title": "JSON documentation feeds",
      "role": "content",
      "text": "Redis documentation is available in structured JSON format optimized for RAG (Retrieval-Augmented Generation) systems."
    },
    {
      "id": "ndjson-feed-all-pages",
      "title": "NDJSON feed (all pages)",
      "role": "content",
      "text": "A single file containing all documentation pages in [NDJSON](https://github.com/ndjson/ndjson-spec) format (one JSON object per line):\n\n| Format | URL | Size |\n|--------|-----|------|\n| NDJSON | [docs.ndjson](https://redis.io/docs/latest/docs.ndjson) | ~30 MB |\n| Gzipped | [docs.ndjson.gz](https://redis.io/docs/latest/docs.ndjson.gz) | ~5 MB |\n\nBoth files contain one record per documentation page, currently more than 2,600."
    },
    {
      "id": "per-page-json",
      "title": "Per-page JSON",
      "role": "content",
      "text": "Each documentation page has a corresponding JSON file at the same URL with `/index.json` appended. For example:\n\n- Page: `https://redis.io/docs/latest/commands/set/`\n- JSON: `https://redis.io/docs/latest/commands/set/index.json`"
    },
    {
      "id": "what-the-feeds-cover",
      "title": "What the feeds cover",
      "role": "content",
      "text": "The feeds contain one record for every documentation page. They deliberately do **not**\ncontain the taxonomy pages that appear in\n[sitemap.xml](https://redis.io/docs/latest/sitemap.xml), so a straight comparison of the two\nshows the sitemap with more URLs.\n\nThe excluded pages are:\n\n- the `categories/` listing and each `categories/<name>` page\n- the `tags/` listing and each `tags/<name>` page\n- the documentation home page\n\nThese are generated index pages that list other pages. They carry no documentation prose of\ntheir own, so a record for them would add navigation noise without adding content. The\nexclusion is a consequence of how the output formats are configured rather than a filter\napplied afterwards: JSON and Markdown are produced for Hugo's `section` and `page` kinds\nonly, and taxonomy, term and home pages are none of those.\n\nTwo consequences worth knowing if you diff the feed against the sitemap:\n\n- Pages excluded from Hugo's page lists with `_build.list: never` are **absent from the\n  sitemap but present in the feeds**, because they are still built and rendered. They are\n  real documentation pages, usually reference material reached by direct link rather than by\n  browsing.\n- Both figures move. The feed is rebuilt at least daily and the corpus grows, so treat any\n  page count as a snapshot."
    },
    {
      "id": "schema-version",
      "title": "Schema version",
      "role": "content",
      "text": "Every record carries a `schema_version` integer, and the same value appears in the\n`json metadata` block of the Markdown output. It is currently **2**.\n\nIt increments only when the **shape** of a record changes: a field added, removed or\nrenamed, or a new value entering the [role vocabulary](#section-roles). It does **not**\nchange when page content changes, and it does not change when the value inside a field\nchanges without the field itself changing. Use `content_hash` to detect content changes;\nuse `schema_version` to detect when your parser might need attention.\n\nVersion 2 added the `aliases` field to page records, and a new `page_type` value,\n`moved`, for the [redirect records](#pages-that-have-moved) served at a moved page's\nold URL. Version 1 was the initial shape: `sections`, `examples`, `content_hash`,\n`page_type`, `id` and `since`."
    },
    {
      "id": "pages-that-have-moved",
      "title": "Pages that have moved",
      "role": "content",
      "text": "When a page moves, its old URL keeps working — but until now it served only an HTML\nredirect, so appending `/index.json` to it returned 404 and a move was\nindistinguishable from a deletion. Two things now fix that."
    },
    {
      "id": "a-redirect-record-at-the-old-url",
      "title": "A redirect record at the old URL",
      "role": "content",
      "text": "Appending `/index.json` to a moved page's URL returns a record with\n`page_type` set to `moved`:\n\n[code example]\n\n**Check `page_type` before assuming the shape of a record.** A `moved` record\ndeliberately carries no `sections`, `examples` or `content_hash` — there is no content\nat that URL, only a pointer. Fetch `moved_to` to get the page itself.\n\nThese records are **not** included in `docs.ndjson`. The feed is one record per\ndocumentation page, and adding roughly a thousand pointer records would make any count\nof the corpus ambiguous. Use the map below if you need them in bulk."
    },
    {
      "id": "a-map-of-every-redirect",
      "title": "A map of every redirect",
      "role": "content",
      "text": "`https://redis.io/docs/latest/redirects.json` lists every alias the site publishes and\nthe page it resolves to:\n\n[code example]\n\nFour things worth knowing before you rely on it:\n\n- `from` is normalized to a leading slash and no trailing slash. `to` is absolute,\n  matching the `url` field on page records. Every key in `redirects` has a redirect\n  record of its own at `<from>/index.json`, so you can resolve one URL without\n  fetching the whole map.\n- **It is an alias map, not a move log.** Many entries are vanity or legacy paths that\n  were never a page's location. Where we can date a move from the repository history,\n  the entry carries a `moved_on`; entries without one are not undated moves, they are\n  aliases that were never a page's location in the first place.\n- **A URL missing from the map is not necessarily gone.** We publish redirects we can\n  establish, not a complete account of every URL that ever existed. In particular we\n  deliberately do not publish a list of deleted pages: the repository history cannot\n  reliably tell a deletion from a move it failed to detect, and telling you a page was\n  deleted when it merely moved would be worse than telling you nothing.\n- `ambiguous` holds the keys that more than one page claims, with every candidate\n  listed. We publish them separately rather than picking one, because the site itself\n  resolves those arbitrarily — so any single answer we gave you would sometimes\n  disagree with what you would actually be served. Treat an `ambiguous` key as\n  unresolved.\n- `shadowed` holds aliases a page declares that the site does not act on, because a\n  real page already occupies that URL — so the URL serves its own content rather than\n  redirecting. They are listed for completeness and **must not** be followed as\n  redirects; doing so would take a reader away from a live page.\n\nThe map covers the current version of the documentation. Version-specific\ndocumentation is outside both machine-readable feeds."
    },
    {
      "id": "json-schema",
      "title": "JSON schema",
      "role": "content",
      "text": "Each document contains:\n\n| Field | Type | Description |\n|-------|------|-------------|\n| `schema_version` | integer | Version of the record format. See [Schema version](#schema-version). |\n| `id` | string | Unique identifier, the page's path without a file extension (for example `develop/clients/redis-py`) |\n| `title` | string | Page title |\n| `url` | string | Canonical URL |\n| `summary` | string | Short description |\n| `since` | string | Redis version the command was introduced in. Present on command pages only. |\n| `page_type` | string | `\"content\"` (has prose) or `\"index\"` (navigation only) |\n| `content_hash` | string | SHA256 hash for cache invalidation (content pages only) |\n| `sections` | array | Content split by headings with semantic roles |\n| `examples` | array | Code blocks extracted from content |\n| `children` | array | Child pages (index pages only) |\n\nEach **section** contains:\n- `id`: Slugified heading, matching the heading's anchor on the rendered page, so\n  `<url>#<section id>` links to that section\n- `title`: Original heading text\n- `role`: Semantic role, assigned from the heading text. See\n  [Section roles](#section-roles) for the current values.\n- `text`: Section content (code blocks replaced with `[code example]` placeholder)\n\nEach **example** contains:\n- `id`: Unique identifier (`{section_id}-ex{index}`)\n- `language`: Language from code fence (`python`, `go`, `plaintext`, etc.)\n- `code`: The code content\n- `section_id`: Which section this example came from"
    },
    {
      "id": "section-roles",
      "title": "Section roles",
      "role": "content",
      "text": "Each section carries a `role`, derived from its heading text. These are the values currently\nin use:\n\n| Role | Assigned when the heading begins with |\n|------|----------------------------------------|\n| `overview` | `overview`, `introduction`, `about`, `description` |\n| `syntax` | `syntax`, `usage`, `command`, `signature` |\n| `example` | `example`, `demo`, `sample`, `code example` |\n| `parameters` | `option`, `parameter`, `argument`, `flag` |\n| `returns` | `return`, `response`, `output`, `result` |\n| `errors` | `error`, `exception`, `troubleshoot` |\n| `performance` | `performance`, `complexity`, `benchmark` |\n| `limits` | `limit`, `constraint`, `restriction` |\n| `related` | `see also`, `related`, `learn more`, `reference` |\n| `setup` | `install`, `setup`, `getting started`, `quickstart` |\n| `configuration` | `configur`, `setting` |\n| `security` | `security`, `auth`, `permission`, `acl` |\n| `history` | `history`, `changelog`, `version history` |\n| `compatibility` | `compatib`, `support`, `version` |\n| `content` | none of the above |\n\nThe table is in priority order and the first match wins, which matters where the patterns\noverlap: a heading of \"Version history\" is `history` rather than `compatibility`, because\n`history` is tested first.\n\nA page's introductory text, before its first heading, is also given the `overview` role.\n\n> [!NOTE]\n> This vocabulary is descriptive, not a contract. It reflects the values produced\n> today and may gain entries, or change how a heading maps to a role, without notice. If you\n> filter or rank on `role`, treat an unrecognized value as `content` rather than discarding the\n> section, and do not assume a value you rely on will keep its current name."
    },
    {
      "id": "verifying-content_hash",
      "title": "Verifying content_hash",
      "role": "content",
      "text": "The `content_hash` can be verified by computing:\n\n[code example]"
    },
    {
      "id": "api-references",
      "title": "API references",
      "role": "content",
      "text": "API references are available for the following client libraries:\n\n- [redis-py](https://redis.readthedocs.io/en/stable/commands.html)\n- [jedis](https://javadoc.io/doc/redis.clients/jedis/latest/index.html)\n- [lettuce](https://lettuce.io/core/release/reference/index.html)\n- [go-redis](https://pkg.go.dev/github.com/redis/go-redis/v9)\n- [redis-rs](https://docs.rs/redis/latest/redis/)"
    },
    {
      "id": "data-type-comparisons",
      "title": "Data type comparisons",
      "role": "content",
      "text": "See [Compare data types](https://redis.io/docs/latest/develop/data-types/compare-data-types) for advice\non which of the general-purpose data types is best for common tasks."
    },
    {
      "id": "redis-patterns-for-coding-agents",
      "title": "Redis patterns for coding agents",
      "role": "content",
      "text": "Salvatore Sanfilippo (also known as *antirez*, the creator of Redis) has provided the Redis community with a resource containing very useful Redis-oriented design patterns. See [this page](https://redis.antirez.com/) for more information."
    },
    {
      "id": "agent-skills-repository",
      "title": "Agent skills repository",
      "role": "content",
      "text": "The [redis/agent-skills](https://github.com/redis/agent-skills) repository provides reusable skills and tools for AI agents working with Redis."
    },
    {
      "id": "error-handling",
      "title": "Error handling",
      "role": "errors",
      "text": "See [Error handling](https://redis.io/docs/latest/develop/clients/error-handling) for a guide to handling errors in client libraries."
    }
  ],
  "examples": [
    {
      "id": "bulk-downloads-ex0",
      "language": "plaintext",
      "code": "https://redis.io/docs/latest/downloads/bundles/<product>-<version>-<format>.tar.gz",
      "section_id": "bulk-downloads"
    },
    {
      "id": "a-redirect-record-at-the-old-url-ex0",
      "language": "json",
      "code": "{\n  \"schema_version\": 2,\n  \"id\": \"develop/ai/agent-memory\",\n  \"title\": \"Moved\",\n  \"url\": \"https://redis.io/docs/latest/develop/ai/agent-memory/\",\n  \"page_type\": \"moved\",\n  \"moved_to\": \"https://redis.io/docs/latest/develop/ai/context-engine/agent-memory/\"\n}",
      "section_id": "a-redirect-record-at-the-old-url"
    },
    {
      "id": "a-map-of-every-redirect-ex0",
      "language": "json",
      "code": "{\n  \"schema_version\": 2,\n  \"base_url\": \"https://redis.io/docs/latest/\",\n  \"generated\": \"2026-08-07T15:00:00Z\",\n  \"count\": 1061,\n  \"ambiguous_count\": 27,\n  \"shadowed_count\": 10,\n  \"redirects\": [\n    {\"from\": \"/develop/ai/langcache\", \"to\": \"https://redis.io/docs/latest/develop/ai/context-engine/langcache/\", \"moved_on\": \"2026-05-11\"}\n  ],\n  \"ambiguous\": [\n    {\"from\": \"/develop/use/pipelining\", \"candidates\": [\"https://redis.io/docs/latest/develop/using-commands/\", \"https://redis.io/docs/latest/develop/using-commands/pipelining/\"]}\n  ],\n  \"shadowed\": [\n    {\"from\": \"/glossary\", \"declared\": [\"https://redis.io/docs/latest/glossary/\"]}\n  ]\n}",
      "section_id": "a-map-of-every-redirect"
    },
    {
      "id": "verifying-content_hash-ex0",
      "language": "python",
      "code": "import hashlib\n\ndef verify_hash(page):\n    parts = [page.get('summary', '')]\n    for section in page.get('sections', []):\n        parts.append(section['text'])\n    for example in page.get('examples', []):\n        parts.append(example['code'])\n\n    content = '\\n'.join(parts)\n    return hashlib.sha256(content.encode('utf-8')).hexdigest() == page.get('content_hash')",
      "section_id": "verifying-content_hash"
    }
  ]
}
