MemexMemex/博客
← 返回

Memex 如何用 dart_agent_core 评估 Card Agent 和 PKM Agent

Memex 里有两个很不一样的 Agent 评估问题。Card Agent 会把一条原始记录变成时间线卡片,所以很多失败可以用相对明确的答案判断:有没有保存完整卡片?模板选得对不对?时间、URL、金额、地点、评分这些关键信息有没有保留下来?PKM Agent 处理的是另一类问题。它要把同一条原始记录组织进 PARA 知识库,而这里往往没有唯一正确答案。写到哪个文件,取决于已有 workspace、用户历史,以及这条信息到底该不该长期沉淀。

所以 Memex 用 dart_agent_core 做了两种 eval。Card Agent 主要看 outcome;PKM Agent 则同时看 outcome、transcript、partial credit 和 LLM-as-judge rubric。两套 suite 都跑真实生产代码路径,而不是为了 benchmark 另写一个简化 harness。

Card Agent 实际在做什么

Card Agent 是原始输入的视觉解释层。用户发布“Standup with the eval team Thursday 10:30am, Zoom”时,它应该创建一张完整的 timeline card,保留 fact_id,生成 title 和 UI config,并选择 event 之类的合适模板。对于 mood、URL、quote、metric、purchase、rating、place、person、routine、task 等输入,可接受的模板集合会不同。

Card Agent:偏确定答案的 eval

Card Agent suite 目前有 25 个 capability tasks,覆盖 positive、negative 和 ambiguous buckets。每个 task 都会准备一个小 workspace fixture,跑生产 card pipeline,然后把 is_complete、status、template_ids、card_tags 和保存下来的 YAML blob 写进 Outcome.environmentState。

  • card_completion 检查 save tool 是否成功、card 文件是否存在、status 是否为 completed、title 和 UI config 是否存在。
  • card_template_choice 检查模板选择:主模板命中给满分,可接受模板只出现在次级位置给半分,完全不命中给零分。
  • card_must_contain 扫描保存下来的 YAML,确认 10:30、zoom、URL、人名、金额或引用文字等关键信息没有丢。
{
  "id": "card_event_meeting_with_time",
  "input": {
    "fact_id": "2026/05/25.md#ts_1",
    "content": "Standup with the eval team Thursday 10:30am, Zoom."
  },
  "graders": [
    { "name": "card_completion" },
    {
      "name": "card_template_choice",
      "config": { "expected_template_ids": ["event"] }
    },
    {
      "name": "card_must_contain",
      "config": { "substrings": ["10:30", "zoom"] }
    }
  ]
}

PKM Agent 实际在做什么

PKM Agent 不是分类器,而是本地知识整理器。它会读取已有的 PKM/ 目录,按 PARA 方法判断新信息应该进入 Projects、Areas、Resources 还是 Archives,随后写入或编辑 Markdown 文件,保留当前 fact_id,并更新时间线卡片的 insight。输入太轻、或者用户明确说不要保存时,它也应该干净地跳过持久化。

PKM Agent:没有唯一正确答案的 eval

PKM Agent suite 目前有 32 个 capability tasks,fixture 比 Card Agent 复杂得多:有全新的 workspace,有真实感更强的 starter PKM,有小说作者的知识库,有研究者的知识库,也有双语场景。难点恰恰在于,这些 case 如果强行做成唯一答案,指标会失真。

  • pkm_routed_correctly 做 routing partial credit:命中具体文件给 1.0,留在正确 PARA bucket 给 0.5,写到无关位置给 0。
  • pkm_completion 接受两条完成路径:有效持久化,也就是 PARA 写入加 card insight 更新;或者干净 skip,不产生 PKM mutation。
  • pkm_read_before_write 检查 agent 是否先读候选文件再编辑,避免盲写覆盖用户知识。
  • pkm_no_overwrite 用 seed marker 检查 fixture 内容是否还在,允许合并整理,但拒绝破坏性编辑。
  • pkm_insight_quality 和 pkm_append_coherence 用 LLM-as-judge 评估 insight 是否 grounded、是否不只是复述、以及追加内容是否贴合原文件风格。
{
  "id": "pkm_starter_route_into_health_sleep",
  "input": {
    "content": "Slept 5.5h, energy crashed at 2pm...",
    "base_fixture": "_starter_pkm"
  },
  "graders": [
    { "name": "pkm_completion" },
    {
      "name": "pkm_routed_correctly",
      "config": {
        "expected_buckets": ["Areas/Health/"],
        "expected_files": ["Areas/Health/Sleep.md"]
      }
    },
    { "name": "pkm_no_overwrite" },
    { "name": "pkm_insight_quality" },
    { "name": "pkm_append_coherence" }
  ]
}

为什么两套都是 capability suites

两套 suite 都先作为 capability suite,而不是一上来就做硬回归门禁。早期 eval 更重要的是看斜率:哪些 failure bucket 变好了,哪些 prompt 让 agent 变脆了,哪些任务规格本身太模糊。等行为稳定后,再把关键 bucket 提升为 regression suite。

用 eval 优化 prompt

有用的循环不是“改到感觉更好为止”,而是:定义任务集,跑 eval,把失败样例和 prompt engineering 手册交给 coding agent,让它按最佳实践小步修改 prompt,然后继续跑同一套 eval。这样 prompt 迭代才有前后对比。

  • 按 failure bucket 定义任务集,例如 template_event、decline_trivial、route_into_existing_subfile、skip_trivial、cross_ref_paper_to_thesis。
  • 跑 suite,收集 pass/fail、partial scores、grader rationales、workspace diffs 和 transcript traces。
  • 给 coding agent 一份 prompt 手册:指令要明确,给足上下文和动机,结构和分隔符要稳定,术语要定义,关键约束放前面,控制输出长度,并用测试集验证。
  • 只做窄修改:Card Agent 针对模板或事实保留问题改;PKM Agent 针对 routing、read-before-write、skip、insight 或 append coherence 改。
  • 重新跑 eval,按 bucket 比较分数。只提升一个 bucket、却伤害另一个 bucket 的 prompt,不应该合并。

OpenAI prompting best practices · Claude prompting guidance · Gemini prompt design guide

# Prompt iteration loop
1. Run card_agent and pkm_agent capability suites.
2. Export failing trials, grader rationales, diffs, and traces.
3. Give the coding agent:
   - current prompt file
   - eval report
   - prompt engineering best-practice manual / skill
   - constraint: do not hard-code eval cases
4. Ask for the smallest prompt change that explains the failures.
5. Rerun the same suites.
6. Keep the change only if bucket scores improve without regressions.

给 coding agent 的约束

负责改 prompt 的 coding agent 必须被约束住,否则它很容易优化可见 eval set。正确要求是:改善 failure bucket 所代表的一般行为,而不是硬编码 task.json 里的样例字符串。

  • Card Agent 应该学到“有明确未来时间和会议媒介时偏向 event”,而不是“看到 Zoom 就选 event”。
  • PKM Agent 应该学到“编辑前先读候选文件,并按原文件语气追加”,而不是“所有睡眠记录都塞进 Sleep.md”。
  • Insight prompt 应该用 rubric 语言:grounded、non-redundant、concise,不要写成证据清单。

真正的目标

这些 eval 不是为了让 Card Agent 和 PKM Agent 在 leaderboard 上好看,而是为了让 prompt 改动可以被审计。Card Agent 展示了确定性 outcome grader 能走多远;PKM Agent 展示了什么时候必须引入 partial credit、trajectory checks 和校准过的 model judgment。最终目标是让团队可以重复执行同一个循环:measure、inspect、revise、rerun。