sphinx-llm
The sphinx-llm package includes a collection of
Sphinx extensions for working with LLMs.
There are two categories of tools in this package:
- Enabling LLMs and agents to consume your docs - Produces additional build output for consumption by LLMs and agents. This is useful when you want your project to be well indexed and represented in LLMs when users ask about projects in your domain.
- Leveraging LLMs to generate content dynamically during the Sphinx build - Uses LLMs to generate content as part of the build process. This is useful for generating static content that gets baked into the documentation. It is not intended to provide an interactive chat service in your documentation.
Installation
pip install sphinx-llm
# For extensions that use LLMs to generate text
pip install sphinx-llm[gen]
Extensions
llms.txt Support
The sphinx_llm.txt extension automatically generates markdown files for
consumption by LLMs following the llms.txt standard
alongside HTML files during the Sphinx build process.
The llms.txt standard describes how you can provide
documentation in a way that can be easily consumed by LLMs, either during
model training or by agents at inference time when using tools that gather
context from the web. The standard describes that your documentation sitemap
should be provided in markdown in llms.txt and then the entire documentation
should be provided in markdown via a single file called llms-full.txt.
Additionally each individual page on your website should also have a markdown
version of the page at the same URL with an additional .md extension.
To use the extension add it to your conf.py:
# conf.py
# ...
extensions = [
"sphinx_llm.txt",
]
When you build your documentation with sphinx-build (or make html), the
extension will:
- Builds your documentation as usual
- Also builds your documentation with the markdown builder
- Merges the build outputs together
- The markdown files will have the same as the HTML name plus an extra
.mdextension
- The markdown files will have the same as the HTML name plus an extra
- Generates an index file for all the markdown files named
llms.txt - Concatenates all generated markdown into a single
llms-full.txtfile
For example, if your build with the html builder generates:
_build/html/index.html_build/html/apples.html
The extension will also create:
_build/html/llms.txt_build/html/llms-full.txt_build/html/index.html.md_build/html/apples.html.md
With the dirhtml builder, which creates URLs like /apples/ instead of
/apples.html, the extension generates markdown files in both the file-suffix
format (page/index.html.md) and the URL-suffix format (page.md) by default:
_build/dirhtml/llms.txt_build/dirhtml/llms-full.txt_build/dirhtml/index.html.md_build/dirhtml/apples/index.html.md(file-suffix)_build/dirhtml/apples.md(URL-suffix, matches Claude docs behavior likehttps://platform.claude.com/docs/overview.md)
You can control which format(s) are generated using the llms_txt_suffix_mode
configuration option:
"auto"(default): Fordirhtml, generates both file-suffix and URL-suffix formats; forhtml, generates the standard.html.mdformat"file-suffix": Fordirhtml, only generatespage/index.html.md; forhtml, generates the standard.html.mdformat"url-suffix": Fordirhtml, only generatespage.md; forhtml, generates the standard.html.mdformat"replace": Replaces the.htmlextension with.mdin the HTML output path. Forhtmlbuilder:page.html→page.md. Fordirhtmlbuilder:page/index.html→page/index.md
[!NOTE] This extension only works with HTML builders (like
htmlanddirhtml).
Configuration
Supported conf.py configuration options for sphinx_llm.txt.
| Name | Description | Type | Default |
|---|---|---|---|
llms_txt_enabled |
Enable or disable all llms.txt artefact generation. Set to False to skip the entire extension without removing it from conf.py. Use sphinx-build -D llms_txt_enabled=0 to skip on a per-build basis. |
bool |
True |
llms_txt_description |
Override the project description set in llms.txt |
str |
Uses the project description from pyproject.toml by default |
llms_txt_build_parallel |
Build markdown files in parallel to the HTML files. | bool |
True |
llms_txt_suffix_mode |
Suffix mode for generated markdown files. Options: "auto" (default behavior for each builder), "file-suffix" (spec-compliant format), "url-suffix" (URL-style format), or "replace" (replaces .html with .md). Note: "both" is deprecated but still supported (treated as "auto"). |
str |
"auto" |
llms_txt_full_build |
Whether to generate the llms-full.txt file. Set to False to disable generation, which is useful for large documentation sites where the concatenated file would be too large. |
bool |
True |
llms_txt_exclude |
A list of Sphinx wildcard patterns matched against document names (not regular expressions or source paths) to exclude from llms.txt and llms-full.txt. * does not cross /, while ** does; for example, "reference/generated/**". The individual markdown files for excluded documents are still generated. |
list[str] |
[] |
llms_txt_override_source |
Advanced option that overrides the automatically generated llms.txt sitemap with the rendered contents of a custom Sphinx source document. Specify a docname or source path relative to the source directory, such as "llms-txt" or "llms-txt.rst". |
str |
"" |
llms_txt_summary_enabled |
Generate one-sentence page descriptions with an OpenAI-compatible provider. | bool |
False |
llms_txt_summary_provider |
Summary provider. The initial implementation supports "openai-compatible". |
str |
"openai-compatible" |
llms_txt_summary_model |
Model used for generated page descriptions. Required when generation is enabled. | str |
"" |
llms_txt_summary_base_url |
Base URL of the OpenAI-compatible endpoint. An empty value uses the OpenAI client default. | str |
"" |
llms_txt_summary_api_key_env |
Name of the environment variable containing the API key. Set to "" only for an endpoint that deliberately requires no authentication. |
str |
"OPENAI_API_KEY" |
llms_txt_summary_allow_insecure_auth |
Allow an API key to be sent to a non-loopback endpoint over plain HTTP. Use only for a trusted network where HTTPS is unavailable. | bool |
False |
llms_txt_summary_max_input_chars |
Maximum Markdown characters sent to the provider. The complete page is still hashed for cache invalidation. | int |
12000 |
llms_txt_summary_timeout |
Provider request timeout in seconds. | int |
60 |
llms_txt_summary_cache_path |
JSON cache path. Relative paths use the Sphinx configuration directory; an empty value stores the cache under app.doctreedir. |
str |
"" |
Each page's entry in llms.txt includes a short description. If a page defines
an html_meta description, that non-empty author-provided value always wins and
no provider request is made. In reStructuredText, use:
.. meta::
:description: An author-provided page description.
In MyST Markdown, use frontmatter:
---
html_meta:
description: An author-provided page description.
---
When no authored description exists, enabled summary generation uses a cached or newly generated description. When generation is disabled, which is the default, the extension retains the existing first-paragraph fallback and makes no provider requests.
Generated page summaries
[!WARNING] Enabling page summaries sends rendered documentation content to the configured provider. Review that provider's privacy and data-retention terms before using this feature with confidential documentation.
Install the optional generation dependencies and explicitly enable summaries:
pip install sphinx-llm[gen]
export SPHINX_LLM_SUMMARY_ENABLED=1
export SPHINX_LLM_SUMMARY_MODEL=your-model
export SPHINX_LLM_SUMMARY_BASE_URL=https://llm.example.com/v1
export OPENAI_API_KEY=your-api-key
sphinx-build docs/source docs/build/html
The summary options can be configured in conf.py or supplied through
environment variables. Environment variables are useful when local and CI
builds need different providers or models, or when you do not want to commit
those settings to conf.py. The available variables are
SPHINX_LLM_SUMMARY_ENABLED, SPHINX_LLM_SUMMARY_PROVIDER,
SPHINX_LLM_SUMMARY_MODEL, SPHINX_LLM_SUMMARY_BASE_URL,
SPHINX_LLM_SUMMARY_API_KEY_ENV,
SPHINX_LLM_SUMMARY_ALLOW_INSECURE_AUTH,
SPHINX_LLM_SUMMARY_MAX_INPUT_CHARS, SPHINX_LLM_SUMMARY_TIMEOUT, and
SPHINX_LLM_SUMMARY_CACHE_PATH. Values resolve in this order: a
sphinx-build -D override, an environment variable, conf.py, then the
built-in default.
Installing the optional dependencies or detecting a local CLI does not enable
summaries; set llms_txt_summary_enabled explicitly.
SPHINX_LLM_SUMMARY_API_KEY_ENV is optional. Set it only to read the key from a
different environment variable, for example
SPHINX_LLM_SUMMARY_API_KEY_ENV=NVIDIA_API_KEY; it names the variable and does
not contain the key itself.
The API key itself is read only from the named environment variable; it is not
a Sphinx configuration value and is excluded from logs, the cache, and cache
fingerprints. The selected credential is sent to the configured endpoint, so
set SPHINX_LLM_SUMMARY_API_KEY_ENV when a non-OpenAI provider uses a different
key. For an explicitly unauthenticated endpoint, set
llms_txt_summary_api_key_env = ""; this does not fall back to OPENAI_API_KEY.
Configured keys are rejected for non-loopback plain-HTTP endpoints; use HTTPS,
or a loopback URL such as http://localhost:8000/v1 for local development. If
neither is possible on a trusted network, set
llms_txt_summary_allow_insecure_auth = True in conf.py or
SPHINX_LLM_SUMMARY_ALLOW_INSECURE_AUTH=1 in the environment. This sends the
API key without transport encryption and should not be used on untrusted
networks.
The versioned JSON cache is stored in the doctree directory by default and is written atomically. Cache entries hash the complete generated Markdown plus the provider, endpoint, model, prompt version, input limit, timeout, insecure-auth setting, and credential environment-variable name. Only the configured Markdown prefix is sent to the provider, but a change anywhere in a page invalidates that page alone. Restore the doctree directory or configured cache path in CI to reuse summaries across jobs.
Custom llms.txt override
[!IMPORTANT] This is an advanced option for users who need full control over
llms.txt. Most projects should use the automatically generated sitemap.
To write llms.txt manually while retaining Sphinx features such as cross
references, create a source document and configure it in conf.py:
llms_txt_override_source = "llms-txt.rst"
The document is rendered with the other Markdown pages, then its rendered
contents replace the automatically generated llms.txt sitemap. All per-page
Markdown files are still generated normally, while llms-full.txt remains
controlled independently by llms_txt_full_build. The custom source document
may be included in a toctree or marked with :orphan:.
Docref
The sphinx_llm.docref extension adds a directive that summarises and links
to another page. It uses the same llms_txt_summary_* settings, environment
variables, provider safeguards, and versioned JSON cache described in
Generated page summaries. Generation is disabled
by default.
Enable the extension in conf.py:
extensions = [
"sphinx_llm.docref",
]
An empty directive opts into automatic generation:
.. docref:: apples
A non-empty body is a permanent, reference-specific manual override:
.. docref:: apples
A reviewed explanation of why the apples page is relevant here.
A page can also set its own description using page-level html_meta when you
want this content to be static.
Summary generation follows this order of precedence:
- Non-empty directive body
- Target page
html_metadescription - Valid generated summary from the shared page-summary cache
- Content-derived fallback when generation is disabled or a target is missing
The optional directive :model: setting overrides
llms_txt_summary_model for one automatic reference. Identical references
to the same target and effective settings generate at most once. Requests and
effective rendering state live in the Sphinx environment, while generated
records are also persisted through llms_txt_summary_cache_path so clean
builds and llms.txt summary generation use one inspectable cache.
Each successful build writes sphinx-llm-summaries.json to the output
directory. It lists each effective summary, its origin, target, consuming
source locations, and generated-summary metadata without endpoints, API-key
environment-variable names, or credentials.
Docref styling
By default, a docref title is prefixed with See also:, and its link uses
the text Read more >> and the CSS class visit-link. Configure these global
defaults in conf.py:
llms_txt_docref_style_title_prefix = "Related:"
llms_txt_docref_style_visit_link_text = "Visit page"
llms_txt_docref_style_visit_link_class = "docref-link prominent"
Override any setting for one directive with :style-title-prefix:,
:style-visit-link-text:, and :style-visit-link-class:. Directive options
take precedence over the matching conf.py setting:
.. docref:: apples
:style-title-prefix: More about
:style-visit-link-text: Read the guide
:style-visit-link-class: docref-link compact
Set an option or configuration value to an empty string to render no title prefix, link text, or CSS class. Separate multiple CSS classes with whitespace.
The original :title-prefix:, :visit-link-text:, and :visit-link-class:
directive options, and the corresponding llms_txt_docref_title_prefix,
llms_txt_docref_visit_link_text, and llms_txt_docref_visit_link_class
configuration values, remain available as deprecated aliases. When a canonical
and legacy form are both set for the same value, the canonical styling form
wins.
Building the docs
Try it out yourself by building the example documentation.
uv run --dev sphinx-autobuild docs/source docs/build/html
Alternatives
There are other projects that solve this same problem, that's the wonderful nature of open source software. This section compares the various approaches each project has taken.
These comparisons have been put together with the best of intentions and involvement from the maintainers of all projects compared here, but we acknowledge they are highly subjective. If you spot any information on this page that you believe to be incorrect or incomplete please don't hesitate to open a Pull Request. The goal here is to provide you with all the information you need to make the right choice for your needs.
| Dimension | sphinx-llm | sphinx-llms-txt |
|---|---|---|
| Purpose | Rich llms.txt and llms-full.txt markdown creation with individual pages and LLM summarization capabilities. |
Simple llms.txt and llms-full.txt files creation. |
| Individual pages | Outputs a Markdown rendered version for each page. | Source of each page is available at a Sphinx specific _sources URL. |
| Supported docs input formats | Works with any Sphinx source format including RST, MyST, etc. | Works with any Sphinx source format including RST, MyST, etc. |
Supported llms.txt output formats |
Markdown. | llm.txt is markdown; llms-full.txt and pages pass through source format. |
| Additional features | In the future could allow llms.txt to include LLM generated summaries of each page (see #28). |
Allows manual configuration of llms-full.txt content. |
| Build-time behavior | Minimal build time impact; a separate build of the markdown is run in parallel, then the two build outputs are merged. | Minimal build time impact; post build runs a converter/aggregator of _sources. |
| Limitations | Not all directives are supported by the markdown builder. | Source documentation files are not processed, so directives like automodule aren't expanded. |
Making a release
Releases are automated via GitHub Actions and any maintainers with write access to the repository can create one in just a couple of steps. To create a new release:
-
From
main, create an annotated stable EffVer tag with avprefix (for example,v0.0.0; prerelease tags do not publish a release):git tag -a v0.0.0 -m 'Version v0.0.0' -
Push the tag to the upstream repository:
git push https://github.com/NVIDIA/sphinx-llm main --tags
The GitHub Actions workflow will automatically build the package and publish it to PyPI using trusted publishing.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sphinx_llm-1.0.0.tar.gz.
File metadata
- Download URL: sphinx_llm-1.0.0.tar.gz
- Upload date:
- Size: 382.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1cc8284343a0100caa3110010da5933cdad8da37d2b9dda0e2a7d503b8da6b1c
|
|
| MD5 |
5cdddde47772370e789cbc38e2f2041f
|
|
| BLAKE2b-256 |
33586b1802820a17e7a128b45046d735f934af00f4290704b647b126213bdeb4
|
Provenance
The following attestation bundles were made for sphinx_llm-1.0.0.tar.gz:
Publisher:
publish.yml on NVIDIA/sphinx-llm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sphinx_llm-1.0.0.tar.gz -
Subject digest:
1cc8284343a0100caa3110010da5933cdad8da37d2b9dda0e2a7d503b8da6b1c - Sigstore transparency entry: 2463318324
- Sigstore integration time:
-
Permalink:
NVIDIA/sphinx-llm@03d825b62d89c99f6213c430ca309ebadb13305b -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/NVIDIA
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@03d825b62d89c99f6213c430ca309ebadb13305b -
Trigger Event:
push
-
Statement type:
File details
Details for the file sphinx_llm-1.0.0-py3-none-any.whl.
File metadata
- Download URL: sphinx_llm-1.0.0-py3-none-any.whl
- Upload date:
- Size: 60.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8d45dbe5f9caffb4d78589c35d15fc8399dd41fc5b445ee4292ff83969754e75
|
|
| MD5 |
5d2d873973f6d1f5d5f124122bb668ad
|
|
| BLAKE2b-256 |
af5b2a338974998bc0fe563635625abdb16a000ee06a63101b361c834cd56ccb
|
Provenance
The following attestation bundles were made for sphinx_llm-1.0.0-py3-none-any.whl:
Publisher:
publish.yml on NVIDIA/sphinx-llm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sphinx_llm-1.0.0-py3-none-any.whl -
Subject digest:
8d45dbe5f9caffb4d78589c35d15fc8399dd41fc5b445ee4292ff83969754e75 - Sigstore transparency entry: 2463318341
- Sigstore integration time:
-
Permalink:
NVIDIA/sphinx-llm@03d825b62d89c99f6213c430ca309ebadb13305b -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/NVIDIA
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@03d825b62d89c99f6213c430ca309ebadb13305b -
Trigger Event:
push
-
Statement type: