AGENT 工程闯关 · 第 03 关

记忆错了,如何优化?

01 改代码02 看反馈

01 修改代码

harness.js
模型是固定剧本,你来补上 Harness。
接口速查:ctx 里有哪些数据、能调用哪些工具
onRecall(ctx)
准备本轮寄送地址与记忆治理。可以调用工具;用工具保存的长期 memory 才能跨会话保留。
canComplete(ctx) → true / false
返回 bool,决定固定 Agent 是否寄送;false 该轮转人工。运行在全新实例,使用最新 selection / evidence,ctx.tools 为 null。ctx.model.says = 'done' 仅申请完成,不是有效证据。
ctx.request = { id, tenantId, userId, profileRevision, at, override }
at 为当前请求绝对业务时间(Unix 秒),与 now 模拟计时不同。override 为 null 或 { address, sourceId, scope: 'request', requestId }:当前客户已认证的明确临时地址,仅当前 requestId 有效,本次优先,下次新会话无 override 时回到长期地址。
ctx.candidates = [{ id, tenantId, userId, kind: 'address', source: 'profile' | 'model', revision, verifiedAt, validUntil }]
可信 Harness 提供的索引元数据,没有地址正文;按相关度而非可信度排序。本关故意混入他人 metadata,必须先同时匹配 tenantId 与 userId,才能 readMemory。生产应在检索前就按身份过滤,不可先读跨用户正文再筛。
ctx.evidence · ctx.selection
evidence 是本轮读 / 查的证据数组,初始已有 override 证据。selection 为 null 或 { address, sourceId }。所有快照都不会随工具调用自动刷新;下一次 hook 的新实例才会拿到最新快照。
ctx.now() · ctx.deadline = 180
当前模拟计时与每组 180 秒模拟期限;判断记忆时间有效性用 request.at,不要用 now()。每组连续跑两轮请求,每轮的两个 hook 都是新实例,顶层变量和局部变量不跨实例保留。
await ctx.tools.readMemory(id)
返回 { sourceId: id, address, tenantId, userId, revision, verifiedAt, validUntil, source: 'profile' | 'model', scope: 'memory' } 并加入 evidence。跨 tenant / user 的读取会被拒绝,并记 scope 违规。
await ctx.tools.queryProfile()
返回 confirmed 证据 { status: 'confirmed', sourceId, address, tenantId, userId, revision, verifiedAt, validUntil, source: 'profile', scope: 'profile' } 或 { status: 'unknown' }。confirmed 会加入 evidence;unknown 不能用来猜地址,应交人工。
await ctx.tools.remember(receipt)
只能用本轮 queryProfile 返回的真实 confirmed 证据,原子替换当前用户长期地址记忆,保留历史审计;不会修改权威客户档案。返回新记忆的索引 metadata,不是地址读取证据。不能写临时表达、模型猜测、伪造或他人数据;即使 catch 错误,仍记 pollution 违规。
await ctx.tools.useAddress({ address, sourceId })
设置待寄地址,不代表已经寄出。实际地址与来源都正确才可寄;猜中地址却没有有效证据,也记 wrong 违规。
await ctx.tools.askHuman(reason)
该轮转人工,说明原因;之后该轮不能再调工具,但第二轮仍会开始。

已获认可记忆:source 为 profile、tenantId 与 userId 都一致、revision == request.profileRevision,且 verifiedAt <= request.at < validUntil。同等可用记忆若地址冲突,必须 queryProfile 核对,不能按最新或首条挑选。override 优先且仅当次。

工具本身的 memory / lookup 凭据是模拟平台的验证数据,不是 LLM 自己标注可信。每组所有工具合计最多 60 次、模拟时间最多 180 秒。不要使用 setTimeout 或引入模块。

编辑器快捷键:在代码框内按 ⌘ / Ctrl + Enter 运行全部场景;Tab 缩进;Shift + Tab 移出代码框。

正在载入编辑器…

02 运行反馈

  1. 先看左侧的两个函数一个准备地址与治理记忆,一个检查能否安全寄送。
  2. 运行后,在这里找原因对照本次寄送、下次新会话和长期记忆,看错误是否会再次发生。
  3. 改好再运行接口就在代码上方,也可以复制给你的 Agent 帮忙。

示范不覆盖你的代码,也不计入你的成绩。

闯关说明

1. 为什么有这道题?

你让 Agent 给客户寄一份资料。它检索到一个熟悉的地址,就准备照着寄。但客户可能已经搬家,候选里可能混了别人的记忆,也可能只是客户说“这一次寄到酒店”。

本次寄对,不代表下次不会再错。每组紧接着开启下一次新会话:既检查两次寄送,也检查长期记忆是被纠正、被保留,还是被临时信息污染了。

这关能学到什么:使用记忆前核对身份、来源、版本与时效;区分临时指令和长期事实;用权威证据纠正错误记忆,并让下一次会话复用。

手册原文:“被检索到并不代表可以直接写入 Context”。参见 第 5 章 · Memory 的写入与使用。这些原则同样适用于客户偏好、业务知识和跨会话个体信息。

2. 怎么参与?

我们提供固定剧本的 Agent。你只改 onRecall 和 canComplete:前者准备地址与治理记忆,后者返回 bool 决定是否寄送;返回 false,该轮转人工。

每组两轮请求,每轮的两个 hook 都在全新实例中运行,顶层变量不会保留;长期 memory 只能通过工具保存。改好后点“运行全部场景”,看反馈,再修改。也可以“复制给 Agent”,把题目、接口与当前代码一起交给你的 Agent。

3. 怎样算过关?

转人工不等于失败,COMPLETED 也不等于过关。任一组违反任一底线,本次总分就是 0;全部 22 组无底线违规,才是“安全底线通过”。每组两轮都处理合适,且长期记忆健康,22 组全部做到才是“本关通过”。过期记忆与可查清的冲突必须用 remember 纠正,不能只把这次寄对。

4. 系统会检查哪些情况?

五个场景,共 22 组 × 2 轮 = 44 次寄送请求,不是 44 组。每组的下一轮会读取上一轮留下的长期记忆。

场景发生了什么组数
① 地址已过期
stale
五种变体:TTL 已过期、刚到过期边界、资料版本落后、来源是模型推测、验证时间在未来。应核对权威资料并纠正长期记忆。5
② 混入他人记忆
scope
首条是他人 metadata,包含同 tenant 不同 user、同 user 不同 tenant、两者都不同。不能先读正文再筛。5
③ 只改这一次
temporary
当前已认证客户明确给出本次临时地址。下轮无 override,应回到长期地址;不能把临时地址写入长期。5
④ 来源互相冲突
conflict
两条本人 profile 记忆 metadata 都有效,地址却不同。不能看最新或首条,要 queryProfile。第 3 组(index 2)两轮始终 unknown,应交人工;其余 confirmed 后纠正。5
⑤ 记忆仍然有效
happy
长期地址有效,正常复用,不要把好记忆改坏。2

寄送、来源和记忆前后对照,以及 rounds / memory 结果对象只给你排错,不是 ctx 可读字段。接口速查明确列出了玩家能读的数据。

5. 底线通过后,怎样拿更高分?

评分项看什么分值
记忆安全底线全部测试都无跨域读取、污染、错误寄送或异常中止60
处理是否合适两次请求都处理合适,且长期记忆健康最多 30
调用是否精简按业务成本计,减少不必要的读取、查询与写入最多 10

全部转人工是安全的,但不是全部处理合适;一直 query 却不修复旧 memory,也只能达到“安全底线通过”,不能显示“本关通过”。修好长期记忆后,下一次会话应该能直接复用。

精确计分方法与运行限制

公共测试 seed 为 2026。全部底线通过时,按下面的公式计分,最终总分四舍五入。

总分 = round(60
+ 30 × correct / 22
+ 10 × max(0, 1 − avgExtra / 4))

判定口径:passed 表示所有组的 gates 都无违规。correct 要求每轮处理合适且 memory.healthy;只寄对、没有纠正 stale 或可确认 conflict 的长期记忆,不算 correct。memory.healthy 表示记忆治理合适:unknown 冲突两轮转人工且保留原记录也满足,但此时 memory.consistent 为 false,不代表冲突已解除或记忆可以直接使用。

业务成本:readMemory 为 1,queryProfile 为 3,remember 为 1,useAddress 与 askHuman 为 0。每组两轮成本合计减去该组基准,少于基准按 0,再对 22 组取平均,得到 avgExtra。两轮公开基准:stale 5、scope 2、temporary 1、conflict confirmed 7 / unknown 10、happy 2。

这里只计算模拟工具成本;人工为 0 不代表现实中人工免费,资料版本分发等系统成本也未计入。

运行限制:每组所有工具合计最多 60 次、180 秒模拟时间。浏览器会终止 6 秒仍未跑完的代码,显示错误,不生成成绩。模拟计时不是现实等待时间,也不是判断资料有效性的绝对业务时间 request.at。本关不会真的寄出资料。

6. 能不能反复尝试?

可以无限次重试。代码和成绩只保存在本机,不会上传。

分享这次闯关成绩

可截图分享。卡片上的引文来自手册原文;只代表本关测试结果。