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 |
|---|---|---|---|
| GLM | full | 9/10 | 124062 |
| GLM | current | 2/10 | 68965 |
| GLM | structured | 8/10 | 25720 |
| DeepSeek | full | 10/10 | 124696 |
| DeepSeek | current | 2/10 | 69202 |
| DeepSeek | structured | 9/10 | 26300 |
原始结果见 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 / current | 0/3 | 0/3 | 5/17 | 2 |
| GLM / structured | 1/3 | 1/3 | 7/17 | 5 |
| DeepSeek / current | 2/3 | 1/3 | 15/17 | 13 |
| DeepSeek / structured | 3/3 | 3/3 | 17/17 | 17 |
原始结果分别在连续任务 GLM与连续任务 DeepSeek。失败原因、执行范围和费用审计见连续任务验收。未执行轮没有被当作通过,两模型整份报告也因其中的策略存在未完成场景而保留 complete=false;DeepSeek 候选自身的三个场景则全部完整通过。
六、按失败原因解释结果
GLM 在两个场景中将客户全称缩写,触发数据库核对失败。这个问题在原策略与候选都出现,不能全部归因于裁剪,也不能为减少失败而放宽全称检查。
两模型的原策略在大草稿修改时都选中了正确行,并保存了正确数量,但调用缺少该批要求的 expected_sku 保护,所以仍判失败。它们不是实际改错 SKU;失败的是保护契约没有满足。
DeepSeek 原策略在末轮丢失最早的独立标记,候选保留原话后正确复述。这支持该固定连续场景中的改进结论,不证明任意长对话的语义记忆。
候选执行了更多后续轮次,直接比较两策略整批总 token 或总费用,会混入执行范围差异。前一组快照实验的输入降幅也不能搬过来,写成本组连续任务的降本比例。时延和业务通过仍应分别评估。
这组实验还区分了阶段内权限:允许的草稿编辑会产生新版本,但不允许提交订单或改变库存。禁止写工具即使被审批拒绝,也算违反该批要求;“零业务写入”不能被扩写成“数据库完全没有任何变化”。
七、让候选保持可选,直到覆盖足够
当前两模型没有共同通过连续任务验收,API / CLI 默认策略没有切换。候选保留用户原话、任务摘要和严格溢出停止,但没有语义约束抽取、跨会话记忆或通用长期记忆模块。
离线可以运行以下现有测试,检查投影、预算边界和临时库工作流;它们不调用真实模型:
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这些测试与真实模型结果分开使用。脚本客户端能从视图找到目标行,证明工程链路可用;真实模型是否稳定保留客户全称、满足保护参数,还要用独立场景验证。
这一系列到这里覆盖了循环、工具、审批、写入恢复、评测、政策证据与多轮上下文。当前能力和未通过项继续以项目状态及各批原始报告为准;后续实现变化需要新的证据,历史文章保留当时的条件与结论。