十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

PostHog ReviewHog 实验解读:claude-fable-5@low 全管线审查运行 F-fable5-low-1 深度剖析

PostHog ReviewHog 实验解读:claude-fable-5@low 全管线审查运行 F-fable5-low-1 深度剖析 PostHog ReviewHog 实验解读claude-fable-5low 全管线审查运行 F-fable5-low-1 深度剖析【免费下载链接】posthog:hedgehog: PostHog is the leading platform for building self-driving products. Our developer tools – AI observability, analytics, session replay, flags, experiments, error tracking, logs, and more – capture all the context agents need to diagnose problems, uncover opportunities, and ship fixes. Steer it all from Slack, web, desktop, or the MCP.项目地址: https://gitcode.com/GitHub_Trending/po/posthog本篇技术文章基于 PostHog 仓库中 ReviewHog 自动代码审查系统的实验运行记录展开核心主题是ReviewHog自动 PR 代码审查管线在 pipeline-models 实验中对claude-fable-5 low这一廉价高吞吐模型组合的完整审查运行F-fable5-low-1。文章将逐步拆解该运行记录的配置快照、漏斗数据、分块策略、审查单元分配与全部 15 条 post-dedup 发现及其验证裁决并结合仓库源码posthog/hogql/property.py、posthog/api/routing.py等说明验证者裁决背后的实现依据。读完本文你将掌握 ReviewHog 单轮审查管线的完整形态、其宽找-严格验证wide-then-strict漏斗的量化解读方法以及如何从一份实验运行记录反推出模型质量与验证严格度的结论。一、运行记录在实验中的位置Fable-5-low 实验臂Arm F1.1 实验背景pipeline-models 实验要回答什么F-fable5-low-1是 pipeline-models 实验2026-07-pipeline-models的三组运行之一。该实验是2026-07-reviewer-model-sonnet5实验的后续其对照控制组Control是上一轮的 B 臂Sonnet 5 xhigh 审查 → Opus 默认验证实验目标是回答两个问题C 臂C-sonnet5val-xhigh验证阶段是否也应该从 Opus 切换到 Sonnet 5 xhighF 臂F-fable5-low审查与验证两个阶段全部使用 claude-fable-5 low—— 一个高端模型 最小推理强度low effort的全管线配置。从配置矩阵PLAN.md可见F 臂的假设是Fable 5 定价为 $10/$50 每百万 token约为 Opus 的 2 倍、Sonnet 5 的 5 倍因此在low推理强度下**靠 token 量塌缩token-volume collapse**来换取总成本持平而风险在于最小推理下的审查深度与验证判定质量。| 臂 | 审查模型 | 验证模型 | 运行数 | | -- | ------------------ | ----------------------- | ------ | | B | sonnet-5 xhigh | opus-4-8 high (默认) | 2 (复用) | | C | sonnet-5 xhigh | sonnet-5 xhigh | 1 | | F | fable-5 low | fable-5 low | 2 |1.2 本运行的关键元数据F-fable5-low-1本身运行记录是对PR #62096冻结于 headba725a89的单次全管线运行报告 ID019f289b-6de5-70e7-8db6-96a343b66a25run_count1statusidle正常完成、未发布——实验运行默认不 publishWall-clock954 秒15.9 分钟是当时两轮实验中最快的一次完整运行配置runtime/model/effort claude/claude-fable-5/low分块门控single-chunk gate 400 行、chunk target 300、soft-max additions 600这些是reviewer/constants.py中控制何时单块、何时走 one-shot 分块、何时回退沙箱分块的阈值需要特别说明的是该实验的历史坑最初的 D1 尝试后改名为 F因为本地 LLM 网关 key 对应的 Anthropic workspace 未开启 data retention所有 fable-5 调用上游 400model_not_available而 agent 的fallbackModel静默降级到 Opus 跑完了整个漏斗且看起来完全正常直到强制的$ai_model检查才暴露。这印证了运行记录与 FINAL_REPORT.md 中的警告漏斗看起来正常不能作为跑的是目标模型的证据。二、漏斗与成本25 → 17 → 7 意味着什么2.1 漏斗各阶段数字运行记录给出该次运行的完整漏斗chunksreview unitsraw issuesafter deduppassed validator31225177chunks 3PR 被切成 3 个逻辑可审查分块与 B/C 臂复用相同的pinned chunks结构保证可比性review units 12即perspective | blind-spot× chunk 的沙箱审查单元数。3 个视角 1 个盲区扫描 4 个镜头 × 3 个 chunk 12这与 ARCHITECTURE.md 中每 chunk 三个独立视角并发 每 chunk 一次盲区扫描的管线描述一致运行记录明确说明 review units 是模型保持恒定的成本代理model-held-constant cost proxyraw issues 25两轮实验至今的最高原始产出此前最高 19after dedup 17去重后存活数也是最高passed validator 7与 C1 持平并列最高之一。2.2 本地 token 统计best-effort运行记录同时给出本地$ai_generationtoken 统计可能为摄入前/部分数据modelgensinput tokoutput tokclaude-fable-517615,799,74277,895claude-opus-4-85458,3793,914total18116,258,12181,809从模型分布可以验证配置是否真的生效176 次 fable-5 生成全部为真实 token0 错误、0 fallback而opus 仅剩 5 次生成、45.8 万输入 token正好对应去重dedup阶段的调用——审查、盲区、验证阶段全部由 fable-5 承担。这与实验 PLAN 中D 验证标准$ai_model claude-fable-5出现在审查和验证生成中opus ≈ 仅 dedup完全吻合。2.3 成本的正确读法从 FINAL_REPORT.md 的跨臂对比表看runraw→dedup→validwall-clockpipeline tokens in/outnaive $B117→11→620.9 min34.5M/240k 2.9M/37k~$87B218→14→6~21 min37.5M/295k 4.4M/44k~$101C118→11→743 min49.9M/352k 3.0M/27k~$119F125→17→715.9 min15.8M/78k 0.5M/4k~$164*F224→13→815.1 min15.0M/79k 0.1M/4k~$155*F1 的输入 token 只有约 1580 万约为 Sonnet 系列运行的 1/3运行时长 15.9 分钟是两轮最快。但朴素定价naive $即列表价 × 原始 token 数、无缓存拆分下 F 臂反而最贵——因为 fable-5 每百万输入 token 价格 $10 吃掉了 3 倍的 token 量优势。然而 Fable 的缓存读取价是 $1/M而 agentic 循环是缓存主导的所以 F 的真实成本可能是最低的——这正是实验报告把扩展dump_result.py按模型拆分$ai_cache_read_input_tokens列为下一步的原因。在缓存拆分数据落地之前实验的结论是不要仅凭成本采纳或否决 F 臂。三、ChunkingPR 被如何切成三块运行记录列出三个 chunk 的文件构成chunk 11 个文件ee/hogai/tools/actions/core.pychunk 24 个文件ee/hogai/tools/actions/tool.py、ee/hogai/tools/actions/__init__.py、ee/hogai/tools/__init__.py、ee/hogai/chat_agent/toolkit.pychunk 34 个文件frontend/src/scenes/max/max-constants.tsx、frontend/src/queries/schema/schema-assistant-messages.ts、frontend/src/queries/schema.json、posthog/schema_enums.py这是一个后端核心实现 后端接入 前端展示与 schema的按层切分core.py 是 CRUD 核心逻辑tool.py 与 toolkit.py 是 Max 工具接入层tool 定义、权限、危险操作门控、默认工具注册前端文件则是聊天 UI 的展示格式化与消息 schema。这与 ARCHITECTURE.md 中按内聚性/导入/层边界分组变更文件、按审查优先级排序的分块原则一致。三个 chunk 被固定pinned复用保证 B/C/F 各臂审查同一批代码、可比性成立。四、Per-review-unit 分解12 个审查单元各自产出了什么运行记录给出每个pass × chunk单元的原始问题数passchunkperspectiveraw issues11contracts-security412contracts-security313contracts-security121logic-correctness222logic-correctness223logic-correctness231performance-reliability332performance-reliability233performance-reliability110001blind-spots-general210002blind-spots-general310003?0关键信息pass 序号 该视角在PERSPECTIVES注册表中的 1-based 位置ARCHITECTURE.md 说明盲区扫描使用保留的 pass 1000 号并被告知哪些镜头已经跑过told which lenses succeededchunk 3前端 schema是产出洼地contracts-security 仅 1 条、performance-reliability 仅 1 条、blind-spots 0 条——只有 logic-correctness 稳定产出 2 条。说明前端展示层代码的可发现缺陷密度远低于后端工具层盲区扫描合计 5 条230正是 post-dedup 中多个blind-spots-general来源发现的来源。五、Findings 全景7 条有效 vs 8 条被驳回post-dedup 共 15 条发现每条都带有 validator 裁决。统计如下VALID保留7 条must_fix· security ·list_actions暴露用户被拒绝的对象级访问权限tool.py:61-73consider· bug · 无名动作的分页排序不完全确定core.py:147-150should_fix· bug · 负 limit/offset 导致未处理异常而非可重试错误core.py:56-60,148-150should_fix· bug · Max 路径 CRUD 跳过了 REST 路径的report_user_action产品分析core.py:192-205,208-226,229-233consider· bug · 动作名未 strip空白变体绕过重名检查core.py:181-189,195-200,217-219should_fix· bug · 元素匹配 step 字段在非$autocapture时被静默忽略step 变成全匹配tool.py:47-51,98-105should_fix· bug · 畸形 LLM 属性过滤器被静默编译为全匹配常量tool.py:98-105,116-129DISMISSED驳回8 条删除审批流重复查询、未截断动作名插入状态标签、未验证的properties: list[dict]、存储的动作名/描述被原样渲染进 agent 上下文、危险操作流重放预览参数、默认工具未加入DEFAULT_TOOL_KEYS、get/delete 展示标签不标识动作、描述未截断削弱上下文窗口上限、重名检查与保存非原子、update_action 无审批门控可破坏性清空语义等。这正体现了 ReviewHog 的宽找-严格验证分工ARCHITECTURE.md 中明确讨论过 55 条原始 → 48 去重 → 12 验证的 75% 淘汰率finder 故意买广度validator 用团队拥有的标准把噪音砍掉。六、核心发现深度解读结合仓库源码以下选择几条最具代表性的发现结合当前仓库源码说明其实现依据。6.1 [VALID] must_fixlist_actions绕过对象级访问控制安全这是本次运行唯一保留的must_fix。问题ListActionsTool只检查资源级权限(action, viewer)然后调用list_actions其查询Action.objects.filter(teamteam, deletedFalse)没有任何对象级访问过滤。而 REST 列表路径则不同TeamAndOrgViewSetMixin的_filter_queryset_by_access_level会在每次 list 时应用user_access_control.filter_queryset_by_access_level(queryset)——该实现位于 posthog/api/routing.py且仅对action list生效单对象获取由权限逻辑处理。因此一个被显式授予对象级 none AccessControl 行的动作在 REST 列表中被隐藏却通过 Max 的list_actions把名称、描述、完整 step 定义含 ID可进一步发起 get/update泄露出去。验证者进一步佐证同 PR 已为 get/update/delete 补上了check_object_accesstool.py 各入口说明作者认可对象级限制在作用域内list 是唯一遗留缺口而 Max 自己的实体搜索上下文ee/hogai/context/entity_search/context.py已经正确调用filter_queryset_by_access_level因此该工具既偏离 REST 契约也偏离既有 Max 模式。建议的修复是把self.user_access_control传入list_actions在 team/deleted 过滤之后应用filter_queryset_by_access_level(qs)在qs.count()之前保证总数与页一致。值得注意这条发现后来成为整个实验最具争议的裁决disputed finding——在 FINAL_REPORT.md 中该 access-control 家族被 6 位独立 judge 以 3:3 分裂F1 的 validator 判定 VALIDF2 的 validator 判定 VALID 并升级到 must_fix而其他轮的 judge 则有 3 次反驳反驳方最强论据是viewer 访问下限与 actions 的访问控制在同一 commit 落地none 行根本不可能存在REST 列表过滤对 actions 是 no-op。实验结论是双方都引用了真实代码此调用必须由 PostHog RBAC 负责人人工裁决无法用更多 LLM 意见解决。6.2 [VALID] should_fix非$autocapture的元素匹配字段被静默丢弃 → 动作变成全匹配静默错误数据这是最重要的静默错误数据类发现。字节码编译器只在step.event $autocapture时才处理selector、tag_name、text/text_matching、href/href_matching。当前仓库 posthog/hogql/property.py 的steps_to_expr实现可见def steps_to_expr(steps: list[ActionStepJSON], team: Team, events_alias: Optional[str] None) - ast.Expr: if len(steps) 0: return ast.Constant(valueTrue) # 零步动作 → 匹配一切 ... if step.event AUTOCAPTURE_EVENT: # 元素匹配全部被这个门控挡住 if step.selector: exprs.append(selector_to_expr(step.selector)) ...因此若 LLM 创建{selector: button.cta, text: Sign up}却没设置event: $autocapture所有元素条件被丢弃exprs为空step 被编译为Constant(True)——动作静默匹配项目中的每个事件。工具层没有任何护栏ActionStepInput不校验该组合工具描述也只在示例里提到$autocapture而_format_step输出会原样回显selector...让模型和用户都误以为条件生效。REST UI 永远不会踩到这个坑因为 UI 的元素选择器隐式设置事件为$autocapture。这是一个比报错更糟的静默错数据任何建立在该动作上的 insight、funnel、CDP 目标都会被污染。建议修复在ActionStepInput加 model validator提供非$autocapture事件时抛ActionToolError或自动置event $autocapture并在工具描述中显式声明约束。6.3 [VALID] should_fix畸形属性过滤器被静默编译为匹配一切常量同类静默错数据问题的另一面ActionStepInput.properties接受任意list[dict]dict 未经校验直接进入Action.steps→refresh_bytecode→property_to_expr。property_to_expr在非严格模式下故意吞掉ValueError/TypeErrorpydantic 的ValidationError是ValueError子类把畸形 dict 降级为ast.Constant(value1)——过滤器变成匹配一切。若模型输出了错误形状如{property: plan, equals: pro}而非{key, value, operator, type}create_action/update_action成功、工具输出报告1 property filter(s)动作却静默过度匹配且_format_step的回显让问题不可见。REST 路径虽有同样的宽松编译但其输入来自 UI 的结构化属性选择器而这是全新的 LLM 自由格式输入入口。建议在工具边界做严格校验strictTrue编译 try/except →ActionToolError把静默损坏变成可纠正的重试。6.4 [VALID] should_fixMax 路径 CRUD 遗漏report_user_action产品分析盲区扫描blind-spots-general发现REST 路径每次变更都会发产品分析事件——ActionSerializer.create调用report_user_action(user, action created, ...)update发 action updatedsoft-delete 也走 update 事件。而新工具的create_action/update_action/delete_action一个都没发。PR 明明刻意复刻了 REST create 路径的其他副作用activity 日志经_acting_user、check_count_limit遥测——core.py:196 的注释明说 Emit the same resource limit hit telemetry the REST create path does却唯独漏掉report_user_action。其后果是通过 Max 创建的每个动作在 PostHog 自身的使用分析中不可见随着 agent 驱动 CRUD 增长action 采纳指标会系统性低估且无法区分/度量 Max 来源的动作管理。验证者确认了姊妹 Max 写工具upsert_dashboard已在工具路径调用report_user_action带EventSource标记且有测试断言因此这是既有约定的遗漏而非特例。建议在三个写操作后补report_user_action并可加created_via: max_tool标记以便在分析中区分 agent 驱动 CRUD。6.5 [VALID] should_fix负 limit/offset 导致未处理异常ListActionsToolArgs.limit/offset是无界Optional[int]幻觉出的负值如offset-1、limit-5能通过 pydantic 校验到达 queryset 切片qs[start : start capped_limit]Django 对负切片抛裸ValueError(Negative indexing is not supported.)。由于不是ActionToolError无法被映射为MaxToolRetryableError工具调用以未处理异常失败而非给 agent 一条可自我纠正的错误消息。值得注意min(limit, MAX_LIST_LIMIT)还会静默接受负数与字段描述声称的 1-100 范围矛盾。验证者指出姊妹 list 工具已有先例ee/hogai/tools/list_feature_flags.py:39-40、ee/hogai/tools/list_data.py:55-56、ee/hogai/tools/read_taxonomy/core.py:15-16都用Field(ge1, leN)/Field(ge0)。修复是一行 schema 约束。6.6 被驳回发现的规律validator 的精度优先标准8 条被驳回发现几乎都落在 review-hog-validation-criteria 技能 定义的 drop 类别里可以归类为投机性 what-if / 永不发生的边界未截断描述削弱上下文窗口上限需要几十个多 KB 描述的动作才可能validator 裁定为 contrived未截断动作名插入状态标签React 转义字符串无注入风险最多是装饰性长状态行删除审批流重复查询发现者自己承认重查是正确行为建议仅是加注释validator 判定为 taste已处理already handled_reconstruct_kwargs_from_payload会用args_schema.model_validate(payload)重新校验恢复载荷ee/hogai/tool.py:406-415pydantic 会把字符串化 ID 42 强转 int畸形 ID 直接校验失败——框架已在快乐路径上排除该情况错误的既有前提 平台级问题未验证properties导致 save() 崩溃property_to_expr非严格模式已吞掉 ValueErrorbytecode 能编译且 REST 契约本身同样宽松存储的动作名/描述渲染进 agent 上下文所有 Max 读工具的共同行为平台层才是真正的缓解位置危险操作门控已覆盖 delete与既有行为一致重名检查非原子REST 序列化器同样的 TOCTOU产品级修复需要部分唯一索引超出工具面 PR 范围update_action无审批门控REST PATCH 同样直接替换 steps且活动日志经ModelActivityMixin可恢复steps: []编译为Constant(True)是平台长期语义纯 UI 策展/品味新工具未加入DEFAULT_TOOL_KEYS经查该列表本来就是策展子集todo_write、create_form、create_notebook同样缺席后果仅是 ModeSelector 提示不列举新工具get/delete 标签不显示动作DeleteActionTool已有format_dangerous_operation_preview在审批流中识别动作。这套裁决逻辑正是 SKILL.md 的precision over recall无法同时命名具体触发器与具体后果的发现要持怀疑态度过工程化、投机、防御性偏执、永不发生的边界、纯风格、已处理、错误前提都要 drop。七、从运行记录到实验结论F1 的价值与局限在 FINAL_REPORT.md 的跨臂评判中F1/F2 与 B/C 组合在一起得出以下可复现结论每个被测试的验证模型都是精确的judge 评估的裁决准确率——fable-5low 约 15/17F1、12/13F2与 sonnet-5xhigh≈10.5/11和 opus 默认相当五轮运行中几乎零无争议垃圾被发布严格验证属性在每种模型下都成立Fable-5low 是不同运行点且可复现25/24 原始发现历史纪录、7/8 有效8 为历史最高、15-16 分钟完成、约 1500 万输入 tokenSonnet 体积的 1/3。judge 验证了每轮有 4-5 条真正新颖的强发现包括两个全新类别strictFalse属性编译静默过度匹配get→update 往返静默丢弃属性过滤器但旧基准old-10 yardstick覆盖率一般约 3/10 有效噪音尾巴真实存在每轮 5-7 条全部被 validator 击杀成本排序在价格上反转朴素美元下 F ≈ $155-164 C1 ≈ $119 B ≈ $87-101但缓存读取价 $1/M 可能让 F 成为真实最便宜的臂——缓存感知计数落地前不采纳也不否决chunk-3/chunk-2 的基准盲区在四种模型配置下持续存在#1、#4、#8、#10 在所有 5 轮中都被漏掉结论性地表明这是视角技能内容问题而非模型/强度问题——任何模型/强度/验证者变更都找不到它们必须让视角技能显式猎取这些场地F1 的 validator 对旧 #10 的驳回理由事实错误React escapes strings而 judge 验证了 Markdown 图片外渗向量真实存在——fablelow 的两处判定错误都发生在真正有争议的调用上#6 的驳回、access-control 家族。实验的最终裁决FINAL_REPORT 与 PLAN.md 的 locked decisions是validator 采纳 sonnet-5 xhigh用户立即翻转VALIDATION_*常量验证阶段从此与审查阶段同为 Sonnet 5 xhigh仅 dedup/chunking 保留 agent 默认Fable-5low 作为快速扫描候选保留等待真实成本数据access-control 争议发现需人工裁决技能内容轮次已到期。八、如何在本地复现与进一步研究如果你希望亲自跑一遍 ReviewHog 管线或复现此类实验可以按 ARCHITECTURE.md 的 preflight 检查Temporal worker 运行中、ngrok 隧道齐全、目标 PR 可审查、无残留报告后执行flox activate -- bash -c DJANGO_SETTINGS_MODULEposthog.settings python manage.py \ run_review --pr-url https://github.com/PostHog/posthog/pull/N --team-id 1 --user-id 1 [--publish]实验本身不发布--publish缺省关闭dump 脚本与运行日志在products/review_hog/eval/下RUN_LOG.md、POTENTIAL_EXPERIMENTS.md本实验的姊妹运行记录F2、C1、G1/G2也都在products/review_hog/eval/experiments/2026-07-pipeline-models/runs/目录下可对照阅读以观察同一 PR 在不同模型臂下的发现差异。值得深入阅读的相关文件ReviewHog 架构总览 — 管线的 10 阶段、沙箱执行层、数据模型、提示词与技能体系ReviewHog 决策记录 — 各阶段构建历史与设计权衡验证标准技能 — validator 的 keep/drop 判定标准本文第 6.6 节的依据pipeline-models 实验计划与报告 与 FINAL_REPORT.md — 实验设计、成本表、old-10 覆盖率与争议发现HogQL 属性编译 —steps_to_expr的$autocapture门控与零步Constant(True)语义REST 访问级过滤 —_filter_queryset_by_access_level的 list 路径实现需要提醒的是本文所分析的ee/hogai/tools/actions/*PR #62096 的审查对象在当前仓库主干中尚未存在——它是实验审查的被测代码被冻结在 headba725a89上因此文中对它的行号引用均来自运行记录原文而底层依据steps_to_expr、_filter_queryset_by_access_level、property_to_expr等已在当前主干源码中验证存在。【免费下载链接】posthog:hedgehog: PostHog is the leading platform for building self-driving products. Our developer tools – AI observability, analytics, session replay, flags, experiments, error tracking, logs, and more – capture all the context agents need to diagnose problems, uncover opportunities, and ship fixes. Steer it all from Slack, web, desktop, or the MCP.项目地址: https://gitcode.com/GitHub_Trending/po/posthog创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表