首页 / 文章

本体结构与模型规模:图形设计会给AI智能体带来怎样的成本?

一个保险知识图谱的三种无损结构如何改变了Azure Cosmos DB上小型和大型模型的准确率、工具调用次数、token数量以及成本。

发布者:REACTAPP.TOP阅读约 30 分钟6885 词

来源: Your Agent Is Not Confused, Your Ontology Is

当某个智能体表现不佳时,大多数团队首先想到的解决办法是使用更大的模型。这种方法确实有效,但其成本大约是优化图结构方法的14倍。这一数据来自一项实验:用三种不同的方式对相同的事实进行建模,让Microsoft Foundry上的单个智能体使用四种遍历工具,且没有其他获取答案的途径。所衡量的是每个问题对应的知识结构成本。

上图展示了同一事实库的三种布局,共计2,435条事实。每个面板都是从实验数据中提取的真实子图,显示了每种本体如何呈现完全相同的这三项保险索赔的关联结构。在扁平布局中,这些结构被包含在属性之中,因此几乎没有任何关联。在标准化布局中,每条事实都成为独立的顶点:没有遗漏任何内容,但也没有任何元素被赋予名称。在带形状的布局中,每个实体都有明确类型,每条边都有对应名称。在这三种布局中,代理、模型和数据库保持不变,唯有形状会发生变化。

首先谈谈数据问题。其中的所有人物、公司、地点以及保险公司都出自带有固定种子的虚构词表,因此没有任何内容对应现实中的实体。相关数据来自瑞典中部的实际运行环境。推理过程在专用的 Microsoft Foundry 环境中完成,知识存储在 Apache Gremlin 账户对应的 Azure Cosmos DB 中,每次工具调用实际上都是 Gremlin 查询对实时图谱的检索。最终共生成了 480 个代理场景、430 万个标记,总成本为 8.09 美元。若让工具直接读取生成器文件而非数据库来对同一数据集进行初步处理,成本则为 7.74 美元,这种处理方式被称为交叉验证运行。所有报告的数值均来自 Cosmos 平台上的运行结果,只有当两次运行共同显示出单次运行无法得到的结果时,才会进行交叉验证。

无人愿意升级的层级

那些推出智能体的团队往往会重复同样的流程:智能体在本应处理的问题上出错,于是有人建议使用更复杂的模型。这样一来,费用翻倍,错误又转移到其他问题上,最终得出的结论仍是智能体尚未准备好。

几乎没人会真正探讨核心问题:智能体所掌握的知识结构是怎样的。暂且抛开事实不谈,不妨思考一下:调整员在数据结构中是节点还是嵌在JSON数据块中的字符串?连接边是标记为assessed_by还是仅仅related?从理赔申请到保单持有人的路径是需要一次跳转还是五次跳转?

之前的测量工作涉及一个用于做决策的系统以及一个用于固化这些决策的工具。在其他研究中,一个由三部分组成的公开系列构建了持久的知识层,利用其自建的合成保险数据在该知识层上运行智能体,并论证了应将知识视为人工设计的产物而非简单的检索集合。但那些研究缺乏具体的测量数据,而这项实验正好提供了这样的数据。它在智能体进行推理的底层添加了一层,并提出了一个很少能得到数值答案的问题:在模型、工具、提示词和事实保持不变,仅改变本体结构的情况下,准确性、工作量和成本会如何变化?

第一个答案引发了质疑,因此人们用规模更大的模型重新进行了整个网格的计算,以验证资金是否真的能超越结构不佳的图表。答案是肯定的。有趣的是价格数值,以及它所反映的值得构建的图表结构。与之前一样,每一个结论都需要有依据。

同一真理的三种形态

测试领域是一个包含投保人、保单、保障范围、理赔申请、理赔员、维修服务提供商、付款信息以及不同区域的保险业务数据库。通过一个初始脚本一次性生成了所有内容,最终得到了507个实体对应的2,435条标准事实,全部为虚构数据。

基于那个事实库可生成三种本体。将它们称为三个数据集是错误的;它们其实是同一数据的三种表现形式,都遵循同一条规则:每种变体都必须在不增不减的前提下重新表述这些事实。为确保这一规则得到遵守,有一个脚本会遍历所有构建好的图结构,重新生成事实,并验证结果与原始数据完全一致。如果某个变体比另一个多知道或少知道一条事实,那么这场比较就会变成对数据覆盖范围的测试。代码仓库的持续集成系统会在每次向主分支推送代码或提交拉取请求时运行此验证,同时检查已提交的数据是否与种子数据逐字节完全匹配,只有两项检查都通过,实验结果才有效。 有一个公平性需要注意:扁平结构与形状化结构的构建方式是在未参考事实集的情况下编写的,因此它们的验证具有实质意义;而标准化图则是直接从事实中编码而来,故在本质上比通过证明得到的结果更接近事实。

许多团队最终首先推出的都是扁平结构,它仅使用两种复杂的节点类型。每个保单持有人节点会将保单及其保障范围以JSON格式存储在一个属性中。每个理赔节点也以相同方式存储其理算员、服务提供方及付款信息。一种通用的边类型related将保单持有人与理赔记录关联起来,这就是整个架构的构成。所有信息都存在,只是被隐藏起来了。

规范化则朝相反方向发展,且并非虚假对立面,因为教科书会对其大加赞赏。它将一切实体化:实体变为仅包含其类型的纯Resource节点,每个属性变为通过通用has边连接的Attribute节点,而每一种关系则变为带有subject和object边的Relation节点。在纸上它看起来完美无缺,但实际上要了解任何内容都需要经过四层转换。

Shaped 的设计是以真正会使用它的用户为中心的。节点类型具有明确的粒度,每条边都有方向、类型以及有实际意义的名称,例如 filed_against、assessed_by 或 settles。策略通过 held_by 指向被保人,而这个名称被有意重复使用,原因在于有九十条派生出的 held_by 边直接从理赔申请连接到其被保人,从而将理赔申请与被保人之间的路径压缩为单跳。重复使用该名称是出于刻意设计,因为这种关系从两端看都是相同的,代理人无需额外的词汇表。这九十条边带有 derived 标志,不提供任何新信息,也不计入无损性证明的范围内,因为它们只是对已存在事实的运算。

图1以三种形式展示了单一关系,即一项索赔及其负责评估的理算员。扁平结构将理算员直接嵌入索赔的JSON属性中,几乎不建立其他关联。标准化结构则为该关系单独设置一个节点、两条边,以及每个事实对应的独立属性节点。结构化结构仅对边进行命名便止步,其说明部分还解释了为何存在这种单独的简化方式。重建脚本验证了这三种结构所包含的事实数量完全相同,均为2,435条。

节点数量可预判数据的规模。在扁平结构中,一个事实集需要130个节点;在结构化结构中需要507个节点;在标准化结构中则需要2,942个节点,每增加一个节点都意味着处理流程中可能需要多一步操作。

具体实体比描述更能体现差异。以那些因结果而广为人知的保单为例,每种变体实际上都是对其独立存储的:

图2通过图形渲染脚本直接从已提交的本体文件中获取策略P-7009,这些文件正是被加载到Cosmos中的那些,因此它能准确显示智能体行走的路径。Flat将策略以字符串形式存储在投保人属性中:它存在,但并非节点,也无法被直接访问。Normalized则将其存储为单纯的Resource节点,其各个属性都位于两跳之外的独立节点中。Shaped则包含带类型标注的节点,其属性附着在节点上,并有带名称的边从节点延伸出去。在这三种情况下保费都是相同的,但它与问题节点的距离却各不相同。

在 Apache Gremlin 所用的 Azure Cosmos DB 中,每个图形都位于独立的图容器中,代理程序正是对这些容器进行遍历;下面的所有工具调用都会转化为对实时图的 Gremlin 遍历。生成器负责输出事实库,加载器则将其写入 Cosmos DB,同时加载器还会对自身进行校验:顶点和边的数量必须与源数据一致,否则会报告不匹配情况,而不会在之后发现图构建不完整。

同一个数据库、同一层工具以及相同的索引默认设置使得这些设计具有可比性,同时也让它们能够被清晰地查看。属性图不会隐藏任何信息——只要询问它所掌握的内容,得到的回答就是设计本身。

表1统计了从图形文件中提取的、属于每种架构的2,435条相同数据。扁平型结构的顶点数多于边数,且有五个顶点没有任何边与之相连。标准化型结构则完全均匀且没有文字信息。形状化结构则是连通性最好的,其标签使用了该领域的专用词汇。

回到扁平型结构。该结构中的边数少于顶点数,且有五个节点没有任何边连接;这些节点对应的是没有提出索赔的保单持有人,在这种设计下,世界上没有任何其他元素能与它们关联。这实际上是一个存储着几乎算不上真正图结构的图形数据库。虽然结构依然存在,但它已被拆解为每个顶点8.2个属性,因此其行为更像文本而非拓扑结构。最终结果取决于这一设计选择,而图形数据库将其视为事实而非观点来呈现。

标准化后的图表与之对应。在三种图表中,这是最为均匀的一种:每个顶点大约对应一条边,没有孤立元素,每个节点有1.6个属性,因为实体化过程将每个事实转化为相同的三种基本构成要素,且这些要素共出现了2,942次。该图表中结构极为丰富,但缺乏词汇元素,仅通过三种顶点标签和三种边标签便能涵盖整个保险业务。

每个顶点有1.36条边的结构化图表连通性最佳,它拥有八种顶点标签和九种边类型。当询问每种图表包含哪些类型的内容时,差异立刻显现出来:

g.V().groupCount().by(label)
  • 扁平结构仅包含索赔(90)和被保险人(40)信息。
  • 标准化报告包含资源(507)、属性(1834)和关系(601)数据。
  • 结构化列表包含八个领域标签:承保范围216、索赔90、保单75、付款59、被保险人40、服务提供商12、理算师10以及地区5。

另一个查询则是按标签统计保单数量:

g.V().hasLabel('policy').count()

表2中将一个查询与三个答案放在一起。这两个零分别代表不同类型的失败。在扁平图中根本找不到对应策略;在规范化图中虽然存在策略,但不会主动显现。扁平图丢失了实体,而规范化图保留了实体却丢失了词汇表,因此只能通过逐步探索才能找到策略,无法直接通过名称定位。这一切都与数据的存储方式无关:三种架构、一个数据库、一个查询。

在为实际问题定价时也会出现同样的不平衡现象。针对C-31020号索赔对应的保单,投保人居住在哪个城市?所有图表都给出Larkfield作为答案,因为所有图表都包含相同的事实,只是到达该答案的路径有所不同。在带结构化的图中,通过衍生边可以缩短路径长度:

# shaped - the derived shortcut collapses the path
g.V().has('number','C-31020').out('held_by').values('city')

平面化且标准化的图表需要的是这个:

# flat - one hop, but only because claims and holders are the only two things
g.V().has('number','C-31020').in('related').values('city')# normalized - the same answer, five steps and two unwrappings later
g.V().has('value','C-31020').in('has')
     .in('subject').has('kind','filed_against').out('object')
     .in('subject').has('kind','held_by').out('object')
     .out('has').has('attr','city').values('value')

Flat只需一步即可完成处理,因为在该模式中,声明和持有者恰好是仅有的两种类型。而规范化处理则需要五步以及两次解包操作。代理永远不会自行组合这些查询;它会通过一次工具调用来逐步寻找路径,这正是该实验的目的所在。尽管如此,这些查询仍能揭示所发现的内容及其数量。

图3显示,在Cosmos DB数据浏览器中的三个图中运行的查询结果是相同的。无论某个图提供两个标签、三个元标签,还是以自身特有的方式表示领域,这些模式所存储的并非不同的数据,而只是同一数据集的不同表现形式。

图4在每个图中选中索赔记录C-31020,让数据浏览器绘制其关联节点。在平面图中,仅有一个节点可通过标记为related的边被访问,该节点为一名保单持有人。理算员AJ-09和保单PL-043显示在属性面板中,但仅为文本形式,因此代理人无法直接定位到它们。在规范化图中出现了八个节点、六个属性和两种关系,这些均没有使用领域语言命名。在结构化图中,有三个节点使用了命名,分别为filed_against、assessed_by和held_by。一个索赔记录,一个数据库,三种距离关系。

工具:四种工具与一张收据

有意将智能体规模保持在最小,因为它并非测试对象。它只是一个简单的函数调用循环,针对 Microsoft Foundry 模型部署运行,其连接方式遵循 Foundry 文档中关于通过 Chat Completions API 使用工具的描述。系统提示词是固定的,每个问题最多可调用 sixteen 个模型(超过此数量则终止该会话),并且需要四个工具来完成任务,这四个工具在三种本体论中的签名完全一致。

图 5 展示了完整的计算资源占用情况:一个 Microsoft Foundry 资源中包含两个模型部署,agent-small 运行 gpt-5.4-nano,agent-large 运行 gpt-5.5,两者都属于 Global Standard 类型。名称和版本取自仓库中的基础设施模板,因此这些数据背后并无隐藏的其他计算资源。

这四个工具分别是:

  • find_nodes 按子字符串搜索节点属性和编号,最多返回二十个匹配结果
  • get_node 读取某个节点的类型及其属性
  • traverse 返回一个节点最多三十个相邻节点,可按边类型和方向进行筛选
  • describe_edges 汇总哪些边从节点出发或进入节点,以及每种边的数量

在底层实现中,每个工具都会在 Cosmos 上转化为 Gremlin。get_node 和 find_nodes 各需一次遍历,即一次点读取和一次扫描;而 traverse 和 describe_edges 则需要三次遍历,因为它们首先需要确认节点是否存在,然后再依次遍历其出边和入边。代理程序并不负责编写这些逻辑,它只需请求某个节点或邻居信息,就会收到结构紧凑的 JSON 回复,这正是图存储系统中常用工具的响应格式,同时也让查询语言与模型相分离。

遍历图结构是获得答案的唯一途径。该智能体既不会查看模式定义,也不会编写Gremlin代码;每当图中缺乏问题所需的元素时,它就会被指令要求用NOT_MODELED这一确切值作为回答。大小写很重要:结构不良的图会通过额外的工具调用来应对扩展需求,而非生成一个庞大的响应,这与实际工具使用情况一致。16轮的限制指的是对话轮次而非工具调用次数,且一轮中可以同时请求多个工具,因此最繁忙的一轮在16次轮次内就完成了60次工具调用。

在与真正的图数据库竞争时,我总结了三条实用经验,它们都表明必须重新设计架构。Cosmos不支持多语句脚本,因此每次请求都需进行一次遍历,吞吐量只能通过并行执行多个请求而非批量处理来提升。严格的60秒请求超时限制意味着g.V().drop()无法一次性删除数千个顶点:操作会在中途终止,留下未完全删除的图结构,因此必须分批清除。无服务器层级也存在吞吐量上限,导致40个同时进行的写入操作会引发超时,这也是为什么加载器和代理工具层都会采用退避策略进行重试。这些都不是什么特别复杂的问题,但它们恰恰体现了空闲状态下的图存储系统与高负载状态下的系统之间的差异。

无需裁判的评分

在评分环节,对智能体的评估标准往往会放宽,因此这类问题受到了最多关注,而且全程没有出现任何大型语言模型作为评判者。这40道题目被分为四个各含10题的类别:仅需查询单一事实的题目、需要两到三步短距离推理的题目、需要较长路径或对子图进行聚合处理的题目,以及无法解答的题目。脚本会根据事实库生成这些题目,并从原始事实中推导出每个正确答案。评分过程十分机械化:数字必须与计算结果一致,字符串必须包含该结果,而对于无法解答的题目,只有当智能体明确表示无法回答时才计为正确。没有本体自行标注,也没有模型互相评判,正确性完全基于对比而非主观意见。

由于智能体只能通过其四种工具来行动,因此每个答案都会附带生成该答案的所有调用记录。在之前的路由器测试中,model字段起到了记录作用;而在这里则是路径记录。正确的答案可以逐步骤追溯,而失败则能明确显示智能体在哪个环节失去了控制。

图6展示了系统架构。一个初始事实库为三个无损结构提供数据,这些结构会转化为Azure Cosmos DB中用于Apache Gremlin的三个图容器;另一个独立分支则为预言机提供数据,预言机会根据相同的事实推导出每个正确答案。智能体仅能通过这四种工具访问这些图,每次调用都会执行一个Gremlin查询。工具、循环和问题保持不变,只有结构会变化,每次运行都会生成记录:工具调用记录、令牌使用情况、延迟时间以及预言机的判定结果。

这种无法回答的查询类型值得单独讨论。它提出的十个问题要求获取事实数据集中根本不存在的信息:电话号码、电子邮件地址、天气状况、车辆识别号码。正确的回应应是图结构无法提供这些信息。而那些编造边关系而非承认图结构中不存在此类信息的智能体,正体现了这类系统中最危险的故障类型,可惜几乎没人会对这种故障进行衡量。

遍历成本

主要实验针对实时的 Cosmos DB 图表展开,推理过程在瑞典中部的专用 Microsoft Foundry 环境中进行。该实验涉及三个本体、四十个问题以及三次完整运行,期间仅保持一个小型模型不变,最终生成了360个智能体场景、310万个标记,耗时70美分。每次工具调用都对应一个 Gremlin 查询。稍后描述的第二个实验则使用更大的模型重新运行,产生了120个额外场景,耗时7.39美元。有一个存储脚本根据记录的支出数据计算出上述所有数值,没有任何一项是手工输入的。

表3总结了该实验的测试结果:使用小型模型,进行三次运行,共360个场景,每次工具调用背后都有一条 Gremlin 查询。每行中绿色标记代表最佳结果。资源相关行故意未着色,因为在这四项指标上其数值均为最低,而且正如后续章节所示,这种低资源消耗的部分原因在于它需要为那些根本无法提供的答案支付成本。

首先从表格中信息最少的第一行开始分析。Shaped模型正确回答了84.2%的问题,Flat模型为78.3%,Normalized模型为59.2%。但在三次其他条件相同的测试中,这三种模型的准确率分别波动了0.075、0.150和0.075,因此Shaped与Flat之间6个百分点的差距其实属于随机误差范围,仅通过三次测试无法判断两者在整体准确率上的差异。而Normalized模型相比其他两者有25个百分点的领先优势,这一差距足以排除随机误差的影响。

这听起来比实际情况要弱。整体数据之所以模糊,是因为它将那些差异极大的区间进行了平均,而这种差异本身就是关键发现:

表4说明了这种汇总数据存在的问题。不同模型的表现并非在所有区间都有细微差异,而是会在各个区间出现明显分歧,而且每个区间对图表的要求也各不相同。

首先看看单次查询的情况。成型评分为0.967,平面评分则为0.533,两者相差43点,而对应的逐次噪声分别为0.100和0.200,因此该信号是真实的。在两次及三次跳转的查询中,评分均为0.967。在最复杂的场景下,噪声分别为0.300和0.400,根本无法判定哪个方案更优。

因此这两种方式并非一种优于另一种。它们在不同的情况下表现不佳,将两者合并为一个数值会掩盖其中有用的信息。当需要寻找目标时,平面方法会不断失败。而当智能体已经取得立足点只需继续前进时,平面方法的表现与设计好的图结构相当。

标准化方法则呈现出不同的情况,如其各区间所示:查询时的评分为0.867,由于每个实体都是真实的顶点,因此优于平面方法;而随着行走步数的增加,评分则降至0.467和0.133。它能找到任何目标,但无法完成任何任务。

每种方法的缺陷

这两种智能体的失败方式及失败位置各不相同。每种智能体都回答了30道问题,共3次,总计90集;按失败类型对错误进行分类可以揭示其背后的机制。

表5汇总了这90集中的所有错误情况。Normalized在轮次预算耗尽后停止运行;而Flat则会在数据库本可给出答案的问题上过早且自信地停止。

Normalized在90集任务中约有四分之一(22集)因预算耗尽而停止,此时它仍在移动中;Flat则很少如此,它总是早早且自信地停止,甚至拒绝回答数据库中已有答案的18道问题。一种智能体是因过度消耗能量而停止,另一种则是主动选择退出。

这次彻底的失败更为严重,相关痕迹揭示出一种无人预料到的机制。以下是两个真实案例。两者都要求为保单P-7009支付额外费用,不同之处仅在于这些工具背后所采用的架构不同:

flat                                       shaped
find_nodes "P-7009"          -> 1 hit:     find_nodes "P-7009" type=policy
   policyholder:PH-05 "Ivo Renner"            -> 1 hit: policy:PL-009 "P-7009"
find_nodes "7009"            -> 1 hit      get_node policy:PL-009
find_nodes "P-7009" type=policy       -> 0     -> premium 750
find_nodes "P-7009" type=policyholder -> 1 hit
ANSWER: NOT_MODELED                        ANSWER: 750

在结构化图中,只需两次查询即可。通过编号查询保单,获取一个保单节点,从中读取保费信息,任务完成。

而扁平化图则呈现出不同的情况。第一次查询返回了一个节点,第二次也是如此。第三次查询使用了type=policy条件,但由于该模式中不存在该标签,因此没有找到结果。第四次查询使用了type=policyholder条件,最终找到了对应节点。按类型来看,代理确实找到了包含答案的准确节点,却仍宣称数据缺失。

该保险单就在那个顶点中,处于某个属性里,只需一次get_node调用即可获取。在10个查询失败的案例中,未经过滤的搜索15次找出了包含该保险单的顶点,但get_node函数从未被用来访问过它。该顶点带有“伊沃·伦纳”这一标签,指的是一个人。在其余查询失败的案例中,该标签属于另外两位投保人之一,而非保险单本身,而人名也无法提示所查询的保险单就在其中。

这就是将实体隐藏起来的特殊风险,而图数据库则能将其定位出来。这些数据虽然可以获取,但却无法被识别。它们已被建立索引,能通过查询返回,也存在于代理的上下文中,但却无法用任何名称来对应所使用的查询条件。

标准化处理在开放环境中进行时效率极低且成本高昂。读取一个属性就需要遍历一个Attribute节点,而追踪一种关系则需经由Relation节点绕行。“令牌数”一列显示了相应的费用:每个问题需要13,701个令牌,而结构化数据仅需7,176个;每次工具调用需要12.15个令牌,结构化数据为7.24个。在120个测试案例中,有25个案例达到了16次转换的限制,结构化数据为3个,平面数据为2个,其中难度最高的案例得分仅为0.133。该图结构完备无缺,只是智能体在完成句子之前就耗尽了精力。

最便宜的选项确实是最廉价的,但这并非褒奖之词。普通模式每百道题的费用为0.109美元,而复杂模式则为0.165美元;按准确率计算,普通模式仍更划算,每百道题正确答案为0.14美元,而复杂模式为0.20美元。从成本角度而言,普通模式确实更经济。但价格无法体现它拒答的18道题这一事实。提前终止测试的成本很低,但低额费用并不能带来实际节省,而仅通过成本指标是无法看出这一点的。

拒答悖论

在考虑了可回答的题目后,表现最好的与最差的在“无法回答”类别中的位置发生了互换。普通模式正确拒答了所有30道无法回答的题目,是表格中唯一获得满分的选项。复杂模式的准确率为0.933,标准化准确率为0.900,它们的错误原因都是轮次用尽,而非故意编造答案。

单独来看,那一行呈现平稳状态。在虚假拒绝次数这一指标旁,情况则相反:拒绝率最高的类型放弃了18道本可回答的题目,而拒绝率最低的类型则放弃了13道。平稳状态并不更擅长识别“无答案”情况,反而倾向于直接表明这一点,而这种在无答案题目上占优势的倾向在有答案题目上则会失效。如果没有与之配套的答案可能性指标,拒绝率指标就会导致生成最不可靠的图表。

与设计理念相悖的发现

其中一个结果与实验所倾向的结构化设计相悖,而第二次测试进一步凸显了这一问题。在结构化设计中仅存在一个派生快捷方式:held_by,它可将理赔申请直接关联到其被保险人。在“理赔申请与被保险人所在城市”的关联度评估中,该设计的得分为0.83,而标准化设计的得分仅为0.33;而采用扁平化设计的得分则达到了0.92,且无需任何快捷方式,因为在那种架构中仅有理赔申请和被保险人这两类元素。那种没有边缘结构的方案能取得更好成绩,这一结果显然不能归功于边缘结构。

更糟糕的是,缺失的快捷方式在预期位置造成了影响。在所谓设计良好的图中,跨保单计算不同覆盖类型的得分仅为0.17,而在将它们归为同一可读属性的扁平结构中则达到0.67。保单索赔的总支付额得分则为0.33。在子图聚合方面,所倡导的设计方案落败,输给了被称为“有缺陷”的设计方案。反规范化并非对良好设计的妥协,而是其组成部分;而那种特定结构的图在需要处理大量数据时,却过于吝啬地应用自身的原则。

用更大模型来摆脱困境

随后,整个网格在规模更大的模型上进行了第二次运行,而核心问题的答案来自于该模型出乎意料的运行表现。最初人们认为,在结构良好的图上运行的小型模型会优于在结构较差的图上运行的大型模型,但事实并非如此。只有那些有答案的问题才会被纳入比较,因此对于无答案问题的拒绝并不会让任何图结构显得更好。每行小型模型的数据包含三次运行共90个样本,而每行大型模型的数据则来自单次运行,共30个样本。

表6仅考虑有答案的问题,因此恰当的拒绝也不会让那些容易拒绝问题的图结构显得更好。

大型模型能够轻松读取隐藏的属性。它回答了全部三十道需要回应的平面图结构问题,包括那些涉及被模式转换为文本的实体的问题;而曾让小型模型陷入困境的十八次虚假拒绝情况也消失了。真实的结论并非大家所期望的那样。

结构不佳的本体也可以被利用。其成本约为每道问题费用的十四倍:在平面图结构上运行的大型模型每百道问题的成本为1.90美元,而在结构化图上运行的大型模型则为13美分。如果保留平面图结构,仅升级其下的模型,那么费用将是相同小型模型在平面图结构上运行时的二十倍。

这一结果因其所蕴含的意义而比预测结果更有用。在采用边界模型和可回答问题的情况下,形状问题不再属于正确性问题,而变成了成本问题:平面模型和有形状的模型都能回答全部三十个问题,只有费用将二者区分开来。而在小型模型中,形状本身就决定了正确性。因此,精心设计的本体所提升的质量,不如其带来的运行低成本模型的能力。平面图将知识层与模型预算绑定在一起,只有当有足够大的模型能够持续处理每个问题时,这种绑定才能无限期地发挥作用。

在全部四个评估维度中,排序结果比仅考虑可回答问题的视角更为清晰。在大型模型下,有形状的模型在所有维度中都取得了完美的1.000分,包括那些无法回答问题的情况在内;平面模型则达到了0.950分,标准化后的得分为0.825分。资金只能在一定程度上确保正确性,而费用问题则始终没有得到解决。

交叉验证带来的警示

这次交叉验证(使用相同的网格、相同的问题,工具读取文件而非Cosmos)得出了项目中最为令人担忧的结果,而问题就出在那个图形上。当被问及事件发生当天的天气状况时——本体明确并未对这一信息进行建模——该智能体却回答“冰雹造成的损害”。它找到了索赔记录中的原因属性,并将其当作天气状况来呈现。当时记录显示,这种最危险的设计缺陷源于单次运行中的一个案例,仅属于观察结果而非实际测量数据,因此无法作为制定规则的依据。

在真实基础设施上重新运行是正确的选择。在测试中,有特定形状的图表正确地拒绝了所有十个大型模型无法回答的问题,而平面形状的图表则对同一问题给出了“冰雹”这样的答案。模型、问题以及陷阱都完全相同,只有被捕获的形状不同。

因此,这一发现并不意味着复杂的图表会引发编造答案的行为。无论模型存储在何处,只要其“原因”属性值为“冰雹造成的损害”,任何被问及天气问题的模型都可能给出此类答案,而且每次运行中被捕获的形状也会不同。这一结论比最初可能得出的结论更为有限,也是现有证据所能支持的。这也意味着这种风险与图表的形状无关:如果某个图表包含的字段看似是某个问题的答案,但实际上它并未回答该问题,那么总会有某个地方的模型给出这样的答案。

两种模型下的标准化形态

两种模型的标准化损失值均有所上升。在小型模型中它排名最后,而在大型模型中,其在可回答问题上的得分仅为0.867,每百次查询的成本高达9.31美元,几乎是同一模型平面图谱成本的五倍,且共有七次出现轮次耗尽的情况。更大型的模型在实体化处理方面的表现也并无改善,因为它的问题从来不在理解能力上,而在于距离问题:每个问题需要调用15次工具,而形态化模型仅需8.3次,而且后者从未出现过误解情况。

规范化处理并非在所有情况下都处于劣势,而那些例外情况恰恰最具启示意义。在仅基于单一因素的查询中,规范化处理的得分为0.867,而扁平化处理的得分仅为0.533;在那两个使扁平化处理失效的查询中,规范化处理的表现明显更优:保险费相关查询的得分为0.83,而扁平化处理仅为0.17;服务提供商专业性相关查询的得分为0.83,扁平化处理则为0.33。实体化处理虽然成本极高,但却不会隐藏任何信息——每个实体都是一个节点,因此都可以被找到。

这就是该论点的总结:每种有缺陷的处理方式都只保留了问题的一半,而舍弃了另一半。扁平化处理保留了距离信息,却失去了可寻址性;规范化处理保留了可寻址性,却失去了距离信息。每种方式都在其保留的那部分功能上具有优势,而在另一部分功能上则毫无竞争力。

“Shaped”并非两者之间的折中方案。在高于“flat”水平的评分区间内它得分为0.967,在高于“normalized”水平的评分区间内也得分为0.967,因此它摒弃了这种折中。这正是它的优势所在,而单一的混合准确率数值却完全掩盖了这一点。

与真实数据库的延迟对比

延迟是交叉验证无法提供的衡量指标。对于文件处理,每次调用的时间在相同操作下波动极大,同一变体在某次操作中每调用可能需要1.17秒,而在另一次操作中则需4.21秒,因此由于服务差异超过了本体论差异,相关数据并未被记录。而在与Cosmos的对比中,情况则相对有序,原因则有些出乎意料。

表7显示,不同形状之间的每题处理时间差异明显,且同一形状内的时间保持稳定,但三种工具的每次调用时间却完全相同,因此该表实际上是以秒为单位呈现的工具调用次数。

在任意一种变体中,时间差最大为7秒,而从平面结构到标准化结构的时间差则接近50秒。一个标准化问题的处理时间是一个平面问题的2.5倍。最后一列数据则显示了实际结果:无论架构如何,每次调用这三种结构所需的时间都大致相同,介于6.2秒到7.4秒之间。因此这并非一项独立的发现。数据库保证了一致性,因为使用Cosmos进行数据传输的时间是可预测的,而使用本地词典则无法预测,也正是这一点使得相关数值能够被记录下来。

由此会产生一个实际后果。由于每次调用的延迟大致恒定,本体结构集不仅决定了令牌费用,也直接决定了响应时间,而且可以在构建之前通过计算跳数来估算这一时间。

原则及其依据

关于本体设计的论述通常会将相关原则视为主观偏好问题。下文中的大多数原则都附有为其命名的编号,而没有编号的原则则会明确说明。

任何可被查询的对象都必须是顶点。如果在门上刻下一条原则,那就让它是这条。该平面图将每项保险费及服务提供商的专长以索引形式存储在同一个数据库中,与其他所有数据一同存放,而小型模型几乎无法检索到这些信息。保险费有17%的检索成功率,专长为33%,而结构化处理方式的成功率则分别为100%和83%。整个范围的结果都在0.533到0.967之间。将某个实体隐藏在另一个实体的属性中并不会增加其被找到的难度,只会让针对它的合理查询以另一个名称返回,而系统会将其视为该实体不存在的证据。交叉验证则增加了一个条件,因为边界模型能够将所有这些信息都提取出来。隐藏并非绝对的障碍,只不过是在模型层级中需要付出的“代价”罢了。

粒度本身就相当于一种预算,而实体化操作会迅速耗尽这笔预算。为保持模式纯度而新增的每个节点都会在每次访问时产生额外开销。与结构化数据相比,规范化后的数据在单事实查询时需要3.7倍的工具调用次数,在短路径遍历时需要2.3倍的调用次数,在长路径查询时则需要4倍的标记数量;在120次测试中,有25次达到了转向限制,而结构化数据仅为3次。另一种每输入一个标记成本高出25倍的模型,使其在回答问题时的性能从0.489提升到了0.867。这确实是个显著的提升,但其成本为每百次查询9.31美元,几乎是相同模型在结构化数据处理方式下的5倍。无论预算多少,距离成本从来都不低。

入口点即架构,且严重依赖模型表现。每个问题都以某个名称或数字开头,首个工具调用的返回结果决定了智能体是直接开始处理还是先进行猜测。在小型模型中,10%的规则化场景、26%的扁平化场景以及53%的标准化场景中,该调用会返回空结果,这是因为搜索结果指向的是Attribute节点而非实体节点。而对于前沿模型而言,无论场景类型如何,该调用从不返回空结果。因此,浪费的初始步骤不仅是一种图结构特性,更是较弱模型遇到其未预料到的入口点时所会出现的情况。应为实际部署使用的模型构建相应的入口,而非仅用于测试的模型。

有意采用非规范化处理方式,当结果与预期不符时需予以承认。有一种衍生的快捷方式 held_by,原本期望在“从索赔到持有者”的路径上发挥作用。在该路径上它的得分是0.83,而规范化处理后的得分仅为0.33;但在不使用快捷方式的相同问题中,直接处理的得分却是0.92,因此无法给予相应评分,也未进行基于边界条件的清洁测试。恰恰是缺失的那一项快捷方式反而提供了更多启示。在统计持有者保单的覆盖类型时,设计良好的图结构下得分为0.17,而直接处理方式下得分为0.67,这两者仍可归为同一类可理解的属性。对于子图聚合而言,原本被推崇的设计方案反而输给了被标记为有缺陷的方案。选择快捷方式是设计环节的决定,工作量则能显示哪些快捷方式是必需的,而在这里显然选择了错误的方案,数据也证明了这一点。

限制了数据扩散范围。搜索结果上限为20条,遍历次数上限为30次,这意味着过度连接的节点只会产生可统计的额外调用次数,而不会导致一个庞大的响应结果。由于没有设置无上限模式,因此节省的成本尚不确定。可以确定的是,如果没有这些限制,成本会隐藏在响应大小中,而调用次数指标则无法反映这一点。

要让缺失部分清晰可见,并如实评分。应将那些无法回答的题目视为设计要求而非测试陷阱,但需将其与可回答的题目放在一起查看。Flat在拒绝回答18道本可作答的题目时,得分仍为完美的1.000。Shaped拒绝回答的题目最少,它错过的两道无法回答的题目最终是选择放弃而非编造答案。一个良好的本体论应能让“我们不建模此内容”这一表述既可被理解又符合事实,而评估体系也需要这两方面来区分那些清楚自身局限的图结构与那些无法识别自身内容的图结构。

名称即 API。智能体读取边缘节点的名称,就如同开发者阅读函数签名一样;在本实验中,我们刻意将命名与结构合并为一个名为“设计”的变量。这一原则本身并无任何数据支持。显而易见的下一步就是将二者分开,明说这一点总比夸大实际测量结果要好。

这不是什么

这并非对图数据库的基准测试。这三种数据结构共享同一个 Cosmos DB 账户、同一套工具层以及相同的索引默认设置,因此存储条件是恒定的而非可变的,也没有任何内容将 Cosmos 与其他图数据库进行比较或对其进行优化。它同样不认为仅靠遍历就能让生产环境中的代理获取所有数据,因为那些没有明确查询入口的模糊查询需要通过搜索来解决;测试结果展示了在哪些情况下单纯遍历可行,而在哪些情况下则不可行。它并未反对事务系统中的规范化处理,因为对于这种按每次查询付费的代理用户而言,规范化的数据结构在这里并不适用,但并不代表规范化本身是错误的。此外,这也不是对不同供应商产品的比较:Microsoft Foundry 是恒定因素而非变量,该方法同样适用于任何具备函数调用功能的平台。

在循环中使用数据库会改变结果吗?这需要一个答案,而非肯定答复。在开展实际测试之前,同样的四种工具在Cosmos环境中以及生成器输出的文件上分别被使用了两次,随后将记录下的工具调用结果在两种环境中重新执行:共计3,056次不同的调用,涵盖了测试中出现的所有独特的工具与参数组合。两种实现方式在所有情况下都给出了完全相同的答案。数据库仍然有其作用——它会增加延迟和请求量,而且基于Cosmos的环境相比基于文件的环境大约需要多4%的代理步骤,其中大部分额外的开销都体现在规范化图上。但代理得到的结果源自本体结构,而非其下层的引擎,而这正是比较所需要了解的全部内容。这些重放过程以脚本形式保存在仓库中。

该工具的局限性

从路由器相关研究中延续下来了一些注意事项。在一个合成领域中使用的40个合成问题仅构成一个小型测试工具。由于这些形状都属于典型范例,因此对比结果十分明显,而实际应用中的本体则介于两者之间,这也是为何最终测量的是端点值。小型模型共进行了三次完整测试,其噪声水平在全文中均有提及。大型模型仅进行了一次测试,因此只有其在两种形状上全部答对(30题全对)的结果才比较可靠。该测试网格中缺失的两道题只能被视为个别案例,无法以此作为论据。此外还仅比较了一个小模型和一个大型模型,因此两者之间的差异仍未被测量。

在发布前对代码进行审计时发现了该工具中的两个缺陷。其一:当请求的边类型在图中不存在时,traverse函数会返回一个空的邻居列表,这与真正没有邻居的节点无法区分。在各项测试中,该工具共进行了112次此类调用,在标准化图谱中22次错误拒绝中有9次包含这种情况;分析脚本会将这两者都计入统计。由于“shaped”进行了最多的此类调用但拒绝了最少的查询,因此总体差异依然存在。不过,工具对于“不存在此类边类型”的情况回复“此处无内容”会带来混淆,更合理的处理方式应是报出现有的边类型。其二:无损性证明是通过对重建的事实进行比较来实现的,因此无法识别那些本身不包含任何事实的边,也就是“flat”中的连接边以及“shaped”中生成的快捷路径。 现在会进行第二次检查,根据这些边所陈述的事实来验证它们,从而发现每一条边是否存在被删除或指向错误的情况。这些实验在第二次检查之前就已经开展,因此在运行时并不存在这样的保障。

结构即系统提示

人们在模型输入的文字上投入了大量精力,却几乎不关注其背后知识结构的形态。对于使用工具的智能体而言,本体论便是一种提示:它规定了世界允许的操作方式,以节点类型和边名称的形式呈现,并且每次只读取一次工具调用指令。设计时需以实际存在的用户为对象。

相关支持材料都保存在实验代码仓库中:事实库、三个本体论、无损性证明、问题集、预言机、智能体以及每项实验的记录。如果有人能以第四种方式对同一事实进行建模,并在那些曾让现有模型失败的题目上取得更好成绩,那将为这些比较增添有价值的参考内容。

关于所使用组件的背景信息,相关参考文档涵盖了适用于 Apache Gremlin 的 Azure Cosmos DB、使用 Microsoft Foundry 模型进行函数调用,以及用于提供成本数据中每个令牌对应价格的 Azure Retail Prices REST API。

相关阅读

  • 您的智能体图应使用 YAML:在启动时编译包含 17 个智能体的 LangGraph —— 小型运行时如何将一个 YAML 规范编译为 LangGraph StateGraph:生成状态、importlib 插件、标签路由器、自适应调用以及会话级节点替换。
  • 利用 DSPy 优化 Terraform 智能体:先构建验证器再优化 —— Terraform 智能体会自行定义架构。首先构建一个确定性的验证器,为智能体设定基准,然后使用 DSPy 和 GEPA 优化其技能文件,从而获得可靠的结果。
  • 为何智能体记忆基准测试会产生误导,以及如何利用自身数据进行评估 —— 公开的记忆排行榜存在有缺陷的答案键和评分标准。应将信息检索与答案生成分开,加入一致性、最新性、弃权情况以及遗忘检测,并跟踪相关成本。