Ramp 构建语义层,将 AI 智能体追踪记录转化为可归因的工作项,从而打通从 AI 支出到 ROI 的路径。

RAMP LABS(@RAMPLABS)深度报道 · 已翻译 · 约 21 分钟
阅览室 · AI 最佳实践#工作#运行#支出#构建#语义层#投资#回报#规模原文

作者:René Sultan

AI遥测技术能告诉我们智能体使用了哪些模型及其成本,却无法揭示我们究竟让它们执行了什么任务。为此,我们构建了一个语义层,将智能体追踪记录转化为目的、结果与成本的完整档案,以满足ROI归因的需求。

该流水线从智能体追踪中构建这一语义层。它先将相关会话合并为完整的智能体运行,再将每次运行拆分为工作项。工作项是指智能体所追求的独立目标。每个工作项记录其目标与结果,并附带工作类型、产品或平台领域,以及所涉及的技术层面的标签。我们将其与运行中的模型支出、负责人、团队和代码仓库关联起来。在为期三周的时间里,该系统分析了约20万次智能体运行,识别出约25万个工作项。

在此之前,我们的遥测技术只能显示哪些模型在运行、消耗了多少令牌以及相应成本,这让我们得以从AI消费方式的角度审视支出。而要推理ROI,我们需要了解智能体产出了什么:目标、结果、团队、产品以及涉及的系统。语义层为我们提供了通往ROI归因的清晰路径。通过将这些记录与产品和业务成果相连接,我们便能从了解AI的成本,转向评估其带来的回报。

Ramp 检查

我们从检查开始,这是 Ramp 内部的后台编码代理。每次检查会话都在远程沙箱中运行,具备完整的开发环境,并能访问 Ramp 工程师可用的工具和上下文。这使得检查能够读取代码、查询内部数据、发出 API 请求、实施更改,并通过测试和实时预览进行验证。

截至 2026 年 8 月,Ramp 合并的所有 PR 中有 75% 来自检查会话,且检查已累计超过一百万次会话。其用途不仅限于直接编码。工程师、设计师和产品经理在检查会话中协作,同时有超过 200 个内部代理在该平台上运行,用于代码审查、事件响应、数据分析和客户反馈等工作流程。这种规模和多样性使检查成为自然的起点。

这些追踪记录已经包含了理解这一系列工作所需的信息。每次追踪都记录了用户的请求和代理的执行过程:其消息、工具调用、代码更改、测试和结果。一个人可以阅读追踪记录,理解代理被要求做什么、做了什么以及工作如何结束。我们的挑战是将这种手动阅读转化为对数十万次会话的一致分析。

重构完整运行过程

对Inspect的请求并不总是局限于单一会话中。在此,会话指的是Inspect的一次执行。Inspect可以开启子会话来调查其他仓库、并行处理请求的一部分,或在新会话中继续相关工作。这些子会话自身也能开启它们的子会话。

一个请求涉及的工作流分析了企业近期的银行活动和即将到来的付款,以建议应向关联银行账户添加多少资金以覆盖接下来的30天。此示例基于真实请求,但名称和仓库标识符已作更改。

用户请求以如下内容开始:

如果你查看资金推荐运行,似乎Web应用出于某种原因总是分派两次运行...你能确认一下这是否是一个bug吗?

Inspect将工作分配至如下会话家族:

内部应用、后端和 Web 应用三个仓库中的八个关联会话记录了调查、后端修复、前端迁移、质量保证和代码生成过程。
内部应用、后端和 Web 应用三个仓库中的八个关联会话记录了调查、后端修复、前端迁移、质量保证和代码生成过程。

根会话协调了整个请求,并处理了internal-app的变更。两个子会话分别调查了前端和后端。后端仓库中的一个会话实施了修复,并开启了另一个会话以审计受影响的Web调用者。一个独立的Web会话迁移了前端,并开启了用于预览QA和生成API客户端的会话。

这八个会话合计使用了约560万令牌,交换了1100条消息,进行了960次工具调用,花费了93美元。根会话仅占该支出的约五分之一。两个合并的拉取请求均来自子会话。

因此,我们将重构作为流程的第一步。重构过程从根会话开始,跟随每个子会话和延续会话,等待它们全部完成,并将它们的轨迹合并为一条记录。我们将根会话及其关联的子会话和延续会话称为一次完整运行。只有在此之后,提取模型才会解读整合后的工作。

从完整运行中提取工作项

重构完成后,提取模型读取完整运行并提取工作项。我们将工作项定义为代理工作的基本单元:一个目标和一个结果。

提取模型的主要输入是根会话及每个子会话的时间顺序轨迹,包括它们的消息、工具调用、命令、文件更改、测试和最终结果。我们还传递从轨迹中派生的事实:重构是否完成、包含多少条消息和工具调用、哪些文件出现最频繁、使用了哪些工具,以及运行是否更改了代码、开启了拉取请求、失败或跨仓库操作。

对于资金推荐示例,提取模型收到一条包含上述所有八个会话的记录。它可以看到原始请求、前端和后端调查、后端修复、前端迁移、质量保证会话以及两个合并的拉取请求。

难点在于确定一个工作项在哪里结束,另一个在哪里开始。调查、编辑、测试和解释通常是同一目标的不同阶段。将每个阶段或子会话视为单独项会高估工作量,但一次运行也可能追求多个应保持独立的目标。

资金推荐运行的示例清晰地体现了这一区别。调查找出了该缺陷的根源。后端变更修复了问题。前端迁移使受影响的客户端适应了新API。提取模型将这些保留为三个工作项,因为每个都有独立的目标和结果。它将质量保证和代码生成视为辅助步骤,而非独立的工作项。

我们在提示中编码了这一区别:

仅为不同的用户或业务目标提取工作项。除非服务于不同目标,否则不要将调查、编辑、测试和解释等常规实施阶段拆分为独立的工作项。追求不同目标的子会话通常自成工作项;而仅延续父目标的子会话通常不是。

提取模型在两层返回结构化响应。一层描述完整运行。另一层包含每个工作项的详细记录。

在运行层面,响应包括:

{
  "session_summary": "Investigated and fixed a race condition that created duplicate funding recommendation runs.",
  "starting_request_summary": "Determine why funding recommendation runs appeared to be dispatched twice.",
  "final_outcome_summary": "The backend now prevents duplicate run creation, and the frontend creates each run once before making read-only requests using its ID.",
  "work_item_count": "3",
  "primary_work_item_id": "W001",
  "work_item_edges": [
    {"from": "W002", "to": "W001", "relationship": "depends_on"},
    {"from": "W003", "to": "W002", "relationship": "depends_on"}
  ]
}

总体而言,提取模型识别出三个工作项:

  1. 重复资金推荐运行的根因分析。 确定重复运行源于前端还是后端。调查将其追溯到并发后端请求创建了相同运行。
  2. 在后端防止重复运行创建。 修改后端,使并发请求复用同一运行而非创建重复项。由此产生的拉取请求避免了重复运行。
  3. 将前端编排更新至新API。 更新受影响的前端客户端,使其仅创建一次运行,然后使用返回的运行ID进行只读请求。这项工作促成了第二个已合并的拉取请求。

每项工作条目均指向支持其的证据,包括相关会话、文件、工具和产物。这使我们能够对照原始追踪记录核验提取结果。

在约20万次分析过的运行中,17%包含多个工作条目。在这些多条目运行中,61%完全发生在单个会话内。反之亦然:扩展为多个关联会话的运行中,30%仅代表一个工作条目。Inspect会话与工作条目之间不存在一一对应关系。此外,占17%的多条目运行消耗了58%的模型支出。

此时,我们已能将任何完整运行分解为其组成工作条目,但仍需一个共享分类法来比较数十万次运行。

描述每个工作项

我们对每个提取出的工作项分别运行了标注模型。它接收了上述结构化的工作项记录以及整个运行过程的摘要。运行摘要提供了上下文背景,而提示词则指示标注模型仅对选定的工作项进行标注。

我们要求标注模型从三个方面描述每个工作项:

  1. 其工作类型是什么
  2. 它支持哪个领域:产品还是内部平台
  3. 它涉及哪个技术领域

我们明确了每个标签应描述的内容,但没有指定标注模型可以返回的固定值。在此阶段,我们刻意没有为标注模型提供预定义的分层结构或标签集。这样做会将我们的假设嵌入输出中,并迫使不熟悉的工作被归入最接近的现有类别。

相反,标注模型用自己的语言撰写每个标签,从而能够捕捉到我们未曾预料到的Inspect使用方式。

核心指令是:

标注工作项,而非整个会话,同时保留会话上下文。使用自由形式的自然语言标签。不要将工作项强行归入预设的分层结构或类别值菜单中。

响应还描述了该项的意图、工作流程、结果、缺失的上下文以及支持性证据。六个字段捕获了我们后来用于构建共享类别的标签。

对于来自资金推荐运行的根本原因分析,标注模型返回了:

{
  "task_type": "root cause analysis",
  "secondary_task_types": [
    "debugging",
    "data exploration"
  ],
  "product_area": "Banking",
  "internal_platform_area": "none visible",
  "technical_area": "Backend API & Services",
  "code_area_group": "apps/wallet"
}

这些字段共同描述了工作类型、领域和技术领域。

来自资金推荐示例的三个工作项获得了以下自由形式标签:

这些是标注模型的描述,而非稍后在归属仪表板中展示的共享类别。在此阶段,差异是有益的。它使标注模型能够保留我们未曾预料到的区分,在证据支持时使用具体语言,并在区域不可见时说明情况而非猜测。

接下来,我们需要一种一致的方法来对生成的标签进行分组。等价的概念可能以不同的名称或不同的具体程度出现,例如 BankingBanking, Treasury & Underwriting。为了在数十万次运行中对工作进行分组和比较,我们需要将该词汇转化为共享的分类体系。

构建共享分类体系

标注模型以不同的具体程度描述了调查工作,使用了诸如 debuggingroot cause analysisproduction investigation 等标签。在三周内,它为大约25万个工作项撰写了超过140万个标签。一个工作项可能收到多个描述其工作类型、领域和技术领域的标签。在标准化这些标签后,仍有超过10万个唯一值。

为了构建首个分类体系,我们使用分类模型将一组观察到的标签分组为共享类别。对于每个标签,输入包括:

  • 标签本身。
  • 其描述的内容:工作类型、领域或技术领域。
  • 其出现的频率。
  • 使用该标签的工作项示例。

我们要求分类模型将表达相同概念的标签分组,同时保留对分析仍有用的区分:

合并明显的拼写、大小写、标点和同义词变体。不要过度合并那些会隐藏经理、产品负责人或Inspect负责人所关心含义的标签。

分类模型返回了针对工作类型、领域和技术领域的独立类别。每个类别都有名称、定义、归入其下的观察标签以及这些标签所描述工作的示例。

首次发布的分类体系包含30个类别:

  • 10种工作类型
  • 11个领域
  • 9个技术方向

在资金建议运行中,共享类别如下:

标注模型生成的标签保留了每个工作项的具体特征,而共享类别则为我们提供了一种一致的方式,用于跨运行比较工作,并按工作类型、领域和技术方向归因支出。

压缩代理轨迹

在最初三周的分析之后,成本成为下一个制约因素。为了在公司规模上持续运行该流水线,我们需要识别成本驱动因素,并在不改变其产生的工作项或类别的前提下降低成本。

为此,我们将每次提取输入压缩至提取模型所需的信息量。每次提取调用平均向提取模型发送约76,000个输入令牌。其中约74,000个(占98%)来自代理轨迹。这使得轨迹成为降低成本最直接的切入点。

我们首先测量了轨迹中包含的内容:

占比最大的是文件读取。Inspect存储了其打开的每个文件的完整内容,尽管提取模型通常只需要文件路径以及读取是否成功。

例如,一个文件读取事件可能包含:

event type: file_read
status: completed
file: /workspace/web-app/src/funding-recommendation/status-page.tsx

result:
1: import { RecommendationSummary } from "../components/RecommendationSummary"
2: import { useFundingRecommendation } from "../hooks/useFundingRecommendation"
3: ...

压缩器将其缩减为:

event type: file_read
status: completed
file: /workspace/web-app/src/funding-recommendation/status-page.tsx
result: file contents omitted

对于搜索、命令和工具调用,它保留了操作及记录事件结果的行。例如,一段冗长的测试日志被简化为:

command: pytest tests/test_funding_recommendation.py
status: completed
result: 42 tests passed

当同一段较长的结果多次出现时,压缩器会保留第一份副本,并将后续的副本替换为引用:

Same result as event 12. Repeated 4,000-character output omitted.

我们完整保留了用户和代理的消息、代码编辑以及子会话记录。这些事件承载了请求、所做的更改以及整个运行过程的结构。我们移除了代理的推理文本和Inspect系统消息,因为它们描述的是Inspect如何运作,而非用户请求了什么或运行产生了什么结果。

随后,我们测试了压缩是否改变了流水线所报告的内容。由于LLM推理并非完全确定性,对相同输入的重复分析可能产生略有不同的标签。我们首先在相同输入上反复运行未压缩的提取,以衡量正常的运行间差异。接着,我们压缩了大约4000条历史轨迹,并重复了提取过程。在工作类型、领域和技术领域方面,压缩与未压缩结果之间的差异,始终保持在未压缩重复运行中已观察到的波动范围内。

我们测量了从少于25,000字符到超过120万字符的轨迹中的token减少量。压缩将平均轨迹从大约74,000个token减少到19,000个,减少了74%,同时保留了用于理解运行过程的对话、代码更改和结果。

在 Snowflake 中实现归因可查询化

财务、产品和工程团队需要将此归因与他们在衡量支出、所有权和成果时已使用的数据结合起来。因此,我们在 Snowflake 中以两个层级发布了结果:

每个工作项都指向生成它的完整运行过程。这使模型支出能够同时关联到多个层面的上下文:负责的所有者、涉及的项目和代码仓库、代理试图实现的目标、它执行的操作以及工作的最终结果。

支出在完整运行层面仅计量一次。对于每个类别视图,我们将该总额平均分配到运行中涉及的各个不同类别。对每次运行应用相同规则,可保持总支出不变,同时允许按工作类型、领域和技术领域进行比较。

资金建议示例不再仅仅作为软件工程部门下的一笔 93 美元明细项出现。我们能够看到该支出支持了 银行、资金与承销 领域内的资金建议工作流。我们可以追踪其涉及 internal-appbackendweb-app,将调查工作与后端修复和前端迁移区分开来,识别负责任的所有者,并看到该工作产生了两个已合并的拉取请求。

同样的结构支持在 Ramp 内部提出更具体的问题。例如,Router 的用户可以隔离与 Router 项目相关的支出,将路由行为的工作与评估、后端集成以及提示词或技能变更区分开来,然后查看哪些人员或自动化流程发起了这些运行,以及每次运行的结果如何。

同时,Inspect 还驱动着超过200个内部代理,用于代码审查、事件响应和数据分析等工作流程。这种归属机制使我们能够以与人工直接发起的工作相同的细致度来分析这些自动化运行。以代码审查代理为例,我们可以从按 代码审查 分类的总支出,深入到其审查的仓库和拉取请求、该代码所支持的产品或系统、产生的发现,以及这些发现是否促成了代码变更。

财务部门不再仅仅询问工程部门在 Inspect 上花费了多少,而是可以提出更具体的问题,例如:

  • Router 项目在评估和路由变更上花费了多少?
  • 哪些产品在调试方面产生了最多的 Inspect 支出?
  • 这些支出背后涉及哪些仓库和负责的负责人?
  • 有多少代码审查支出用于支持 Banking 业务,而非内部开发者工具?
  • 哪些高成本的运行带来了合并的变更、完成了调查,或者最终没有产出任何成果?

这些记录改变了我们分析 AI 支出的方式。我们不再仅仅按模型、令牌数量和部门来组织数据,而是可以围绕项目、目标、成果、负责的负责人、产品以及涉及的技术系统来构建分析框架。

这正是连接 AI 支出与 AI 投资回报率之间缺失的一环。一旦支出承载了其背后工作的目的和结果,我们就能将其与 Ramp 已经衡量的产品、工程和业务成果进行对比,并提出关键问题:这些结果是否证明了我们的投入是值得的?

将AI支出归因产品化

我们将归因功能产品化,把Snowflake记录转化为公司层面的视图,展示Inspect支出的去向、所支持的目标与产品、工作负责人以及每次运行的最终结果。

该视图旨在从总体支出追溯至其源头。用户可以从Ramp全公司的所有Inspect活动开始,再按时间、部门、责任负责人、代码仓库、工作类型、领域或技术方向进行筛选。

筛选至某位责任负责人后,可查看其模型总支出、完整运行次数及每次运行的平均支出。同一视图还展示其最主要的工作类型、领域、技术方向和代码仓库,随后列出构成这些总额的具体运行记录。

用户随后可以选择一个类别来查看其背后的运行情况。每次运行都会显示其成本、负责的所有者、仓库、关联会话数量、工作项数量以及分析状态。其工作项直接显示在下方,并附有代理所做工作的描述以及分配给每个工作项的工作类型、领域和技术领域。
用户随后可以选择一个类别来查看其背后的运行情况。每次运行都会显示其成本、负责的所有者、仓库、关联会话数量、工作项数量以及分析状态。其工作项直接显示在下方,并附有代理所做工作的描述以及分配给每个工作项的工作类型、领域和技术领域。

资金建议示例展示了从总体到源头的追溯路径。选择根因分析与调查,即可看到构成该部分支出的93美元运行记录。用户可查看发现后端竞态条件的调查过程、修复该问题的后端变更,以及随后进行的前端迁移。该运行记录还可链接回Inspect,其完整的会话系列和原始追踪信息仍可供查阅。

选择“根本原因分析与调查”会显示资金建议运行及其归因支出背后的三个工作项。
选择“根本原因分析与调查”会显示资金建议运行及其归因支出背后的三个工作项。

因此,一个类别的总额始终与其产生的工作相关联。财务可以从Ramp中归因于缺陷修复与补救的Inspect模型总支出入手,将其细化到特定产品、负责人或代码库,然后检查支撑该金额的运行和修复情况。产品或工程负责人可以从其项目出发,比较AI支出的去向,并审视最昂贵的运行是如何结束的。

将归因产品化也为Ramp提供了一种共享的数据解读方式。财务、产品和工程团队使用相同的工作类型、领域、技术区域、所有权和结果定义。公司领导者可以跨组织比较支出,而最接近工作的人员可以验证数字背后的目标、结果、代码变更和原始Inspect会话。

随着归因作为全公司范围内的产品可用,我们得以看到Inspect在Ramp中的实际使用情况,以及公司为此支出获得了什么回报。

从AI支出到AI投资回报的路径

衡量AI的投资回报率不能始于令牌或模型调用。它必须始于代理被要求追求的目标及其帮助产生的成果。当我们能将成本与目的相连时——即工作旨在达成什么、支持了谁、以及因此带来了哪些变化——成本才变得有意义。

这正是我们的语义层所创造的背景。它将模型支出与工作背后的目标、工作的结束方式、负责的所有者及团队,以及涉及的产品和技术系统相连接。在Ramp,我们现在能够以公司规模看到AI支出背后的目的,并将任何总额追溯至基础工作。

由此,我们可以将AI支出与Ramp已用于评估投资的产品、工程和业务指标相连接。处理Router问题的代理是否帮助团队更快交付?在银行调查上的支出是否使产品更加可靠?AI是否减少了维护财务产品经济模型所需的手工工作?这些是财务和业务领导者已经对人员、软件和项目所做的判断。语义层为他们提供了对AI做出这些判断所需的记录。

下一代AI成本管理将不会止步于衡量AI的成本。它将展示投资的目的、产生的成果以及是否值得。这个语义层是我们在Ramp构建这一未来的基础。如果您对此产品感兴趣,请发送邮件至veeral@ramp.com和rene.sultan@ramp.com,以便加入alpha测试。

想跟上我们接下来的AI实验吗?请在此订阅并在@RampLabs上关注我们。我们也在Ramp招聘各类职位

已读完 · 本文由熊猫易读翻译重排