Skip to content

AI 工程Erpilot 开发实录

对话裁短以后,业务任务还在吗:多轮状态与上下文实验

区分任务状态、历史观察与请求视图,用固定快照和真实连续任务检验上下文投影、信息保留与保护参数。

Erpilot 系列第 7 篇 · 2026-10-20 发布 · 实现与验收截至 2026-10-19

上一篇:政策 RAG 的检索与回答。本文分别讨论固定历史快照答题与连续业务任务;候选上下文视图仍仅显式启用。

本文引用的源码与报告保存在随文资料清单中,包含当时尚未推送到项目仓库的工作区内容,文件版本由 SHA-256 校验值标识。代码文本与复现脚本为局部摘录,运行仍需 Erpilot 工作区依赖。

一份订单草稿有许多商品,用户说“把第 31 行改一下”。数据库保存了完整草稿,但下一轮请求可能只带上工具结果的头尾;模型看不到中间那一行,仍然需要生成参数。

另一类要求甚至不在草稿里:用户早先独立说过一条核对标记,随后完成查询和修改,最后才要求复述。即使客户、商品和数量都能从数据库找回,这条未持久化要求也可能随历史裁剪消失。

这两种情况对应不同的信息:业务状态、历史观察和用户原话。Erpilot 的上下文实验从区分它们开始,再检查压缩后的输入是否足以支撑本轮任务。

一、历史、任务状态与请求视图分开 ​

业务数据库保存当前草稿与各版快照。对话历史记录用户说过什么、模型提出过哪些调用以及工具当时返回了什么。本轮请求视图则决定模型这次实际能看到哪些消息。

信息能支持的判断需要注意的时效或身份
当前业务查询现在有哪些草稿、当前版本与商品顺序修改前重新读取,并绑定会话与版本
历史工具结果当时观察到了什么可能过期,也可能已被后续失败取代
用户原话请求、指代与尚未写入业务状态的要求保持 user 角色,不能随意压缩为另一种含义
模型请求视图本轮推理所用的材料是发送前的投影,不自动成为执行事实

因此,恢复任务不能仅靠让模型重读聊天。单份草稿可通过 get_order_task 找回,多份未提交草稿则返回 ambiguous,先澄清目标;修改绑定明确版本、行号,并可携带 expected_sku。

如果所选行的 SKU 与预期不符,业务层拒绝修改。这能阻止某类错误写入,却不能保证模型一定提出正确参数。输入保留、参数生成和业务校验仍需分别检查。

二、给模型一份保留结构的视图 ​

当前默认压缩包含单条工具结果截断和较早轮次裁剪。它可以控制发送内容,但字符串头尾截取可能破坏 JSON,也可能刚好删掉中间目标行。

候选 ContextView 在发送请求前深拷贝历史,再对工具内容做受信任的应用投影。候选路径保留原传入历史供 checkpoint 与审计使用;发送视图的省略不等于删除原业务数据。

ERP 适配器将任务结果摘要为状态、草稿身份、版本、客户、备注和原顺序 SKU / 数量。多草稿保留候选列表;无草稿和最新读取失败也要保留,不能寻找更早一次成功结果覆盖它们。

无法安全投影的大响应变成合法 JSON,标明已省略、原始长度、内容哈希与 refresh_required。这样模型至少能区分“数据没有提供”和“一份可直接使用的完整结果”。哈希用于定位原内容,不负责恢复被省略的信息。

工具交换也有结构约束:assistant 的 tool_calls 与对应 tool 消息成组保留;并行调用不能只留下其中一个结果。省略整份业务快照与拆坏协议消息,是不同问题。

投影仍保持 tool 角色,并标记历史观察和重新查询要求。工具内容不能选择自己的投影器,也不能通过被摘要而升为 system 指令、实时库存或写入授权。

实现分为通用的 ContextView与ERP 摘要适配器,agent_core 不需要导入 ERP 领域包。

三、先测历史快照,不把背景夹具当成真实对话 ​

首组实验冻结十个场景,比较完整历史 full、现有策略 current 和结构化视图 structured。场景覆盖较长背景、大工具结果、版本更新、多草稿、最新错误和早期独立要求。

其中背景轮次由夹具提供,每个 case / 策略只有最后一问调用真实模型。这个设置适合检查固定历史中的信息保留与答题,但不证明模型真实连续执行过所有背景任务。

实验还修正过一个会制造假阳性的夹具:v1 的商品编号与数量随行号递增,模型即使没看到中间行,也可能按规律猜中。v2 改为固定哈希派生的非连续 SKU 和数量,并保留旧报告作为诊断材料。不能将可猜中的字段还原当成信息未丢失。

v2 同范围的实际结果如下,输入 token 来自端点 usage:

模型策略严格答题通过实际输入 token
GLMfull9/10124062
GLMcurrent2/1068965
GLMstructured8/1025720
DeepSeekfull10/10124696
DeepSeekcurrent2/1069202
DeepSeekstructured9/1026300

原始结果见 GLM JSON和 DeepSeek JSON,范围与用量说明见快照实验验收。

在这个固定批次,候选相对现有策略的输入 token 分别减少约 62.7% 和 62.0%,但没有全部通过;GLM 的候选尾延迟也没有改善。输入变少、答题变好与整体变快,需要分别用指标证明。

完整历史也有失败:GLM 在最新查询失败的场景引用了旧成功观察。更多文本不能保证模型选择最新有效事实,实验需要同时包含旧成功与新失败。

四、字段还在,不代表模型一定用对 ​

离线信息检查读取投影输入,看目标字段是否存在。真实模型答题还要验证它能否从这些字段中选对行、保留类型和原文要求。

快照实验中,GLM 的结构化输入包含目标商品和数量,模型仍选错了中间行;两模型也都丢失过未写入任务状态的早期独立要求。前者是使用信息的失败,后者是投影遗漏信息,不能合成同一类“模型记忆差”。

基于这两点,后续连续任务新增显式 workflow=True:保留场景内全部用户原话,摘要补上从 1 起算的 item_number 和该报价版本的 total_amount。这些仍是历史快照信息,修改前依然要求重新读取当前任务。

完整用户原话会随着轮数增长。因此新候选还设置 fail_on_overflow:受保护消息超过估算预算时,请求前停止,不能为了继续运行静默删掉系统消息或用户要求。

这个边界只针对消息的启发式估算。工具 schema 另占输入空间,估算也不是供应商 tokenizer;它不能被写成整个请求的实际 token 硬上限,更不是无限长对话能力。

五、再让模型真正连续完成业务轮次 ​

第二组实验保持真实上轮输出,模型每轮经过 LangGraph、FastMCP 与独立临时 SQLite。三个场景分别验证早期要求、两份草稿的澄清选择,以及大草稿中间行修改;初始大草稿是明确标注的夹具,后续对话与参数由模型实际生成。

每轮检查旧版本不可覆盖、仅目标草稿生成预期新版本、客户全称与备注保留、商品顺序和全部数量正确;订单和库存等业务表保持原值。末轮结构化核对还检查报价金额与早期标记,数据库正确不能替代答复正确。

一轮失败后,后续依赖轮不再执行,其他场景继续。因此需要同时列出计划轮、执行轮和通过轮:

模型 / 策略完整场景 / 计划通过场景 / 计划执行轮 / 计划通过轮
GLM / current0/30/35/172
GLM / structured1/31/37/175
DeepSeek / current2/31/315/1713
DeepSeek / structured3/33/317/1717

原始结果分别在连续任务 GLM与连续任务 DeepSeek。失败原因、执行范围和费用审计见连续任务验收。未执行轮没有被当作通过,两模型整份报告也因其中的策略存在未完成场景而保留 complete=false;DeepSeek 候选自身的三个场景则全部完整通过。

六、按失败原因解释结果 ​

GLM 在两个场景中将客户全称缩写,触发数据库核对失败。这个问题在原策略与候选都出现,不能全部归因于裁剪,也不能为减少失败而放宽全称检查。

两模型的原策略在大草稿修改时都选中了正确行,并保存了正确数量,但调用缺少该批要求的 expected_sku 保护,所以仍判失败。它们不是实际改错 SKU;失败的是保护契约没有满足。

DeepSeek 原策略在末轮丢失最早的独立标记,候选保留原话后正确复述。这支持该固定连续场景中的改进结论,不证明任意长对话的语义记忆。

候选执行了更多后续轮次,直接比较两策略整批总 token 或总费用,会混入执行范围差异。前一组快照实验的输入降幅也不能搬过来,写成本组连续任务的降本比例。时延和业务通过仍应分别评估。

这组实验还区分了阶段内权限:允许的草稿编辑会产生新版本,但不允许提交订单或改变库存。禁止写工具即使被审批拒绝,也算违反该批要求;“零业务写入”不能被扩写成“数据库完全没有任何变化”。

七、让候选保持可选,直到覆盖足够 ​

当前两模型没有共同通过连续任务验收,API / CLI 默认策略没有切换。候选保留用户原话、任务摘要和严格溢出停止,但没有语义约束抽取、跨会话记忆或通用长期记忆模块。

离线可以运行以下现有测试,检查投影、预算边界和临时库工作流;它们不调用真实模型:

bash
uv run pytest packages/agent_core/tests/test_context_view.py packages/evals/tests/test_context_experiment.py packages/evals/tests/test_context_workflow.py

这些测试与真实模型结果分开使用。脚本客户端能从视图找到目标行,证明工程链路可用;真实模型是否稳定保留客户全称、满足保护参数,还要用独立场景验证。

这一系列到这里覆盖了循环、工具、审批、写入恢复、评测、政策证据与多轮上下文。当前能力和未通过项继续以项目状态及各批原始报告为准;后续实现变化需要新的证据,历史文章保留当时的条件与结论。

最后更新:

写清楚每一个技术决策