重新思考LLM集成应用的复杂度度量:超越源代码

arXiv cs.AI 论文

摘要

本文介绍了Hecate,这是首个能够量化LLM集成应用中提示层和代码层复杂度的工具。它采用基于霍尔逻辑的Prompt-as-Specification形式化方法,并在开源仓库上评估了52个候选度量,以识别那些能够捕获超出传统纯代码度量的结构广度。

arXiv:2607.01903v1 公告类型:新 摘要:LLM集成应用将自然语言提示与程序代码相结合,其大部分运行时行为源自提示层而非代码本身。然而,现有的复杂度度量仅在代码层面运行,因此完全忽略了这一行为逻辑。我们提出了HECATE,这是首个旨在评估此类应用中提示层和代码层复杂度的工具。HECATE的核心是Prompt-as-Specification,一种受霍尔逻辑启发的形式化方法,将每个提示解释为预期行为的规范。基于已发表的分类学中识别出的25个复杂度维度,该工具生成了52个候选度量。我们针对从18个开源仓库收集的118个组件对每个度量进行了评估,利用源自版本历史的维护活动作为复杂度的经验代理,并丢弃了在考虑代码规模后失去显著性的任何度量。只有十个度量通过了这一测试。其中七个属于我们新引入的集合;这些度量并非衡量单纯的数量,而是统计结构上不同的元素,例如LLM调用点、内存属性和提示模板——我们称之为结构广度的属性。在三个幸存的传统度量中,RFC表现出类似的广度导向特征,而Halstead N和V仅作为规模的残余效应存活;我们的最佳度量表现超过所有这三个。至关重要的是,即使将最强的代码级度量作为协变量加入,提示层度量仍然保持显著性,从而确立了提示复杂度作为一个独立的维度。最后,对跨越六个保留仓库的20个组件进行的最终验证表明,两个表现最佳的度量继续预测维护工作量,支持了它们在训练集之外的泛化能力。
查看原文
查看缓存全文

缓存时间: 2026/07/03 05:46

# 重新思考面向LLM集成应用的复杂度指标:超越源代码
来源:https://arxiv.org/html/2607.01903
###### 摘要

LLM集成应用将自然语言提示与可执行代码交织在一起。其行为的很大一部分由提示层控制,然而所有已有的复杂度指标仅针对代码,使这部分逻辑未被度量。我们提出Hecate,这是首个量化此类应用在提示层和代码层两个维度上复杂度的工具。Hecate基于Prompt-as-Specification形式化方法,该方法根植于霍尔逻辑,将每个提示视为一个行为规格说明。基于已发表分类法中的25个复杂度维度,它生成了52个候选指标。我们在来自18个开源仓库的118个组件上评估所有52个指标,以从提交历史中提取的维护信号作为真实基准,并仅保留那些在控制代码规模后仍具有显著性的指标。52个指标中有10个通过了这一筛选。其中7个是新提出的指标,每个都捕捉了独特的结构要素——如LLM调用点、记忆属性和提示模板——我们将这种质量称为结构广度(而非原始体量)。在保留下来的三个传统基准中,RFC指标具有可比较的广度,而Halstead N和V仅作为弱规模残差存在;我们最强的指标超越所有三者。即使额外控制最强代码指标后,提示层指标仍保持显著性,证实提示复杂度是一个独立维度。在对来自六个未见过的仓库的20个组件的留出评估中,两个最强指标保留了预测能力,提供了泛化性的证据。

## I 引言

大型语言模型(LLM)现在已经足够强大,能够遵循自然语言指令、编写代码,并通过多步骤任务进行推理。因此,开发者越来越多地将它们嵌入真实软件中,其中LLM作为引擎来规划步骤、调用工具并决定下一步做什么。结果出现了一类快速增长的程序,称为LLM集成应用,这类软件将自然语言(NL)提示与可执行代码交织在一起,以执行代码生成、网页浏览和多步骤规划等任务[30 (https://arxiv.org/html/2607.01903#bib.bib11),32 (https://arxiv.org/html/2607.01903#bib.bib12),13 (https://arxiv.org/html/2607.01903#bib.bib13)]。像AutoGPT、MetaGPT[18 (https://arxiv.org/html/2607.01903#bib.bib14)]和browser-use这样的系统在GitHub上总共获得了数十万颗星,而LangChain[6 (https://arxiv.org/html/2607.01903#bib.bib15)]等框架已投入生产使用。

随着这些系统从原型走向生产,它们的复杂度成为一个真正的工程问题。复杂度使得软件成本高昂,因为复杂的程序需要更多更改工作量,包含更多缺陷,且更难调试[2 (https://arxiv.org/html/2607.01903#bib.bib4),25 (https://arxiv.org/html/2607.01903#bib.bib38)]。为了保持这一成本的可视性,工程师依赖复杂度指标。诸如McCabe的圈复杂度[21 (https://arxiv.org/html/2607.01903#bib.bib1)]、Halstead的软件科学[15 (https://arxiv.org/html/2607.01903#bib.bib2)]以及Chidamber–Kemerer度量套件[7 (https://arxiv.org/html/2607.01903#bib.bib3)]长期以来充当着早期预警信号,指引团队关注最需要审查或重构的模块[5 (https://arxiv.org/html/2607.01903#bib.bib5)]。一个好的指标将模糊的风险感知转化为团队可以追踪的数字。

这些指标共享一个假设:它们度量代码,且仅度量代码。实现它们的工具,如Radon[19 (https://arxiv.org/html/2607.01903#bib.bib36)]和Lizard[33 (https://arxiv.org/html/2607.01903#bib.bib37)],读取源代码而忽略其他所有内容。这个假设在LLM集成应用中失效,因为此类应用的许多行为根本不在代码中体现,而是写在提示中。单个提示可以携带条件指令,例如“如果输入模糊,要求澄清”,以及角色分配、工具路由规则和输出约束。这些逻辑塑造应用行为的方式与周围的代码同样重要,然而没有代码指标能够“看到”它。图1 (https://arxiv.org/html/2607.01903#S1.F1) 使这一差距具体化。组件A和组件B包含几乎相同数量的代码,但组件B承载了更多提示逻辑,即条件规则、若干工具路由规则以及组件A所缺乏的结构化输出契约。组件B所需的错误修复提交次数是组件A的三倍,然而传统指标对两个组件的评分几乎相同。没有现有的复杂度指标能够度量这种NL与代码的混合体。

图注图1:两个代码规模相似的组件,传统指标对其评分相同,但我们的指标却能区分。为这些应用构建复杂度指标面临三个难点。❶ 提示缺乏形式化结构。代码有明确定义的表示形式,即抽象语法树和控制流图,复杂度指标在此基础上定义。相比之下,提示是自由格式文本。在度量之前,我们需要一个关于提示包含什么的结构化模型。❷ NL层和代码层相互纠缠。应用的行为来自提示和代码的结合。值通过字符串插值从代码流入提示,模型输出通过解析和工具调用流回代码。复杂度很大程度存在于这种交互中,而非单独某一层。❸ 代码规模占主导地位。先前工作表明,一旦固定代码规模,大多数代码指标就不再预测缺陷[9 (https://arxiv.org/html/2607.01903#bib.bib6)]。在对72项研究的调查中,仅按规模对模块排序就匹配或超越了大多数复杂的预测模型[35 (https://arxiv.org/html/2607.01903#bib.bib8)]。因此,新指标必须证明其携带超越规模的信息,而不仅仅是跟踪规模。

我们提出Hecate¹,一个静态分析工具,衡量LLM集成应用在NL层和代码层的复杂度。Hecate依次应对这三个挑战。针对第一个挑战,它引入了Prompt-as-Specification,一个受霍尔逻辑启发的模型[17 (https://arxiv.org/html/2607.01903#bib.bib9),23 (https://arxiv.org/html/2607.01903#bib.bib10)],将每个提示视为行为规格说明,即一组条件规则、一组全局不变量以及提示依赖的上下文谓词。这为NL层提供了度量所需的结构。针对第二个挑战,Hecate不孤立地处理这两个层。从三个已发表分类法[24 (https://arxiv.org/html/2607.01903#bib.bib23),31 (https://arxiv.org/html/2607.01903#bib.bib24),1 (https://arxiv.org/html/2607.01903#bib.bib26)]中的25个复杂度维度出发,它推导出52个候选指标,涵盖NL层、代码层以及它们之间的接口,因此提示与代码的耦合变得可计数。针对第三个挑战,Hecate仅当一个指标凭实力赢得位置时才保留它。我们在保持代码规模固定的情况下,针对真实维护工作测试每个候选指标,并丢弃任何其信号仅由规模解释的指标。Hecate是确定性的、无依赖的,并且仅通过静态分析运行,无需执行应用或调用任何LLM。

我们在来自18个开源仓库的118个组件上评估Hecate,以从版本控制历史中挖掘的维护信号作为真实基准。评估得出三个发现。首先,大多数候选指标不起作用。52个指标中只有10个在固定代码规模后仍保持显著效应,即7个提出的指标和3个传统基准,相关性从0.22到0.40。这七个提出的指标衡量我们所说的结构广度,因为它们计算应用管理的不同元素的数量,如LLM调用点、记忆属性或提示模板,而非应用的大小。三个保留下来的传统基准较弱,而我们最强的指标优于它们。其他42个指标失败,它们的失败解释了为什么如此多直观的复杂度度量本质上是规模的伪装。其次,提出的指标优于传统的幸存者。McCabe CC在控制规模后失去显著性(ρ=+0.06)。RFC,一个计算可到达的不同方法的耦合指标,是最强的传统幸存者(+0.30),但我们排名前两位的指标优于它(n_mem_refs +0.40, n_llm_calls +0.38)。NL层指标即使在额外控制最强的代码指标后仍然显著,这表明提示复杂度是一个真正独立的维度,而非代码的副产品。同样的计数决策分支的创意在代码中平均ρ=+0.06,但在提示中为+0.27。第三,这些发现在研究仓库之外也成立。在来自6个未见仓库的20个留出组件上,两个最强指标保持了它们的效应量,而传统基准再次失效。

本文做出三个贡献。

- • 一个重要且困难的问题。据我们所知,我们是首个在LLM集成应用中度量超越代码的软件复杂度的研究,这些应用的大量逻辑存在于NL提示中。我们阐述了问题,明确了其三个挑战,并通过Prompt-as-Specification为其提供了形式化基础。
- • 一个工具和指标设计方法。我们构建了Hecate,一个静态分析器,用于度量NL和代码层的复杂度,并采用维度驱动的方法,从三个已发表分类法推导出52个候选指标,并在规模控制下验证每个指标。
- • 经过验证且可泛化的结果。在118个具有版本控制真实基准的组件上,我们识别出10个携带超越代码规模信号的指标,解释了为什么其他42个不起作用,并展示了最强指标在未见仓库上仍然有效。

## II 背景

### II-A LLM集成应用

LLM集成应用是一种软件系统,其核心使用大型语言模型,并辅以工具调用、记忆和规划[30 (https://arxiv.org/html/2607.01903#bib.bib11),32 (https://arxiv.org/html/2607.01903#bib.bib12)]。从架构上看,此类应用将一个提示(定义角色、约束和决策逻辑的NL指令)绑定到一组工具(LLM可调用的可执行函数)以及一个在LLM推理和工具执行之间交替的执行循环[13 (https://arxiv.org/html/2607.01903#bib.bib13)]。在我们的研究中,分析单元是单个程序化结构(通常是类或构造函数调用),它将提示绑定到工具。我们将每个这样的单元称为LLM集成应用的一个组件。LangChain[6 (https://arxiv.org/html/2607.01903#bib.bib15)]和MetaGPT[18 (https://arxiv.org/html/2607.01903#bib.bib14)]等框架推动了快速采用。我们研究的18个仓库平均超过30,000个GitHub星标和2,700次提交。

### II-B 软件复杂度指标

McCabe的圈复杂度(CC)[21 (https://arxiv.org/html/2607.01903#bib.bib1)]计算程序控制流图中线性独立路径的数量,并且仍然是最广泛使用的代码复杂度指标。Halstead的软件科学[15 (https://arxiv.org/html/2607.01903#bib.bib2)]通过运算符和操作数计数定义体积、难度和努力度。Chidamber–Kemerer(CK)度量套件[7 (https://arxiv.org/html/2607.01903#bib.bib3)]引入了面向对象指标,包括WMC(类的加权方法数)、CBO(对象间耦合度)和LCOM(内聚缺乏度),Basili等人[2 (https://arxiv.org/html/2607.01903#bib.bib4)]和Briand等人[5 (https://arxiv.org/html/2607.01903#bib.bib5)]验证了它们作为缺陷预测器的有效性。Li和Henry[20 (https://arxiv.org/html/2607.01903#bib.bib16)]提出NOA(属性数量)作为可维护性预测指标。所有这些指标完全在源代码上运行,无法捕捉以NL提示表达的逻辑。此外,即使在代码层,它们的预测价值也受到质疑。

### II-C 规模混淆因素

El Emam等人[9 (https://arxiv.org/html/2607.01903#bib.bib6)]表明,大多数CK指标在控制类规模后失去了与缺陷易发性的关联,得出规模是一个主要混淆因素的结论。Subramanyam和Krishnan[26 (https://arxiv.org/html/2607.01903#bib.bib7)]确认WMC在规模控制后变得统计上不显著。Gyimóthy等人[14 (https://arxiv.org/html/2607.01903#bib.bib17)]以及Zhou和Leung[34 (https://arxiv.org/html/2607.01903#bib.bib18)]在开源Java系统上复制了这一发现。在更大规模上,Zhou等人[35 (https://arxiv.org/html/2607.01903#bib.bib8)]调查了72项跨项目缺陷预测研究,并证明ManualDown(一个按LOC对模块排序的简单模型)匹配或超越了大多数复杂的预测模型。这些结果确立了以控制规模为条件的偏相关作为指标验证的金标准。偏相关衡量两个变量(一个指标和一个维护结果)之间的关系,同时统计上移除第三个变量(混淆因素,这里是代码规模)的影响。如果一个指标的关联在此移除后消失,则该指标根据El Emam等人的说法,“实际上是规模的代理”。按照标准实践,我们将偏相关应用于对数转换后的LOC(log(LOC)),以归一化右偏的规模分布[9 (https://arxiv.org/html/2607.01903#bib.bib6)]。解决了规模混淆问题后,剩下的挑战是如何形式化NL层,以便在其上定义指标。

### II-D 霍尔逻辑与NL规格说明

霍尔逻辑[17 (https://arxiv.org/html/2607.01903#bib.bib9)]通过由前置条件、程序语句和后置条件组成的三元组来推理程序正确性。Meyer的契约式设计[23 (https://arxiv.org/html/2607.01903#bib.bib10)]扩展了这一思想,增加了前置条件、后置条件和类不变量。最近,Bouras等人[4 (https://arxiv.org/html/2607.01903#bib.bib21)]使用自然语言状态描述作为代码验证的前/后条件。相反,我们将提示视为行为规格说明。这种Prompt-as-Specification视图为定义提示结构、代码结构及其交互上的复杂度指标提供了基础。

本工作的范围。我们测量的是软件复杂度,而非提示难度。这种区别类似于软件复杂度与算法复杂度之间的区别:前者关注实现的结构和可维护性,而后者关注所解决问题的内在难度。例如,一个要求LLM证明黎曼猜想的提示是困难的,但结构上并不复杂。相反,一个包含大量条件行为、工具交互和记忆依赖的提示可能对LLM来说很简单,但对开发者来说却难以理解和维护。因此,我们的指标针对的是提示结构而非推理难度。

## III Hecate方法

为了解决这个问题,Hecate分两个阶段进行。首先,

相似文章

Lean软件规模定律(阅读时间17分钟)

TLDR AI

该研究提案探讨了不同编程语言中代码库大小如何影响编码LLM的困惑度,并以Lean作为形式语言的测试案例。它表明Lean可能具有更优的缩放指数,从而使大规模软件更安全、更可靠。

从重复模式的层次复用角度衡量语言复杂性

arXiv cs.CL

提出阶梯路径指数作为基于算法信息论的语言复杂度度量方法,并将其应用于21个平行语料库。该指数在不同语言间近似不变,支持等复杂度假说,并揭示了字符库与语料长度之间的权衡关系。

LLM生成代码中的拼凑问题

arXiv cs.AI

本文形式化描述了'拼凑问题'——即LLM生成的代码在局部正确但在整个代码库中结构上不连贯的现象,提出了一个八类故障分类法和一个混合验证框架,并证明许多故障能够避开现有工具。

将代码置于显微镜下:面向LLM的小波上下文

Reddit r/LocalLLaMA

WaveScope 是一个 MCP 服务器,它应用小波变换对代码库进行处理,为 LLM 提供多分辨率结构上下文,以改进代码理解和编辑,解决上下文退化与结构性感知问题。