找回密码
立即注册
搜索
发回帖 发新帖

5470

积分

0

好友

703

主题
发表于 1 小时前 | 查看: 11| 回复: 0

一处交易对方留下的修订出现在 Word 文档里。Uber 的 Legal Redlining Agent(LRA)从侧栏读取修订、定位条款,给出接受、拒绝或修改建议,同时附上风险等级与面向对方的审阅意见。律师逐条核查,必要时重写,再把结果放进正式回复。

它不是那种上传合同、等待报告的独立 AI 工具,而是直接嵌入律师日常使用的 Word,处理一处处 redline——也就是合同里的修订痕迹。

2026 年 10 月 8 日,Uber 公开了这套系统的建设过程。第一代 LRA 从 2024 年初启动,2025 年进入内部法务团队试用。Uber 每年要谈判数千份合同;官方图示中,企业合同场景平均经过 5 轮,每轮支持耗时大约 2~10 小时。这个数字并不代表行业平均水平,但足以说明 LRA 面对的是一条高频、重复且不能轻易出错的工作流。

上线之后,Uber 记录到的结果是:平均合同审查时间减少超过 20%,AI 生成决策的准确率达到 91% 。不过统计口径没有展开——样本量、准确率定义、基线、评测周期都看不到,只能当作团队内部数据,不能外推成通用的法律能力。

Uber 还把第一代系统的几次失效写得相当具体。

最初的 RAG 检索 并不稳定,谈判手册没覆盖的场景下,输出近乎随机。团队开始记录律师反馈后,又发现一个简单的赞成、反对或点踩,根本装不下律师的专业判断。系统能给出决策之后,谈判语气仍然不合用。等它开始起草替代条款,模型编造术语、偏离合同已有定义的问题又冒了出来。

Uber 没有靠一次模型升级抹平这些问题,而是逐段修工作流:让律师终稿进入反馈库,把公司立场放进规则库,让律师直接维护语气要求,再把条款生成接回 Word。

顺着这些失效往下看,LRA 最值得拆解的不是模型多懂法律,而是它怎样避免把四样东西混为一谈:当前合同、公司规则、历史处理、律师最后采用的文本。

一处红线

一处红线进入系统后,LRA 会先识别对方想改什么,判断法律风险,查找适用规则与历史处理记录,再给出接受、拒绝或修改建议。如果建议修改,系统还会起草替代条款,并生成面向对方的审阅意见。律师决定采用、拒绝还是继续改写,确认后的版本才进入正式合同回复。

一处红线从 Word 读取、并行分析、生成建议到律师确认和反馈沉淀的完整链路

合同谈判不是一道只有标准答案的分类题。相同条款放到不同客户、地区、交易规模和谈判阶段,处理方式可能不同。LRA 接手的是其中重复、可检索、可生成的部分,最终判断仍由负责合同的律师完成。

时间也不只省在"接受还是拒绝"的判断上。Uber 特别提到,律师更需要一份能继续修改的反建议文本,以及一段能直接发给交易对方的解释。前者涉及合同定义、义务和例外,后者还要符合团队谈判风格。能交付这两样,LRA 才算进入真实工作流。

四次碰壁

Uber 把第一代 LRA 的建设过程分成四次主要迭代。顺着这四次修改看,比直接看最终架构更容易理解每个组件为什么存在。

RAG 先碰壁

最初的方案很直接——法务团队提供谈判手册和历史谈判示例,系统检索语义相关片段,再把这些片段与对方修改一起交给大模型做决定。

这个方案很快暴露了三个问题。

第一,查询与知识库并不对称。早期流程先识别对方意图,再从谈判手册中找相关内容。检索键表达的是"这次修改想达到什么目的",库里保存的却是政策说明和历史谈判示例。两边谈的可能是同一件事,语言形态却不同,语义检索很容易把"看起来相近"误当成"适用于当前谈判"。

第二,谈判手册不可能覆盖所有组合。检索不到合适依据时,模型仍然会生成一段完整回答,只是回答开始依赖通用语言能力,而不是 Uber 的真实立场。手册没有覆盖的场景,结果甚至接近随机。

第三,结论正确也不等于回复可用。合同谈判中,语气本身就是策略的一部分。过于防御会让沟通僵硬,过度积极又可能削弱立场。通用模型很难只凭一份手册还原团队日常的分寸感。

到这里,问题已经不只是检索不准。系统还要分清对方想改变什么、公司是否允许,以及这次应该怎样回应。

反馈不能只点踩

Uber 随后开始记录律师反馈。

最早的记录内容并不复杂:律师选择接受、拒绝还是修改,原始文本是什么,对方改了什么,外加一个点踩信号。这能告诉系统"刚才的建议不对",却解释不了错在哪。

团队后来继续补充律师期望的动作、具体评论,以及律师最终采用的修改文本。一次审阅才有了比较完整的前因后果:

原始条款
  + 对方红线
  + 对方意图
  + AI 的风险与决策
  + 律师最终动作
  + 最终采用文本
  + 律师给出的理由

系统记住的就不只是"这次答错了",还有在什么上下文里、律师把建议改成了什么。

运行时,LRA 会查询已经积累了数千次交互的反馈库。系统先做带元数据过滤的相似度搜索,把范围缩小到大约 20 条。

再交给大模型做第二轮过滤,核对候选案例是否真的符合当前双方的意图。最后只有少量案例进入上下文,用来辅助决策和评论生成。

相关规则和历史反馈也会显示在建议界面里。律师看到的不仅是系统结论,还有哪些材料影响了这次建议。这看起来像界面细节,实际上关系到律师愿不愿意把一段 AI 生成的文字带进真实谈判。

Uber 还会平衡同意与不同意的示例,并对历史反馈做指数衰减。当前半衰期设置为 365 天,越新的处理记录越容易进入后续 Prompt。这样做不是把旧案例判成"错误",而是降低系统持续复用过时立场的概率。

反馈库经过元数据过滤、模型二次筛选和时间衰减后,只有少量案例进入上下文

Uber 把这套机制称为自学习。不过,"学习"主要发生在检索结果与少样本上下文中,并没有持续微调模型参数的公开记录。律师改完一次,模型权重不会自动变化;变化的是下一次调用时,模型能够看到哪些依据。

语气交给律师

加入反馈后,系统仍然长期受语气问题困扰。Uber 最终在处理链末端增加了一次独立的模型调用,专门调整谈判回复。

这个节点没有做多轮反思。它先假定输入文本可能过于防御或过度迎合,再按法务团队定义的目标、风格和开场示例重写。Uber 的解释是:直接假设草稿有问题,省掉了"要不要修改"的判断,也避开了循环带来的延迟和 token 消耗。这一步贡献了多少提升,Uber 没有单独给数据。

Prompt 的维护方式也变了。工程团队维护结构,律师直接维护具体目标、表达风格和开场示例。目标语气写得很具体:直接、使用第一人称、不闲聊。按 Uber 的说法,法务团队几天内就把输出调到了更符合自身习惯的状态。

直接影响输出的领域内容由法务团队自己维护。工程团队守住边界、格式和运行质量,律师决定哪些表达能够代表团队。

条款要能落地

接受或拒绝一处红线,只解决了判断问题。律师更耗时的工作,往往是写出一版可以继续谈的替代条款。

简单文本生成在这里很容易出错。Uber 观察到,模型可能编造合同里没有的术语,或者偏离文档已经定义的概念。于是团队把 MODIFY 路径改造成 Agent 工作流:先参考历史反馈和规则,再生成折中条款,而不是让模型脱离依据自由改写。

这一轮变化让 LRA 不再只给判断,还要交出一段律师能继续编辑的文本。条款一旦由模型生成,版本关系也跟着进来:修改针对哪一版合同、引用哪些已有定义、生成文本是否遵守命中的规则、律师改写后哪一版才是最终事实。Uber 没有展开这些实现细节,它们是从公开链路继续往下推时绕不开的工程边界。

架构分工

LRA 采用薄客户端模式。Word 加载项处理文档交互和用户输入,Python 后端负责 AI 编排。律师触发分析后,后端使用 LangGraph 并行执行意图识别、风险评估和政策查找 ;OpenSearch 保存规则与历史反馈;Redis 保存会话状态;Uber 的 GenAI Gateway 承担模型接入。

下面这张图按 Uber 公开的组件和数据流重画,只表达逻辑关系。精确的节点顺序和服务边界,Uber 没有公开。

┌──────────────── Microsoft Word ────────────────┐
│ React + TypeScript 加载项                       │
│ 读取修订、定位条款、展示建议、应用修改           │
└───────────────────┬────────────────────────────┘
                    │ 当前文档、红线、律师操作
                    ▼
┌──────────────── Python 后端 ───────────────────┐
│                LangGraph 工作流                 │
│                                                │
│  意图识别 ─┐                                   │
│  风险评估 ─┼─> 决策:ACCEPT / REJECT / MODIFY  │
│  政策查找 ─┘              │                    │
│                            ├─> 评论生成          │
│                            ├─> 条款修改          │
│                            └─> 语气调整          │
└──────────────┬─────────────────────┬───────────┘
               │                     │
               ▼                     ▼
┌──────────── OpenSearch ───────┐   ┌── Redis ──┐
│ Rules Index                   │   │ 会话状态    │
│ Feedback Index                │   │ 后续问答    │
│ nomic-embed-text-v15          │   └────────────┘
└──────────────┬────────────────┘
               │ 规则、历史案例、律师终稿与理由
               └──────────────> 回到后端上下文

这些组件都不罕见,区别在于各自保管什么。模型负责识别、判断和生成;LangGraph、后端与 Redis 维持流程和会话;Word 保存当前合同,OpenSearch 保存规则与历史处理。Redis 还支持律师围绕当前文档继续追问。

《AI Agent 核心架构详解》里讨论过模型、运行时和业务系统的分工。LRA 给了一个具体例子:真正不能混的不是服务数量,而是谁保管当前事实、谁推进流程、谁只负责给出候选判断。

Word 不是外壳

Uber 没有另做独立网页,而是把产品嵌进律师原本就在使用的 Word。加载项使用 React 和 TypeScript 开发,通过 Office JavaScript API 读取修订、应用修改,并高亮正在审阅的条款。

把入口放在 Word,先解决了律师来回复制合同的问题。更重要的是,Word 保存着这项任务的当前状态。

律师处理的不是一段脱离上下文的文字,而是某份合同、某个版本、某处修订。Agent 的建议也不能只停在聊天记录里,最终要准确落到相应条款。文档位置、修订作者、删除内容、前后定义和当前版本,都会影响后续判断。

《一文讲清 Agent 如何理解业务》里把业务理解拆成对象、状态、规则、权限和动作。LRA 正好把这几个词落到了实处:对象是合同与条款,状态是当前版本和红线,规则索引保存公司立场,律师保留最终裁决权。修改写回 Word 后,动作才真正发生。少一项,系统都可能看懂文字,却改错合同。

落到工程实现,Office JavaScript API 又带来了三类很具体的问题:

  • API 往返较慢,团队用缓存减少与 Word 的交互次数;
  • 修订 API 在部分文档结构上会崩溃,加载逻辑为此增加了异常处理;
  • 被删除的文字可能返回空字符串,应用只能自行维护文本状态,才能正确展示差异。

这些问题与模型能力无关,却直接影响结果是否可信。如果系统遗漏了被删除的义务,后端检索和推理再准确,也是在审查一份不完整的合同。

这里的薄客户端不等于前端只负责显示。加载项要处理 Word 的文档状态和写回动作,后端承担耗时的检索、判断与生成,双方还要尽量减少往返。

拆开才好查错

Uber 使用 LangGraph 编排后端,并行运行意图识别、风险评估和政策查找。并行能减少一部分等待时间,图编排也把一次"合同审阅"拆成了不同问题。为了看清故障位置,可以把这些节点继续拆开。Uber 没有公布对应的故障字段,表中第三列是基于公开链路的工程推演。

节点 主要回答的问题 典型失败
意图识别 对方想增加什么权利、减少什么义务 只看到文字变化,没有识别真实诉求
风险评估 修改会给 Uber 带来什么影响 风险等级与具体法律后果脱节
政策查找 是否存在明确规则或可接受退让 漏检规则,或把相似规则用错场景
决策 应接受、拒绝还是修改 依据正确,但动作选择错误
条款修改 怎样形成可继续谈判的文本 引入新定义,改变原有责任边界
评论生成 怎样向对方解释立场 理由空泛,或暴露不必要的内部判断
语气调整 怎样符合团队沟通风格 改善语气时顺手改变了法律含义

如果所有内容都塞进一个 Prompt,系统也许能生成一份看起来完整的答案,但错误很难定位。拆成节点以后,团队可以判断问题出在文档读取、检索、决策、条款生成还是语气处理,再调整对应的数据和评测。

合同 Agent 与普通问答系统的差别也在这里。普通问答允许模型直接组织最终文本,合同系统更关心每一步依据能否追溯,生成动作是否受到约束,最终文本是否还保留原来的法律立场。

两类依据

LRA 在 OpenSearch 中维护两个主要索引。

规则索引保存公司的法律政策、立场、可接受的退让方案和期望回复示例。律师可以在原始模板中选中经常被修改的文字,并为它建立规则。系统检测到相关红线后,会对修改后的句子做语义搜索;高置信度命中时,规则进入上下文,并对模型输出形成硬约束。流程末端还有一次 LLM 检查,用来验证结果是否遵守命中的规则。

反馈索引保存历史谈判记录,包括当时的上下文、对方意图、AI 分析、律师最终动作、实际采用文本和理由。反馈主要处理可协商空间,让系统知道团队过去在相似场景中怎样取舍。

两者都通过向量检索进入模型上下文,但它们不能拥有相同权限。

数据来源 表达的内容 在当前决策中的位置
规则 组织当前明确维护的政策和底线 命中后约束或覆盖自由判断
历史反馈 某次交易中真实发生过的处理 提供相似经验,不能自动升级为政策
当前模型判断 对意图、风险和候选文本的推断 形成建议,仍可能被规则和律师修正
律师裁决 当前合同的最终取舍 决定本次正式文本,并成为新的反馈

规则、历史反馈、模型判断和律师裁决在当前决策中的权限不同

Uber 把这套机制称为混合决策引擎,并将规则侧描述为确定性规则引擎。不过从完整链路看,它并不是传统意义上完全由精确条件驱动的决策表。规则触发仍包含语义向量搜索,最终遵循性检查也使用了 LLM。

这里的确定性,主要来自"规则拥有更高决策优先级",并不表示每一步都摆脱了概率模型。公开材料里也没有"80% Pipeline、20% Agent"这样的比例,无法从中推出工作量或决策占比。

模板是锚点

这套检索能跑起来,有一个关键业务条件:谈判通常从同一份源合同开始。

系统会按分号、句号或换行切分合同。当后续出现红线时,它可以回到原始模板中的对应句子,用同一句原文查找规则和历史反馈。律师提供反馈时,系统也使用这句原文作为入库锚点。

这样一来,查询和索引内容来自同一个源句子,向量表示更对称。即使合同经过几轮修改,原始条款仍能帮助系统把检索范围限制在相近位置;语义搜索再负责吸收措辞上的细微变化。

反馈索引还有另一条线索:对方意图。Uber 不只对原始文本做向量化,也会按交易对方想实现的目的组织历史记录。这能找到"文字不同,但诉求相同"的案例。

两种检索键各自补了一块短板:

原始模板句子:回答"这是合同里的哪一处问题"

对方谈判意图:回答"对方实际上想改变什么"

元数据过滤:回答"哪些客户、业务和合同范围可以比较"

只按原文检索,容易漏掉不同表达下的相同诉求;只按抽象意图检索,又可能把不同条款、不同业务线的案例混在一起。模板锚点、意图向量和元数据过滤组合起来,才构成这套反馈检索的基本精度。

换成自由格式合同、陌生模板或一次性交易,原始句子这个稳定锚点就没了,检索难度会明显上升。条款分类、文档结构恢复、定义引用解析或法律本体的重要性也会随之增加。Uber 只把本体和知识图谱列为后续探索,并没有把它们写成第一代 LRA 已上线能力。

时间权重也只能解决一部分问题。365 天半衰期能降低旧案例反复出现的概率,却不能判断案例是否仍然适用。上周的一次让步可能只属于某笔特殊交易,一年前的公司政策也可能继续有效。

如果反馈里没有业务线、地区、合同模板、客户类型、政策版本和例外原因,系统只知道过去有人这样处理过,却不知道这次还能不能照用。Uber 没有完整披露这些字段。这是沿现有架构继续推导的问题:系统不只要记住一次决定,还要知道它在什么条件下失效。

错在哪一层

Uber 给出的 AI 生成决策准确率是 91%。系统还持续运行 LLM-as-a-judge 评测,监控两项指标:检索上下文质量 document_quality_metric,以及模型对公司规则的遵循程度 rule_adherence_metric。

后两项指标比单一准确率更能说明这套架构怎样运行。

最终决策错误,可能是规则没找到,也可能是找到以后没有遵守;可能是对方意图识别错误,也可能是替代条款引入了新的义务;甚至可能是后端建议正确,但 Word 写回了错误位置。它们最后都表现为"律师改了 AI 的建议",修复方法却完全不同。

只看最终准确率,团队仍然不知道该改哪一层。沿着实际链路拆开看,故障位置会清楚得多:

环节 观察内容
文档读取 红线、删除文字、定义和当前版本是否完整
意图识别 是否识别对方真正希望改变的权利与义务
规则检索 应命中的规则是否找到,是否出现错误命中
反馈检索 案例是否匹配当前意图、条款位置和适用范围
决策 接受、拒绝、修改是否符合当前政策
条款生成 是否引入不存在的定义、金额、义务或例外
语气调整 是否保留原有法律立场,只改变表达方式
人工裁决 律师保留结论、重写文本或推翻建议的原因
文档写回 修改是否准确落到目标条款和目标版本

Chip Huyen 在《Agents》中也按规划、工具执行和效率等失效模式观察系统。放到合同审阅里,整体准确率适合看趋势;下一版到底该动检索、规则、Prompt、工作流,还是 Word 集成,仍得回到分层指标。

别把链路串错

整条链路跑起来后,系统一直在维护三组对应关系。

合同与版本是一组。系统读取哪一版红线,律师正在看哪一处修改,最终文本又写回哪一版。

建议与依据是一组。当前建议命中了哪条规则,参考了哪些历史案例,模型怎样从意图和风险走到接受、拒绝或修改。

建议与裁决又是一组。律师改的是模型哪份建议,为什么改,最后采用的文本能否在下次相似场景中被找到。

只要丢掉一组关联,就会出现一种很难察觉的错误:Word、检索、模型和反馈库都返回成功,拼起来却不是同一份合同、同一条规则或同一次裁决。

《输出结果不等于完成任务》里区分过模型输出、工具返回、动作生效和目标完成。放到合同审阅里,生成一段替代条款只算模型输出;它写回正确的合同和版本,再经律师确认成为正式回复,任务才算完成。系统还要留下这次修改为什么被允许,它依据的是哪一版规则和哪些历史处理。

人工介入也不只是末尾放一个确认按钮。律师改完以后,后续节点究竟读取旧文本还是新文本,取决于运行时有没有保存输入版本和中间状态。Uber 使用了 LangGraph 和 Redis,但没有公开人工暂停、恢复和冲突处理的具体实现。这部分仍是架构推导,不能算作已经确认的能力。

回头看四次迭代,LRA 并没有沿着"RAG、Agent、多 Agent"这些名词一路升级。它只是逐次把混在一起的责任拆开。

手册不能代表真实决策,律师终稿和理由就进入反馈;历史经验不能代表公司底线,规则与反馈就分开。工程团队不替律师决定谈判口吻,语气内容交给法务团队维护;模型给出的替代条款不能直接成为合同,最后仍由律师改写和确认。

LRA 能取得这组结果,依赖重复合同、稳定模板,以及持续产生的高质量律师反馈。Uber 没有公开 91% 准确率的详细口径,也没有证明陌生模板和全新交易能取得同样结果。Claude Code、OpenCode、Skills、法律本体和知识图谱,仍是后续探索。

放回整条链路,LRA 是一套分工清楚的合同审阅系统:Word 管当前文档,规则库管公司立场,反馈库保存过去的处理,模型给出候选建议,律师决定本次采用什么。

模型当然重要。系统能不能长期用下去,最后落在三件很朴素的事上:合同版本不混,规则和历史案例不混,律师最终采用的文本不丢。

参考资料

在云栈社区里,关于 Agent 工程实践的深度讨论也在持续展开,欢迎一起交流。




上一篇:Seakills 发布:一句话让 Agent 完成 Sealos Cloud 部署上线
下一篇:EmbeddingGemma 2 本地实测:九档量化检索质量与多模态端点避坑
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-10-25 05:58 , Processed in 0.069024 second(s), 39 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表