💡 没有自动eval的Agent项目就是定时炸弹:prompt改一行、模型换一个版本都可能让准确率崩盘。今天把Day 12的eval dataset接上CI,让每个PR自动跑回归测试。
难度警告:本day涉及CI/CD、并发控制、统计分析,是Week 4最硬的一天。
引导问题:
答案揭示:
手动测试的问题:
自动eval的价值:
引导问题:
答案揭示:
设计要求:
agent eval --dataset eval.jsonl --out report.json--threshold 0.85,低于就exit非零--max-concurrency限速,--mock本地测试引导问题:
答案揭示:
分层策略:
关键字段:
id: 稳定IDinput: 用户消息expected_*: 期望结果(可能是answer、tool序列、action等)tags: 分类,可按tag过滤和统计Judge的陷阱:
关键设计:
full-eval label触发全量if: always())平衡成本和覆盖。
初始化:
警戒线:
防止改prompt专门过eval的问题:
evalrunner二进制--dataset --threshold --out --concurrency./evalrunner --dataset evals/dataset.jsonl能跑通.github/workflows/eval.ymlQ: Eval太贵,怎么省钱?
A:
gpt-4o-mini作为被测模型gpt-4o-mini也行(准确率略降)Q: Flaky eval怎么办?
A:
@flaky,不计入pass rateQ: GitHub Actions超时?
A:
--concurrency 10)Q: 怎么追踪历史趋势?
A:
evals/history.jsonlQ: Eval改动也要review吗?
A: 必须!dataset属于"考试题",改题要和改代码分开PR review,避免"改题来过eval"。
题目: 设计一个算法,将二叉树序列化为字符串,并能从该字符串反序列化还原原始树。序列化/反序列化的格式不限,但需要自洽。
思路: 用 BFS(层序遍历)序列化:逐层入队,空节点记为 "#",非空节点记录值,各节点用逗号分隔。反序列化按同样层序顺序重建:用队列记录待分配子节点的父节点,依次从 tokens 中取值挂左/右子树。
复杂度: 时间 O(n),空间 O(n)(队列最大存一层节点,最差 n/2)。
变体/面试追问:
题目: 给定一个二叉树,找出路径节点值之和最大的路径。路径可以从任意节点出发,到达任意节点,不必经过根节点,但每个节点最多出现一次。
思路: DFS 后序遍历。对每个节点,分别计算左、右子树能贡献的最大单向路径和(负数则取 0,表示不选)。以当前节点为"弯折顶点"时,最大路径和 = node.Val + left + right,用全局变量记录最大值。函数返回值只能是单向路径(node.Val + max(left, right)),供父节点使用。
复杂度: 时间 O(n),空间 O(h)(h 为树高,递归栈)。
变体/面试追问:
题目: 给出前序遍历和中序遍历的结果,构造出原始二叉树。假设树中没有重复值。
思路: 前序遍历第一个元素是根节点。在中序遍历中找到根节点位置,其左侧为左子树的中序序列,右侧为右子树的中序序列。用哈希表缓存中序索引,避免每次线性查找,将总复杂度从 O(n²) 降至 O(n)。
复杂度: 时间 O(n),空间 O(n)(哈希表 + 递归栈)。
变体/面试追问:
明天我们会:
准备问题: