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。