编写 API 文档#

唯一事实来源#

公开对象是从定义它们的模块中发现的:参考文档生成器会遍历运行时包,保留每个模块自己定义的公开名称,为每个名称生成一个页面,并按职责对页面分组。不要修改 docs/_generated,重新构建会重新生成这些文件。API 说明写在源码的文档字符串里,教程写在手写的 RST 页面中。

Sphinx、reStructuredText 与文档字符串风格#

这是几个不同的层次。Sphinx 负责构建网站并生成交叉链接。reStructuredText(RST)是手写 .rst 页面使用的标记语言。Google 风格规定 Python 文档字符串的结构,Napoleon 扩展把这些小节转换成 Sphinx 标记。PyData 主题控制呈现效果。

NumPy 风格的文档字符串是另一种输入约定,并不是做出类 NumPy 网站的前提。本项目始终使用 Google 风格的小节,而不在同一个类里混用不同约定。

常用的 RST 结构:

A section heading
=================

:class:`~zett_agent.agent.Agent`
:meth:`~zett_agent.agent.Agent.stream`
:doc:`extending/first-extension`

.. code-block:: python

   reply = await client.run("Hello")

.. literalinclude:: _examples/first_agent.py
   :language: python
   :pyobject: main

指令内容之前要留一个空行,并缩进它们的选项和正文。经过测试的示例请用 literalinclude,这样网站上的代码和可下载的程序不会悄悄产生分歧。交叉引用角色会解析符号并生成链接;单用反引号并不会创建 API 参考条目。

图#

当流程、状态和时序图需要真正的节点和连线时,请使用 Mermaid。手写文档可以直接使用该指令,Sphinx 会在不同视口尺寸下把它渲染成清晰的 SVG:

.. mermaid::
   :caption: The model-tool loop

   flowchart LR
      user[UserMessage] --> model[model]
      model -- ToolCall --> tool[tool]
      tool -- ToolMessage --> model
      model --> assistant[AssistantMessage]

公开 API 的文档字符串使用 .. zett-diagram:: name,后面跟一份 ASCII 版本。这样源码在编辑器、help() 和终端里依然有用;本地的 diagrams Sphinx 扩展只会在构建网站时把该块替换成已注册的 Mermaid 图。行为发生变化时,两种表示都要更新。

当输出的具体字符本身就是文档的主题时——比如终端记录、线格式或 ASCII 表格——请保留 .. code-block:: text。更大的架构图应该放进手写的指南里。

Google 风格的文档字符串#

先写一句简短的祈使式摘要,再写可选的行为细节,然后是相关小节。类型由类型注解提供;文档字符串说明含义、单位、默认值、归属关系和失败条件。

async def run(message: str) -> AssistantMessage:
    """Process a request and return its final answer.

    Args:
        message: Current user input, not the complete conversation history.

    Returns:
        Final assistant output after stream cleanup.

    Raises:
        AgentProtocolError: If the runtime is not initialized.

    Examples:
        Send one message::

            reply = await agent.run("Hello")
            print(reply.content)
    """

异步生成器用 Yields,数据模型字段用 Attributes,只有在能说明真实约束时才用 Note 或 Warning。无关的小节请省略。只包含代码的示例在 :: 之后使用缩进的文字块;只有普通 Python 代码而位于 Examples 标题下时,可能会被当作正文解析。

字段注释#

@dataclass
class Usage:
    """Normalized provider usage."""

    #: Input tokens, including the subset read from cache.
    input_tokens: int = 0

#:能让紧邻源码的字段说明被 autodoc 读取。不要在 Attributes 小节和字段注释里重复同一段说明。请写明时间单位、UTC 与单调时钟的区别、可为空的值以及子集关系。

工具还有一层约定#

Snippet 和 Guidelines 由工具装饰器读取,并纳入模型看到的 guidelines。它们不只是网站排版。修改它们之后,请保持解析器语法的完整,并运行工具模式的测试加以校验。面向开发者的示例应放在 Examples 小节,而不是写给模型看的准则里。

构建与校验#

在仓库根目录下执行:

make docs
make docs-serve

构建会把文档警告当作错误。文档测试会检查每个公开导出是否都有生成的页面,并检查链接、示例块和参数说明是否出现在构建产物中。普通构建会导入这个包,但不会实例化模型提供商、执行示例,也不会触碰会话数据。