ARTICLE DETAIL

资讯详情

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

PostHog PR 描述写作技能实战解析:从三个已合并 PR 看五遍打磨如何缩短正文

PostHog PR 描述写作技能实战解析:从三个已合并 PR 看五遍打磨如何缩短正文 PostHog PR 描述写作技能实战解析从三个已合并 PR 看五遍打磨如何缩短正文【免费下载链接】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 开源仓库中的技能文档.agents/skills/writing-pr-descriptions/references/examples.md为骨架完整解析该技能如何把 PR 描述写成审阅者扫一眼就能定位注意力的扫描面先是三个已合并 PR 的端到端改写实例一次重排、两次删减再补上技能主文件.agents/skills/writing-pr-descriptions/SKILL.md的五遍工作法Pass 0–5以及posthog/models/flag_evaluations/sql.py、posthog/clickhouse/migrations/下的真实源码作为证据。读完后你将掌握一套可复制的 PR 正文写作流程效果前置、逐条删减、逐条成句、短句主动语态以及正文必须比初稿更短的可检查自检标准。为什么 PR 正文是扫描面而不是文章技能文档开宗明义审阅者用几秒钟扫描一段描述然后决定把注意力花在哪里。正文必须脱离 diff 独立成立stand without the diff因为许多审阅者直接看代码只有当正文赚到注意力时才会回头读它。两个关键词贯穿全文顺序Order决定理解审阅者是否理解改动取决于信息排列形式与长度Form and length决定速度同一事实用哪种载体最快传递。因此技能规定先解决顺序绝不为了形式牺牲顺序并要求以五遍工作法推进lead效果前置、route路由到形式、cut删减、shape塑形、check自检。已有正文时先做 Pass 0 保留现场。Pass 0编辑已有正文而不是覆盖gh pr edit --body会替换整个正文因此草稿中没有归宿的部分一推送就会消失。已有正文里藏着无法重建的工作人工上传的截图与录制、收集的链接、勾选的复选框、写给指定审阅者的备注。标准流程来自 SKILL.mdgh pr view number --json body --jq .body pr-body.md # edit pr-body.md gh pr edit number --body-file pr-body.md把已有正文中的每一张图片、每段视频、每个链接、每个已勾选项都带进新正文放到它所属的标题之下只有改动使其不再成立时才替换并在正文中说明替换理由。Pass 1第一行写效果不写机制第一行是唯一保证被读到的行。写作者刚在机制里泡了一小时机制会自然先冒出来——技能要求把它压下去把这一行留给人体验到了什么。四个形状覆盖几乎全部 PR修复fix什么坏了对谁坏特性feature什么人原来做不到什么、现在能做到了例SQL 编辑器支持 join却无法给表挂计算字段重构/杂务/使能改动谁被阻塞、代价是什么、消除了哪一类故障——没人看得见但有人在等后续改动/栈中的一层上一个 PR 留下了什么没做完这一个补了什么必须链接那个 PR 并假设没人读过它。配套规则第一行若以符号、文件路径、类名或设置项开头说明你以机制开头重写在知道的前提下用一句话量化问题规模多少团队、多频繁、从何时起机制跟在效果之后按审阅者需要检查的顺序排列Changes 的第一条子弹是改动本身重命名、再生成的快照、注释修正放最后若改动含用户可见部分用一行说明哪部分是机械性的否则审阅者无法区分纯内部改动与你描述成内部的可见改动若 diff 中某部分风险更高点名它并说明其余是机械性的。examples.md 中 Example 1 就演示了这种重排不改写三个事实原样保留只把顺序倒过来审阅者先看到挂了 30 秒再失败再看到 MessagePort 时序最后才是port?.postMessage(...)丢消息的机制——没有新增、没有删减风险先于原因呈现。Pass 2把每条事实路由到最快的形式散文是页面上最慢的载体。写任何句子前先问什么形式传递得更快路由表如下事实类型承载形式视觉变化任何人看到的 UI截图前后对比强制而非可选流程/拓扑变化CI 接线、管道、状态机、请求路径两个带品牌配色的 flowchartbefore 在前同一维度下多个值比较Markdown 表格配置/设置变更fenceddiff块审阅者需要看的现有代码行区间 permalinkGitHub 渲染为代码片段测试输出、日志、长命令记录details块不可错过的行为变化或风险 [!WARNING]或 [!NOTE]其他一切子弹遵循 Pass 4 的塑形规则不是每个 PR 都需要所有形式只有当它能加快审阅时才使用绝不做装饰。空小节写一条子弹或 None。UI 改动却没有可见变化时用一行说明外观没有变化——审阅者无法区分这种情形与漏截图沉默会被读成后者。Mermaid 与截图的上传约束SKILL.md 补充了具体约束Mermaid 语法错误会渲染成错误块高管道用TD、宽路径用LRMermaid 读不了 CSS 变量必须直接写 hex并且每个fill配一个文本color保证 GitHub 亮暗两种主题下都清晰。技能提供的四个品牌配色classDef phBlue fill:#1d4aff,stroke:#1d4aff,color:#fff; classDef phRed fill:#f54e00,stroke:#f54e00,color:#fff; classDef phYellow fill:#f9bd2b,stroke:#f9bd2b,color:#000; classDef phGray fill:#e5e7eb,stroke:#c7ccd1,color:#000;按角色赋值class NodeA,NodeB phBlue;phBlue给 agent 与主路径phRed给 API 与外部系统phYellow给出入口phGray给数据与产物形状按种类{{hexagon}}表示 agent[rect]表示步骤。截图通过hogli pr:upload-image file上传并粘贴其打印的 markdown首次运行只警告重跑加--yes。产物永久公开因此严禁上传客户数据、客户名、密钥或内部信息。Pass 3删减——正文必须站得住且更短保留什么、删掉什么正文必须独立成立不要假设审阅者先读 diff甚至完全不读。保留改动为什么必要它做了什么达到无需打开文件就能理解的程度你否决的替代方案、爆炸半径、上线后要盯什么、先看哪里六个月后从git blame抵达的人需要什么——他们问不到你review 线程也不会告诉他们。删掉逐文件、逐行的 diff 叙述无人质疑的选择背后的理由只在否决了显而易见替代方案时保留理由标题的复述与上面小节的总结过程叙述然后我跑了 X、Y是关于你会话的事实不是关于改动的事实对无争议事实的含糊其辞任何原因 原因为什么重要组合里的后半句无法点名读者的子弹。判据不是它是否在 diff 里——diff 拥有每个细节却完全没有要点。规模跟着改动走能套在任何 PR 上的正文对这个 PR 就什么都没说。六行 diff 的正文必须读起来像六行改动的正文单文件修复整篇正文 3 到 6 条子弹典型 PRProblem 与 Changes 合计约 10 条子弹每个不适用的标题下写一行或 None那是完整回答而非空缺数字、路径、标识符在删减中存活形容词与第二层解释不存活。小不等于残缺三条子弹仍要承载为什么必要与做了什么。可检查的主张描述是 PR 中唯一没有验证机制的人工产物——代码有 CI正文只有你。因此要让每条主张都便宜到易于证伪关于世界的声明你跑了什么、测了什么、在生产里看到了什么必须链接证据失败的运行、error tracking issue、行区间 permalink、dashboard删掉 CI 已经替你声明的内容24 passed、mypy clean既占一行又无法从正文核验而且 checks 更有权威声明你没检查的内容未运行数据库相关套件因为该沙箱没有数据库是多数正文里最可信的一行绝不声称没做过的测试——事后被发现一次就会赔上此后所有描述的可信度。关于代码行为如何的陈述无需链接——审阅者对着代码就能核验。examples.md 明确区分两者The fallback never fires属于第二类One source has failed every run since May属于第一类需要链接。Changes 之下的小节Problem 与 Changes 承载审阅。其下一切都是证据与来源审阅者最后才看或根本不看当下半部分超过上半部分时砍下半部分Testing按上述主张规则点名每条新测试防住哪个回归记录放details块Agent context自主性、工具、调用的技能、会话中发生了什么变化你的设计为何胜过显而易见替代方案的理由属于 Changes——审阅需要它而没人会滚过 changelog 复选框去找它。最终判据正文必须比你的初稿更短Pass 5 会检查它。Pass 4塑形——可检查的形状形状可检查语气不可检查这正是技能不谈语气的原因。九条规则每条子弹一个事实子弹前置加载扫描者看到开头几个词所以以承载事实的主语开头而不是它成立的条件下句子不超过 25 词主动语态、明确主语仅当动作主体确实未知或无关时才用被动简单时态不用完成时/进行时the builder took entry 1而不是 the builder has been taking entry 1同一事物始终用同一词不为风格换词保留冠词The job downloads the artifact而不是 job downloads artifact名词串最多三个词The flag evaluation column codec 改成 the codec on the flag evaluation column无习语、无比喻、无玩笑。规则 2 排布子弹内部的词序Pass 1 排布子弹之间的顺序两者从不冲突效果在前陈述效果的子弹以受影响的人开头。只作用于散文——表格单元格不是句子图不是散文。SKILL.md 中的工作示例一个 28 词、五环因果链的句子被拆成三条各 22 词的可独立核验子弹保留了每个标识符与审阅者必须检查的每个环节去掉的是低于读者需求一层的细节glob 匹配单个产物。其他散文规则不用破折号en-dash 仅在需要时用标题、章节、加粗文本用句首大写只大写首词与专有名词少用行内代码节制使用冒号与分号不按列宽硬换行、不对齐表格GitHub 自行重排渲染。最重要的句子的主语是改动本身不是作者——绝不出现 I/me/mywe 只留给 PostHogThe exporter now retries once而不是 I made the exporter retry once。代理以 I 写作等于把别人没做过的工作记到被指派者头上。作者身份是## Agent context中一条陈述事实而不是正文的语气。Pass 5自检自己的草稿在gh pr create或gh pr edit之前跑两项检查。扫描测试scan test只看标题、Problem 第一行、Changes 第一条子弹遮住其余你知道现在什么不同了、对谁不同吗你知道这个 PR 对此做了什么吗你没有靠符号、文件路径或类名就到达了上述两点吗任何一处 no 都说明正文是按写作者而非读者排的回到 Pass 1——行检查救不了这一点。行检查line check正文比初稿短吗更长说明只拆没砍回到 Pass 3正文规模跟随 diff 规模吗六行改动配长篇正文读起来是填充Problem 与 Changes 合计比其下的小节长吗否则砍下半部分合上 diff 读正文能说出这个 PR 为什么存在、做了什么吗不能就是砍掉了读者需要的东西只读 Changes能说出一个人现在会看到/做到什么不同或说明没有用户可见变化吗两者皆否则回到 Pass 1逐条读子弹并点名读者点不出名字的就删每条子弹独立陈述一个事实吗两个就拆最长句超过 25 词就拆把每个被动句改成主动除非主体确实未知用介词拆开超过三个词的名词串有没有句子以作者为主语围绕改动重写I/me/my 不得出现改动改变人能看到的东西吗附前后截图或说明外观为何无变化重写已有正文了吗人工放置的图片、视频、链接、勾选项是否都还在改动流程或拓扑了吗附品牌化的前后图散文在比较同一维度下的多个值吗换成表格每一条关于跑了什么、测了什么、看到了什么的主张都链接证据或声明未核验吗行为描述无需链接有!-- --模板注释残留吗该节未填填充或删除## Agent context填了吗列出调用的技能正文声明了没发生的手动测试吗删掉正文点名了内部客户、事故、Slack 引文或运营指标吗本仓库是公开的删掉。技能强调没有任何检查器强制这些规则Pass 5 就是强制手段。examples.md三个已合并 PR 的端到端演练references/examples.md的定位是规则在 SKILL.md 中清楚、但你想看它端到端应用时的读物三个已合并的 PR按发布状态经过全部五遍之后展示。其中 Example 1 是重排——同样的事实按审阅者需要的顺序排列Example 2 与 3 是删减。三者都比原稿更短因为子弹是切到关键事实的方式而不是把段落以更长篇幅复述一遍。Example 1效果从三行降到两行fix(dashboards): tolerate legacy keys in persisted dashboard filters。问题段初稿 82 词、发布稿 71 词每个事实都存活只是顺序重排审阅者先学到磁贴坏了、没人能在应用里修复然后才轮到哪个类校验了什么。表格列出的三处移动印证了路由逻辑文本从到A 400 for unknown keys on write would block saving: the UI echoes persisted blobs back into savesAgent context 最后一条子弹Changes作为一条子弹Ranpyteston the two touched test files (52 passed), repo-widemypy(clean), andhogli ci:preflight --fix(no failures)Testing删除。checks 已报告三者The existing PATCH round-trip test intest_dashboard.pyguards the wiringTesting删除。已有测试仍然通过被否决的替代方案是审阅者判断设计所需的一行最终放在 changelog 复选框之下。Example 2一条长因果链fix(data-warehouse): recognize Neons pooler rejection of libpq options。发布稿 297 词剩余各遍之后 197 词。核心机制事务模式连接池拒绝 libpqoptions启动参数_connect_with_options_fallback按池子用的确切措辞匹配并重连FATAL: unsupported startup parameter: optionsNeon 的 pooled 端点点名的是设置项而非参数ERROR: unsupported startup parameter in options: statement_timeout.unsupported startup parameter: options不是后者的子串于是 fallback 永不触发、连接直接失败。CDC 路径上该连接是cdc_extract_activity做的第一件事流读取器总是发送options因此每次针对 Neon pooled 端点的抽取都在stream_reader.connect()上永久失败且被归类为可重试的connection_failed——用户被告知去检查一个既可达又健康的数据库。有一个数据源从创建当天起就从未成功抽取过。Pass 3 砍了 100 词Neon 错误第二行与完整用户可见消息读者只需要破坏匹配的那句措辞、statement_timeout1800000 -c idle_in_transaction_session_timeout0总是发送 options才是事实、原因对中的后半句、无人质疑的主张、以及属于代码注释的 timeout 细节。Pass 4 把 76 词的失败链拆成审阅者逐条检查的五环。两个 fenced 块原样存活——Pass 4 只管散文。示例还指出该改写本身未通过 Pass 1首行讲的是 libpq 事实而效果在第 6、8 条子弹。应改为以Neon pooled 端点同步从未工作过与用户被告知检查一个健康的数据库开篇且首条子弹是唯一受 claim 规则约束的——从未工作过每次运行都失败是作者亲见读者无法对照代码核验必须链接运行记录或 error tracking issue。Example 3一段里两个独立理由fix(flags): drop custom codecs from flag_evaluations columns。发布稿 190 词剩余各遍之后 111 词。Migration 0292 给flag_evaluations加了显式逐列 codecString 列ZSTD(1)、datetime 列DoubleDelta, ZSTD(1)但这是错误决策该集群在 ClickHouse 服务端统一调优压缩钉死列级 codec 只会把它从集群级调优中摘出去且 DoubleDelta 只在值随排序键趋势变化时才有回报而flag_evaluations按(team_id, flag_key, toDate(timestamp), cityHash64(distinct_id))排序不以时间开头DoubleDelta 在此不划算。Migration 0293 先 SET 再MODIFY COLUMN ... REMOVE CODEC横跨分片数据表与两个 Distributed 表——先设置后移除保证无论 0292 已运行codec 存在还是全新安装已按更新 DDL 建成无 codec 表REMOVE CODEC对无 codec 列会报错迁移都能干净执行。Pass 3 砍了 79 词精确 codec 值上一条子弹已说明用途、Thats the wrong call here这类由下两条子弹自然推出的结论、同句重复的主张、三个完整表名All three tables足够。Pass 4 把两个独立理由集群统一调优 vs DoubleDelta 失效从焊接成一段中拆开——否则想质疑 DoubleDelta 论证的审阅者必须先解开中央调优论证。最终效果线The codecs onflag_evaluationstake those columns out of the clusters central compression tuning and buy nothing back.仓库源码印证flag_evaluations的真实形态Example 3 讨论的表在当前仓库中真实存在可以对照核验。列模板在 posthog/models/flag_evaluations/sql.py第 72–77 行明确写着No column carries a CODEC并给出与示例 PR 完全一致的理由ORDER BY只把时间戳归一到天、之后按 distinct_id 哈希排序三个DateTime64列在磁盘上近乎随机排列正是 delta 家族失效的地方且注明仅在有测量数据时重访表族命名沿用主集群分片惯例sharded_flag_evaluationsDATA 节点上的分片复制 MergeTree、writable_flag_evaluationsingestion 层 Distributed 写路径、flag_evaluationsDATA 节点读路径HogQL 以posthog.flag_evaluations暴露、kafka_flag_evaluations与flag_evaluations_mv见 sql.py 第 21–33 行分片键用sipHash64(distinct_id)与 events 表一致使回填分片本地化排序键内嵌toDate(timestamp)支撑月度分区下的按旗标日查询第 47–58 行。迁移文件链与示例中0292 建列、0293 删 codec叙事对应0292_flag_evaluations.py 按五步创建整条表族分片存储表DATA→ writable Distributedingestion 层→ 读路径 DistributedDATA→ Kafka 引擎表ingestion 层→ 最后的物化视图0297_flag_evaluations_events_mirror.py 展示了 launch 前用drop-and-recreate 而非 ALTER重塑表族——topic 尚无生产者、全族为空从规范列模板重建不会与全新安装漂移且避免可能卡死发布流程的DROP COLUMNdrop 按依赖逆序MV → Kafka → Distributed 前端 → 存储带SYNC清理复制表的 ZooKeeper 元数据0301_flag_evaluations_default_columns.py 把九个类型化属性列从 MATERIALIZED 重建为 DEFAULT——ALTER UPDATE可写的类型供未来属性删除重写路径使用。这些迁移直接呼应技能 Pass 3 的规则sketch 级叙述0292 给了逐列 codec、镜像 events 表与机制REMOVE CODEC对无 codec 列报错所以先 SET是正文该保留的事实而精确值与重复结论应删除。若以此类迁移为素材写作 PR 描述正文可按 examples.md 的模板组织Problem 写人看到的失败每次抽取都失败、用户被告知检查健康的数据库Changes 写机制与取舍匹配改为前缀、先 SET 再 REMOVE、shared column template 同步剥除 CODEC并把属于代码注释的细节留在注释里。技能背景与依据SKILL.md 的 Background 一节给出了这套规则的研究依据Pass 1 建立在三项研究上NN/g 的网页写作研究中 19 名参与者有 15 名以扫描方式接近陌生文本简洁、可扫描、前置加载的版本可用性高出 124%扫描者看到的是每行开头因此前几个词决定其余内容是否被读Bacchelli 与 BirdICSE 2013发现审阅时间花在理解改动而非发现缺陷上所以交付理解是正文的第一职责。Google 的 CL 描述规范在 Pass 3 上与之呼应描述承载问题与本方案的理由并给不在代码里的读者足够上下文Pass 4 改编自 ASD-STE100Issue 92025 年 1 月53 条写作规则中的子集25 词上限是该标准对描述性文本的限值程序性文本为 20 词PR 正文很少涉及规则 1 与 2 是自有规则——STE 对程序写一句一个指令、对描述写一段一个主题子弹介于两者之间而前置加载来自上述扫描研究。标准另一半约 900 个经许可的一词一义词汇表刻意不纳入词汇仍是判断问题examples.md 中这些规则背后的测量数据存在于引入它们的 PR 里可从git log回溯SKILL.md找到——那是技能维护者的来源证明不是写正文的指令。结语一套可执行的写作闭环把技能浓缩为可执行闭环先做 Pass 0 保全已有正文 → Pass 1 把效果提到第一行 → Pass 2 把每条事实路由到最快载体 → Pass 3 删到正文比初稿短且规模跟随 diff → Pass 4 用九条塑形规则把幸存内容切成可检查形状 → Pass 5 用扫描测试与 19 项行检查自检。examples.md 的三个已合并 PR 证明这套流程在真实 PostHog 仓库中落地有效297 词到 197 词、190 词到 111 词、82 词到 71 词全部比初稿短。技能对写作方式的全部承诺可以压缩成一句话正文必须比初稿短、每颗子弹一个事实、句子不超过 25 词、主动语态、效果在前——先正确排序再用形式加速最后用删减与塑形收尾。【免费下载链接】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),仅供参考
返回列表