For the complete documentation index, see llms.txt. This page is also available as Markdown.

结构化输出

根据提供的模式强制规范智能体输出。

前置条件

本指南假设你已经熟悉以下概念:

在许多用例中,我们需要 Agent 理解自然语言,但输出为 结构化格式。一个常见用例是从文本中提取数据,以插入数据库或供其他下游系统使用。本指南介绍 Neuron 如何让你强制 Agent 输出结构化结果。

如何使用结构化输出

核心概念是,LLM 响应的输出结构需要以某种方式表示出来。Neuron 用于校验的 schema 由 PHP 类型提示定义。基本上,你必须定义一个具有严格类型属性的类:

Neuron 会从 PHP 对象生成相应的 JSON schema,以向底层模型说明你需要的数据格式。然后 Agent 会解析 LLM 输出以提取数据,并返回一个填充了相应值的对象实例:

默认输出类

你也可以将输出格式封装到 Agent 实现中,使其成为 Agent 的标准输出格式。你始终需要调用 structured() 方法来要求严格输出。

控制输出生成

Neuron 要求你定义两层规则来创建结构化输出类。

第一层是 SchemaProperty 属性,它允许你控制发送给 LLM 的 JSON schema,以便其理解所需的数据格式。

第二层是验证。验证属性可确保从 LLM 响应中收集到的数据与你的要求一致。

SchemaProperty

SchemaProperty 属性允许你定义每个属性的 JSON schema 参数:

嵌套类

你可以使用其他 PHP 对象作为属性类型来构建复杂的输出结构。以 Person 类为例,我们可以添加 address 这个属性,其类型为另一个结构化类。

Address 在定义中,我们只要求 street 和 zip code 属性,并允许 city 为空。

现在,当你向 Agent 请求结构化输出时,你将得到填充好的实例:

数组

如果你将某个属性声明为数组,Neuron 会假定其中的项目列表是字符串列表。如果你希望数组包含其他结构化对象的列表,可以使用 anyOf 参数:

下面是假设性的 Tag 类实现,它有自己的验证规则和属性信息:

多类型数组

从上面的示例可以看出,anyOf 参数是一个数组。Neuron 也支持由多种对象类型组成的数组。只需列出数组可以包含的结构化对象,Neuron 就会将它们的所有规格包含到供 LLM 使用的 JSON schema 中。

最大重试次数

由于 LLM 并非完全确定性,因此如果 LLM 响应中缺少某些内容,必须设置重试机制。

默认情况下,Neuron 会从 LLM 响应中提取并验证数据;如果存在一个或多个验证错误,它会自动再重试一次请求,并向 LLM 说明哪里出错了以及涉及哪些属性。

你可以自行自定义 Agent 为从 LLM 获取正确答案而必须重试的次数:

如果你使用能力较弱的 LLM,可以考虑设置一个折中的重试次数,在获得有效答案的概率和潜在的 token 消耗之间取得平衡。

你只需传入 0 即可禁用重试。这将成为一次性尝试:

监控与调试

使用 Neuron 构建的许多应用程序会包含多个步骤以及对 LLM 的多次调用。随着这些应用程序变得越来越复杂,能够检查你的代理系统内部到底发生了什么就变得至关重要。实现这一点的最佳方式是使用 Inspector.

每个环节都会提供自己的调试信息,以便实时跟踪 Agent 的执行:

了解如何启用 可观测性 ,请看下一节。

验证规则

由于 LLM 是非确定性系统,其输出的一致性会受到输入上下文质量的显著影响,而且它们仍可能产生幻觉,因此我们提供了一组验证规则,你可以将其添加到结构化类属性中,以指示 Neuron 验证 LLM 生成的最终数据集。

如果一个或多个属性无效,验证规则允许 Neuron 连同详细的错误报告一起多次重新向 LLM 发送生成请求,直到达到 maxRetries 值。

如果你没有定义任何验证规则,从 LLM 响应中提取的数据将直接填充到结构化输出类中。

#[NotBlank]

正在验证的属性不能为空。它接受 allowNull 标志,用于决定是否将显式的 null 值视为空值等价。

#[Length]

判断一个 字符串 是否符合给定条件:

#[WordsCount]

判断一个中的单词数量 字符串 是否符合给定条件:

#[Count]

判断一个 数组 是否符合给定条件:

#[EqualTo] - #[NotEqualTo]

这些规则具有相同的结构和含义,并接受一个参数来定义要比较的值。正在验证的属性必须严格等于(#[EqualTo])或不同于(#[NotEqualTo])参考值:

#[GreaterThan] - #[GreaterThanEqual]

这些规则具有相同的结构和含义,并接受一个参数来定义要比较的值。正在验证的属性必须严格大于(#[GreaterThan])或等于(#[GreaterThanEqual])参考值:

#[LowerThan] - #[LowerThanEqual]

这些规则具有相同的结构和含义,并接受一个参数来定义要比较的值。正在验证的属性必须严格小于(#[LowerThan])或等于(#[LowerThanEqual])参考值:

#[OutOfRange]

判断一个 数字 是否超出给定范围:

#[IsFalse] - #[IsTrue]

正在验证的属性必须具有规则定义的精确布尔值:

#[IsNull] - #[IsNotNull]

正在验证的属性必须遵守规则定义的可空条件:

#[Json]

正在验证的属性必须包含有效的 JSON 字符串:

#[Url]

正在验证的属性必须包含有效的 URL:

#[Email]

正在验证的属性必须包含有效的电子邮件地址:

#[IpAddress]

正在验证的属性必须包含有效的 IP 地址:

#[ArrayOf]

正在验证的属性必须是一个包含所给对象类型全部元素的数组。

#[Regex]

正在验证的属性必须符合给定的正则表达式。

自定义验证规则

验证规则是 PHP 属性,因此要创建新的规则,你应该继承框架的 AbstractValidationRule,并将该类标记为 PHP 属性:

现在你可以在结构化输出类中使用该规则:

最后更新于