ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

PostHog ReviewHog 架构决策实录:为何评论解决(Resolution)是独立的 Temporal Workflow 而非 Review 的一个阶段

2026/9/20 11:52:39 拓冰建站 浏览量
PostHog ReviewHog 架构决策实录:为何评论解决(Resolution)是独立的 Temporal Workflow 而非 Review 的一个阶段 数据分析后端前端数据可视化大数据【免费下载链接】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 的自动化代码评审产品 ReviewHogproducts/review_hog在完成了对 PR 的评审并发布之后还会进一步处理 PR 上未解决的评审线程分诊triage、回复、必要时直接在 PR 分支上实现修复并自动 resolve。这个评论解决能力在架构上被设计为与评审review-pr完全独立的第二个 Temporal Workflowresolve-pr而非评审流水线的后置阶段。本文以 ADR 记录 0001-resolution-is-a-separate-workflow.md 为核心结合仓库源码backend/temporal/下的 workflow、client、types 与 resolution 实现展开讲解这一决策的三个核心理由、其代价跨阶段协调必须手工构建以及对应的 busy-guard 等配套机制帮助读者理解何时该把一段业务切分成独立工作流的工程判断。一、决策背景评审之后评论还要被解决ReviewHog 的单轮评审由ReviewPRWorkflowTemporal workflow 名review-pr定义于 workflow.py编排拉取 PR → 分块 → 多视角并行评审 → 去重 → 验证 → 生成报告并发布评论。但评审发布不是终点——发布后PR 上仍会残留大量未解决的评审线程ReviewHog 自己的发现、其他机器人的评论、人类的讨论。解决阶段resolution stage负责把这些线程逐一收尾对值得修复且安全的线程直接在 PR 分支上实现修复并回复对人类线程保持礼貌回复但从不自动 resolve把最终决定权留给人类对其他机器人的线程依据判定结果回复/解决。在 ARCHITECTURE.md 中resolution stage 被描述为post-review, standalone-capable stage——它既可以作为评审的延续也可以独立运行。正是standalone-capable可独立运行这一要求直接催生了本文 ADR 的决策让解决逻辑以独立 Workflow存在而不是并入评审 Workflow 作为一个后验证阶段。二、三个否决合并方案的核心理由ADR 明确记录了曾考虑过的备选方案把 resolution 折叠进 review workflow作为发布之后的post-validation stage后验证阶段。最终被否决理由有三逐一展开。理由一独立解决是一等公民合并后仍需要第二个入口/resolve命令对应POST /api/review_hog/resolve与run_resolution管理命令以及 inbox 交接inbox handoffs需要去处理ReviewHog 从未评审过的 PR 上的评论——那些线程可能是人类、其他机器人留下的。如果 resolution 只是 review workflow 里的一个阶段那么要独立触发它就仍然需要一个只有 resolution、没有 review的入口——等于还是要有一个第二套触发路径。与其维护同一工作流内的两套入口 阶段开关不如干脆把它建成独立的一等公民 Workflow。源码印证了这一点client.py 的模块注释明确写道ReviewPRWorkflow— the single-turn review …ResolvePRWorkflow— triaging and settling a PRs unresolved review threads并且两条入口各配一套阻塞式 CLI 触发execute_review_pr_workflow/execute_resolution_workflow与非阻塞式生产触发start_review_pr_workflow/start_resolution_workflow结构完全对称。理由二resolution 崩溃绝不能拖垮已发布的评审——abandoned child 免费提供这道接缝这是最关键的解耦点。评审已经发布到 PR 上之后resolution 阶段才开始运行且运行时间长每线程一个沙箱轮次修复验证的轮次动辄数分钟整体可达小时级。如果 resolution 是评审工作流内的一个阶段那么 resolution 的任何失败/重试都会波及已经完成的评审发布而作为abandoned child被父工作流以ParentClosePolicy.ABANDON派发后与父解耦的子工作流父工作流评审发布完即可结束子工作流解决独立存活、独立失败、独立重试——**一个 resolution 崩溃必须不能使已发布评审失败**这一约束被架构免费满足。源码中可看到这条接缝的落点。在 workflow.py 的ReviewPRWorkflow._run末尾发布完成之后resolve_after ( inputs.resolve_comments if inputs.resolve_comments is not None else (inputs.publish and acting.resolve_comments) ) if resolve_after and meta.pr_number is not None: await workflow.start_child_workflow( resolve-pr, ResolvePRWorkflowInputs(...), idresolve_pr_workflow_id(...), parent_close_policyParentClosePolicy.ABANDON, id_reuse_policyWorkflowIDReusePolicy.ALLOW_DUPLICATE, )两处细节值得注意parent_close_policyParentClosePolicy.ABANDON父工作流review结束时不再等待/终止子工作流resolve子工作流继续独立运行——这就是 ADR 所说的 abandoned-child seam派发是fire-and-forget、best-effort的workflow.start_child_workflow的异常被捕获并只记日志Could not dispatch the resolution stage; the review is unaffected保证派发失败也绝不反噬已完成的评审。理由三两条短历史独立版本化互不引入非确定性Temporal 工作流是确定性重放模型工作流代码一旦改变in-flight 实例的历史重放就可能产生非确定性错误。如果把 review 和 resolution 合成一个长工作流那么编辑其中任何一段的命令序列activity 调用顺序都会给另一段的 in-flight 运行带来非确定性风险。分成两个独立、各自身短的 Workflow 后两边的历史独立演进改 resolution 阶段不会影响正在运行的 review改 review 也不会影响正在运行的 resolve。三、代价与配套跨阶段协调必须手工构建ADR 的 Consequences 部分明确承认了这一决策的代价Cross-stage coordination is manual: Temporals same-id joining dedups review-vs-review and resolve-vs-resolve but cannot see across the two.Temporal 的 same-id joining同一 workflow id 重复触发时复用/合并运行只能在同一类工作流内生效review-pr对review-pr、resolve-pr对resolve-pr。而 review 与 resolve 是两个不同的 workflow id 命名空间Temporal 自己看不见这个 PR 的评审/解决周期当前是否正忙。因此is this PRs cycle busy?这个 PR 的周期是否正忙这类跨阶段检查必须由应用层显式实现。ADR 记录该问题于 2026-08-13 决定并在设计 resolution-stage 可见性时再次确认。busy-guard跨工作流的显式忙碌探针对应的实现是 client.py 中的workflow_running(workflow_id)def workflow_running(workflow_id: str) - bool: try: client sync_connect() description async_to_sync(client.get_workflow_handle(workflow_id).describe)() except RPCError as e: if e.status RPCStatusCode.NOT_FOUND: return False logger.warning(Busy-guard describe failed for %s: %s, workflow_id, e) return False except Exception: logger.exception(Busy-guard describe failed for %s, workflow_id) return False return description.status WorkflowExecutionStatus.RUNNING关键设计点确定性 id 是前提两个工作流各自用确定性 idreview-pr:team:owner/repo:pr与resolve-pr:team:owner/repo:pr见 types.py 的review_pr_workflow_id/resolve_pr_workflow_id均小写化以便在 Temporal UI 搜索busy-guard 才能按 id 精确 describefail-open打开即失败豁免除 not-found 外的一切探针错误describe 抖动、临时故障都返回 False——触发器不应因一次 describe 失败就 500真正的 Temporal 故障会在随后的 start 调用上暴露策略含义review-pr运行时拒绝启动resolve-pr独立 resolveresolve-pr运行时拒绝启动review-pr唯独评审发布后链式派发 resolve这一路径天然免检——它由父工作流按确定性规则在恰当时机派发不会与自身冲突。这条豁免正是 ADR abandoned child 接缝带来的另一项收益见 ARCHITECTURE.md 的 Resolution visibility the busy-guard 一节。跨阶段可见性从 artefact 推导 resolution 运行状态跨阶段协调是手动的的另一个落点是状态可见性。resolution 运行期间评审 API 与 PR 状态评论必须能回答当前 resolve 跑到哪了。ReviewHog 的做法不是新增一套进度簿记而是从已持久化的 artefact 推导reviewer/progress.py::resolution_states运行开始时_prepare_run写入一个resolution_run工作清单 artefact排队的线程 id 计数运行中每个已交付 verdictreply_postedTrue的thread_verdictartefact 计入完成数完成以一条author review_hog_resolution的收尾 note 为准没有收尾 note 且超过 30 分钟静默窗口IN_PROGRESS_STALE_AFTER则判定为中途死亡stopped。PR 评论侧的计数器只统计 GitHub 写入真正落地的线程delivered_outcomes已判定但未投递的线程计入收尾统计的 couldnt handle 计数绝不虚报。此外每个排队线程的开启评论会被打上一个 best-effort 的 反应作为本运行排队中标记github_threads.py::add_eyes_reaction重复添加无副作用、永不移除。这些机制共同把两个独立工作流对用户呈现为连贯的单一进度体验。四、独立 Workflow 内部的容错设计侧面印证决策的合理性既然 resolve 是独立的一等公民工作流它的容错就必须自洽——ResolvePRWorkflowresolution.pyworkflow 名resolve-pr的结构恰好印证了这一点设置阶段复用评审流水线validate_github_integration_activity→sync_review_skills_activity→generate_schemas_activity与 review 一致一个超长 activity 持有整个会话resolve_threads_activity因为沙箱会话是进程内句柄、不能跨 activity 边界所以一次 activity 跑完整个 PR 的解决会话start_to_close_timeout4h、每 5 分钟心跳、RESOLUTION_MAX_ATTEMPTS次重试按线程幂等而非按 activity 幂等每个 verdict 在产生副作用前先持久化为thread_verdictartefactactivity 重试时通过确定性预过滤github_threads.py 的classify_thread无 verdict / 有水印更新的评论 → 重新分诊verdict 已判定但回复未投递 → 只补投递两者皆已完成 → 跳过只花 LLM 轮次在真正剩余的工作上投递侧再加固FIXED 判定中的 commit SHA 是模型回声投递前服务端先commit_on_branch证明可达、再inspect_fix_commit证明出处我们的 app bot 签名提交触碰.github/、CODEOWNERS、依赖清单等受限路径的修复提交只发人工复核警告且永不自动 resolve——详见should_resolve与_deliver_side_effects工作流级兜底fail_resolution_activity由ResolvePRWorkflow的 except 分支触发带workflow.patched(fail-resolution-cleanup-2026-08)版本门控覆盖 activity 自身 handler 看不见的死亡形态——prepare 失败、超时、取消、worker 死亡——把报告复位并依据持久化工作清单改写失败状态段。这些层层加固都建立在resolution 是独立工作流的前提上正因为它是独立的它才可以拥有自己独立的超时、重试策略、兜底清理和幂等协议而不必与 review 的历史耦合。五、工程启示小结ReviewHog 的这条 ADR 是一个典型的拆 vs 合架构权衡案例可提炼为三条可复用的判断标准当子能力需要独立入口且入口触发方是第三方/异构来源时合并没有省掉第二个入口只是把入口藏进同一工作流——此时独立工作流更诚实当子能力运行时间长、失败语义与父能力必须彻底隔离时abandoned child 接缝是父成功发布、子独立重试的最廉价实现当两段逻辑独立演进、互不希望被对方的代码变更引入非确定性时短而分离的工作流历史优于长而耦合的工作流历史。其代价同样清晰Temporal 的 same-id joining 这类内置机制无法跨工作流生效凡是这个 PR 当前在忙什么这类跨阶段问题都必须像 ReviewHog 的workflow_runningbusy-guard 和resolution_states状态推导一样由应用层显式建模。对这一决策的完整论证脉络含 resolution-stage 可见性的再次确认可进一步阅读 DECISIONS.md 的 Stage 7 与 CONTEXT.md 的 Busy-guard、Work-list、Resolution etiquette 等章节。赞分享数据分析后端前端数据可视化大数据【免费下载链接】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 决策解析采用已有团队技能为何是复制而非引用PostHog ReviewHog 决策解析采用已有团队技能为何是复制而非引用 本文基于 PostHog 仓库中 ReviewHog 产品的架构决策记数据分析后端前端数据可视化大数据PostHog ReviewHog 设计决策全记录从 CLI 到 Temporal 自动代码审查的四阶段构建之路PostHog ReviewHog 设计决策全记录从 CLI 到 Temporal 自动代码审查的四阶段构建之路 在 PostHog 仓库中 product数据分析后端前端数据可视化大数据PostHog ReviewHog 验证准则如何裁决一个 PR 评审问题是否值得保留PostHog ReviewHog 验证准则如何裁决一个 PR 评审问题是否值得保留 导读 本文讲解 PostHog 仓库中自动化代码评审产品 ReviewH数据分析后端前端数据可视化大数据创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考