
Upsonic 重构工作流完全指南行为保持型重构的四阶段流程、硬门禁与反模式【免费下载链接】gpt-computer-assistantBuild autonomous AI agents in Python.项目地址: https://gitcode.com/GitHub_Trending/gp/gpt-computer-assistant本指南面向在 Upsonicsrc/upsonic/中执行代码重构的 AI 助手与人工贡献者系统讲解改变内部结构、但不改变任何可观察行为的操作化流程。读完你将掌握如何为一次重构划定合法边界、如何用特征化测试锁定现有行为、如何在不污染公共 API 的前提下完成代码移动与重命名以及如何用一份硬门禁清单证明重构真的完成了。本指南是 feature.md 的轻量级兄弟文档复用了其 §4 方面附录而非重复陈述。1. 适用范围与边界判定重构refactor在 Upsonic 中有一个严格定义改变代码的内部结构但不改变任何可观察行为。它与功能开发feature、缺陷修复bug-fix是三种形状完全不同的工作必须使用对应的指南。适用本指南的场景重命名、提取extract、内联inline或移动代码且不改变可观察行为拆分过大的模块、类或函数删除死代码或未使用的导出用另一个契约完全相同的内部 helper 替换现有 helper机械性迁移例如dict[...]→TypedDict、同步 helper → 独立函数。不适用本指南的场景请使用对应指南任何哪怕只改变一点点可观察行为的工作 → feature.md由缺陷驱动的变更 → bug-fix.md之后如有需要再单独重构改变用户可感知延迟特征latency的性能调整 → feature.md。边界判定常见歧义重构顺带新增了一个小 helper 类只要该 helper 是内部实现不导出、无公开调用方且公共 API 不变它仍然是重构否则它就是一个 feature。重构顺带修复了一个潜在缺陷立即停止。将工作拆开——先在 bug-fix.md 下完成缺陷修复附回归测试再在其上执行重构。两者绝不能共享同一个 commit。一个偷偷修 bug 的重构既无法审查也无法干净地回滚。重构需要重命名公共符号允许但必须在原位置提供弃用别名deprecation alias以保持既有用户导入可用——或者获得用户对破坏性变更的明确签字同意。2. 如何使用本指南本指南由三部分组成你MUST按顺序通过全部四个阶段§3 — 四阶段流程Motivate Scope → Characterize → Transform → Verify Behaviour Preserved这是主干每个阶段都包含入口门禁entry gate、要做什么、对feature.md §4的方面引用aspect references与出口门禁exit gate§4 — 硬门禁汇总Hard Gates Summary每个阶段边界的预检清单§5 — 反模式Anti-patterns重构场景下最常见的 AI 错误。RFC 2119 关键字。文中MUST、MUST NOT、SHOULD、SHOULD NOT、MAY均按 RFC 2119 语义使用。任何标记为MUST的都是硬门禁违反即需要用户明确批准。方面处理规则。阶段中引用的每一个方面都MUST被处理。若某个方面不适用你必须用一句话显式说明理由例如Observability Cost: N/A本次重构不调用模型、不新增 I/O。静默跳过是禁止的。3. 四阶段流程详解阶段一Motivate Scope动机与范围界定入口门禁存在一个进行重构的理由。要做什么强制性预工作咨询Pre-Work Consultation。按照 CLAUDE.md 中的Default Pre-Work Consultation约定在陈述目标状态之前并行执行两项检查Claude Code memory— 见 memory.md。拉取反复出现的用户纠正、相似的历史重构、项目约定Serena 代码查找— 见 serena.md。查找相似的历史重构、相关符号、以及你计划触碰的表面的所有调用方。在回复顶部公开调查结果From memory: …. From Serena: ….当未审计的调用方被破坏时重构会响亮地失败Serena 的引用追踪reference tracing是不可省略的。用一句话陈述动机。有效动机偿还显式技术债、为某个已知的即将到来的 feature 铺路、某个文件/类跨过了复杂度阈值、消除重复、拆分一个已承担过多职责的模块。无效动机代码感觉不对、我不喜欢这种风格、为现代化而现代化。没有具体理由的重构会漂移。显式声明范围之外OUT of scope的事项公共 API 不变、无新功能、无行为变化、无性能变化、无缺陷修复。若任何一条不成立你就不是在重构——请选择正确的指南。识别受影响的子系统。指出src/upsonic/下哪些子系统受影响。跨子系统重构风险更高阶段四需要更多谨慎。定义目标状态。目标文件布局、目标签名、目标命名。我将重构 X不够你需要具体描述重构后的形态post-refactor shape。计划细化非平凡重构 MUST。调用/write-plansuperpowers生成结构化的六段式计划Touchpoints 钉死每个文件/符号的移动。该命令由 Agent 调用——这是强制性输出不是可选项。两种交付路径非平凡重构多文件移动、公共符号重命名、拆分超大模块在/twoskill双终端辩论内编写计划。用户打开/two planner与/two critic。Planner 在起草 Turn 1 时调用/write-planCritic 审查迭代至相互收敛上限5 轮迭代。最终输出plan/final_plan.md。平凡机械重构内部符号的单 helper 重命名、无公共表面、无调用方审计发现Agent 在单个终端中直接调用/write-plan——无需/two辩论。用户须显式声明路径Skipping /two — single-helper rename, /write-plan single-shot./two是辩论运输层debate transport/write-plan是计划格式。非平凡重构二者组合使用平凡重构只用/write-plan。方面引用Default Pre-Work Consultation— 见 CLAUDE.md、memory.md、serena.md。公共符号的任何移动/重命名Serena 调用方审计不可协商。Architecture Subsystem Fit— 见 feature.md §4.1。停留在既有子系统布局内重构不是新增顶层模块的理由。Plan Refinement— 非平凡重构使用/two首选或/write-plan小型。平凡机械重构可跳过但须显式声明。出口门禁Memory Serena 已咨询发现或未发现已公开动机已用一句话写下范围外事项已显式列出目标状态已被具体描述受影响子系统已识别存在已锁定的计划或平凡重构的跳过已被显式声明。阶段二Characterize刻画现有行为入口门禁阶段一出口已通过。要做什么识别覆盖重构表面的所有测试。测试通过了在没有任何测试覆盖你触碰路径时毫无意义。运行这些测试确认在改动前它们通过。如果覆盖率不足没有测试或测试未覆盖所触碰路径你MUST先添加特征化测试characterization tests。遵循 testing.md 阶段 1–3用 user-first / Serena / memory 推导场景写 RED 测试人工审查。这些测试锁定现有行为并作为重构变更的一部分提交——它们不是一次性弃物。同步与异步路径都要覆盖。如果表面同时有name()与aname()孪生方法变换前两者MUST都被执行到。如果表面有外部 I/ORedis、Postgres、模型 API、文件系统适用 smoke 测试——见 feature.md §4.5。在进入阶段三前锁定测试集。特征化测试变绿后显式声明锁定Tests locked. Transformation may not edit any test file beyond mechanical renames/moves.这是阶段三变换所依据的契约。方面引用Tests— 见 feature.md §4.5。按表面所触及的内容选择测试层级unit_tests还是smoke_tests。API Discipline— 见 feature.md §4.2。同步 异步对等性由阶段二测试验证。出口门禁现有或新添加的测试覆盖了重构表面所有这些测试在重构前代码上通过同步 异步路径都被执行到。仓库佐证Upsonic 的存储子系统在 storage/base.py 中大量使用aget_session/get_session、adelete_session/delete_session这类a前缀孪生方法见 L790 附近与 L181 附近。阶段二要求同步/异步双路径都被测试执行正是因为这条 API 纪律是全局的——coding-standards.md §2.3 规定公开异步方法用a-前缀、同步方法用裸名且 coding-standards.md §5.2 规定每个执行工作的公开方法必须同时有 sync 和 async 两个版本。阶段三Transform变换入口门禁阶段二出口已通过。要做什么做最小变更集以到达目标状态。理想情况是一次一个机械移动一次重命名、一次提取、一次移动。每完成一个有意义的步骤后运行阶段二测试。若测试失败说明你引入了行为变化——回退并缩小该步骤的范围。同步 异步孪生必须一起移动。绝不要只重构同步路径孪生之间的漂移正是 feature.md §4.2 要防止的东西。更新__init__.py导出以保持规范的导入路径。如果公共符号必须移动在原位置添加**弃用别名deprecation alias**重新导出该符号并发出DeprecationWarning。保持惰性导入纪律不得在顶层新增重型依赖——见 coding-standards.md §2.4。NO新功能。NO缺陷修复。NO性能变化。NO不属于阶段一目标状态的新公共符号。保持独立函数纪律——不得新增模块级可变状态、不得有隐藏全局见 coding-standards.md §1 与 §3.5。方面引用Architecture Subsystem Fit— 见 feature.md §4.1。不得引入跨子系统泄漏。API Discipline— 见 feature.md §4.2。同步 异步对等完整类型注解保留。Integration Distribution— 见 feature.md §4.7。__init__.py导出更新移动的公共符号添加弃用别名。出口门禁代码可编译阶段二测试仍然通过——除机械重命名/移动外未被修改mypy --strict干净公共 API 表面未变或移动/重命名符号已有弃用别名。阶段四Verify Behaviour Preserved验证行为保持不变入口门禁阶段三出口已通过。要做什么运行完整单元测试套件uv run --all-extras pytest tests/unit_tests -v。如果触碰了 I/O运行make smoke_tests。运行pre-commit run --all-files。对src/运行mypy --strict。对测试文件做 diff。如果现有测试有任何超出重命名/移动的改动断言被放宽、parametrize 用例被删除、fixture 被重构你很可能把行为变化藏进了测试代码。STOP将其拆分为独立的 bug-fix 或 feature。验证公共导出未变。从规范路径 smoke-import 每个公共符号若有失败重构破坏了公共表面。如果任何公共符号被重命名或移动确认原位置的弃用别名就位且发出DeprecationWarning。确认被触碰公共符号上的 docstring 仍与被保留的行为一致。docstring 与代码脱节的重构是不完整的。确认 tests/doc_examples/ 中的示例仍可执行。任何示例破坏都证明你漏掉了公共表面的漂移。如果重构是为某个规划中的 feature 铺路在 commit body 中链接未来计划。内存卫生Memory hygiene提交前 MUST。按照 memory.md 的When and What to Save反思本次重构是否浮现出值得带入下个会话的内容——通常是发现了一条约定、一个非显而易见的依赖方向或一条关于范围纪律的用户纠正。若有保存一条精炼的记忆条目若没有显式声明No memory-worthy learning from this refactor.静默跳过是不允许的。方面引用Tests— 见 feature.md §4.5。全部测试层级变绿。Integration Distribution— 见 feature.md §4.7。导出 弃用别名。Docs Examples— 见 feature.md §4.6。docstring 与被保留行为一致示例仍可运行。出口门禁硬门禁汇总§4中的每一项都通过。硬门禁。在此门禁通过之前你MUST NOT称该工作为已重构、干净或完成。测试仍然通过是必要不充分条件§4 的每一项都通过才是门禁。仓库佐证Upsonic 的类型化异常体系为行为契约提供了可验证的落点。exceptions.py 从单一根异常UpsonicError派生APIKeyMissingError、ConfigurationError、ProviderError、RateLimitError、AuthenticationError、RunCancelledException、ExecutionTimeoutError等见 L32、L37、L90、L133、L143、L148、L163、L171。重构后 smoke-import 验证公共导出时这类层级就是公共契约未变的实证。4. 硬门禁汇总Hard Gates Summary这是本指南最重要的页面——每个阶段边界使用一次以下条目在没有用户明确批准跳过的情况下不可协商─── Before transitioning OUT of MOTIVATE SCOPE ────────────────────── [ ] Memory consulted (memory.md); findings surfaced or no relevant entry [ ] Serena consulted (serena.md); caller-audit done for any public symbol move/rename [ ] Motivation stated in one sentence [ ] Out-of-scope items listed (no new features, no behaviour change, no fixes) [ ] Target state described concretely [ ] Affected subsystems identified [ ] /write-plan invoked by the agent; six-section locked plan exists [ ] Plan delivered via /two debate (non-trivial) or /write-plan single-shot (trivial — explicitly declared) ─── Before transitioning OUT of CHARACTERIZE ────────────────────────── [ ] Tests covering the refactor surface exist (added if missing, via testing.md Phases 1-3) [ ] All those tests pass on pre-refactor code [ ] Sync async paths both exercised [ ] Test set locked before Phase 3; declared explicitly ─── Before transitioning OUT of TRANSFORM ───────────────────────────── [ ] Phase 2 tests still pass without modification (renames/moves only) [ ] mypy --strict clean [ ] Public exports unchanged, or deprecation aliases added [ ] Sync async siblings refactored together [ ] No new features; no bug fixes; no performance changes ─── Before claiming the refactor DONE ───────────────────────────────── [ ] Memory hygiene: end-of-workflow reflection complete; entry written or no memory-worthy learning stated [ ] uv run --all-extras pytest tests/unit_tests passes [ ] make smoke_tests passes (if I/O touched) [ ] pre-commit run --all-files clean [ ] mypy --strict clean [ ] Public API surface verified unchanged (smoke-imports succeed) [ ] Deprecation aliases in place for moved/renamed public symbols [ ] Docstrings still match the preserved behaviour [ ] Examples in tests/doc_examples/ still run [ ] Ready to hand off to commit workflow (commit.md)如果任何一项无法勾选重构就没有完成。将某项标记为 N/A 是允许的但MUST附上一句理由。命令出处上述验证命令uv run --all-extras pytest tests/unit_tests -v、make smoke_tests、pre-commit run --all-files、mypy --strict与仓库实际配置一致。Makefile 的smoke_tests目标会先执行deps_smokeuv sync --extra storage --extra faiss并启动tests/smoke_tests/docker-compose.yml中的 Docker 服务再运行uv run pytest tests/smoke_tests -vpyproject.toml 中mypy、ruff、pre-commit等作为开发依赖管理测试按 pytest.ini 配置执行。5. 反模式Anti-patterns在本框架中重构时最常见的 AI 错误无测试重构。没有测试时的测试通过了是一个无意义门禁。先在阶段二添加特征化测试否则你没有行为保持的保证。(Aspect: §4.5)把 feature 打包进重构。我在提取 helper 时给构造函数加了个新选项。那不再是重构而是 feature。拆分工作先重构再在 feature.md 下叠加 feature。(Aspect: §4.2)把 bug-fix 打包进重构。我注意到一个潜在 bug就在移动函数时顺手修了。bug-fix 需要回归测试并作为 bug-fix.md 下的独立变更。打包使 diff 无法审查、bug 无法独立回滚。(Aspect: §4.3)重命名公共符号却不加弃用别名。现有用户导入在下个版本静默破裂。公共 API 是契约重命名需要在原位置有弃用别名或获得用户对破坏性变更的明确签字。(Aspect: §4.2)只重构同步路径。同步和异步孪生是同一个 API 的两种实现。只重构其中一个会引入漂移而 bug 会利用这种漂移。(Aspect: §4.2)在重构期间改进测试。更新测试、放宽断言、删除 parametrize 用例、现代化——这些都是藏在测试代码里的行为影响性变更。阶段二测试只能机械变更文件移动、重命名。(Aspect: §4.5)把创建顶层子系统伪装成重构。把tools/拆成tools/和tool_processors/是需要按 feature.md §4.1 论证的架构变更不是悄悄的重构。(Aspect: §4.1)不审计调用方就反转依赖方向。我把它从 X 移到了 Y。现在每个既有调用者的from upsonic.x import Foo都破裂。原位置加弃用别名并做调用方审计否则它不是重构。(Aspect: §4.7)跳过预工作咨询memory Serena。移动或重命名公共符号却不做 Serena 调用方审计的重构等于保证发布即导入破裂。memory 和 Serena 都必须在陈述目标状态之前运行。(Aspect: Default Pre-Work Consultation in CLAUDE.md, Phase 1)产出没有/write-plan的重构。多文件移动、公共符号重命名、拆分超大模块——这些在编辑任何src/代码之前都需要/write-plan输出。自由形式的重构会漂移结构化计划不会。非平凡重构通过/two辩论交付平凡机械重构可以 single-shot——但路径 MUST 被显式声明。(Aspect: Phase 1)在变换期间编辑特征化测试。阶段二的整个意义就是锁定行为。如果变换时某个阶段二测试看起来不对说明重构的范围错了——拆分变更不要静默编辑测试。(Aspect: testing.md Phase 4, this guide Phase 3)在重构结束时跳过内存卫生。重构常常浮现出应该向前传递的约定和范围纪律纠正。工作流末尾的内存反思是强制的要么保存要么声明no memory-worthy learning.(Aspect: memory.md, Phase 4)6. 快速映射Quick MapPhase 1: Motivate Scope — memory.md serena.md pre-work pass (MUST) caller-audit for public symbol moves /write-plan invocation → six-section locked plan (MUST for non-trivial) delivered via /two debate (non-trivial) or single-shot (trivial) why, target state, what stays the same Phase 2: Characterize — tests cover the surface (testing.md Phases 1-3) lock test set before Phase 3 (MUST) Phase 3: Transform — small mechanical steps, syncasync together locked tests stay locked (no semantic edits) Phase 4: Verify — tests pass UNCHANGED, public API unchanged, no drift memory hygiene reflection (MUST) Then: commit.md — propose message, wait for approval, commit在任何时刻不确定时重读相关阶段章节以及 feature.md §4 中交叉引用的方面规则。§4 的硬门禁汇总Hard Gates Summary是本指南最重要的一页。7. 重构完成后的收尾进入提交工作流阶段四出口门禁通过后工作尚未结束——按 commit.md 的规则提交。Upsonic 的提交纪律对重构尤其相关硬规则绝不未经批准提交。不要运行git commit、git push或任何改写历史的命令reset --hard、rebase、amend、force-push直到人类审查了 diff 并明确表示提交。工作看起来完成时停下来说ready to commit, want me to?等待显式yes/commit it。沉默不是批准。提交信息格式type(scope): subject。type 取feat、fix、refactor、test、docs、chore、perf、style、build、ci之一scope 为所触及区域agent、prebuilt、models、tools……跨多区时可省略subject 为祈使句、小写、无句号、≤ 72 字符。仓库风格示例refactor(prebuilt): standardize layout under src/upsonic/prebuilt。不要提交密钥.env、凭据、token不要盲目git add -A要暂存特定文件不要绕过 hooks--no-verify、--no-gpg-sign除非用户要求不要 amend/rebase 已发布提交subject 行不要写多段论文不要在提交信息中出现 Generated by … / Co-Authored-By除非用户要求。提交工作流做出改动 →git statusgit diff审查 → 向用户展示 diff 摘要 → 提出提交信息 →等待显式批准→ 暂存特定文件并提交 → 提交后运行git status确认干净状态 → 除非用户要求不要 push。重构完成后若此次重构修改了documents/ai/explanation/subsystem/subsystem.md中声明的可观察契约还需按照 CLAUDE.md 的约定在同一个 commit或紧随的docs: sync explanation/…commit中同步对应解释文档纯内部重构私有 helper、注释清理、保持所有可观察契约的重构则可跳过同步。小结。Upsonic 的重构工作流把保持行为不变从一句口号变成了可执行的工程纪律阶段一用 memory Serena /write-plan锁死动机、边界与目标状态阶段二用特征化测试把现有行为刻进测试集阶段三以小步机械变换 同步/异步孪生同移守住纪律阶段四用全套验证命令、测试 diff 与 smoke-import 证明公共表面零漂移并以强制内存卫生收尾。§4 的硬门禁清单是每次重构结束前的最终裁判——测试仍然通过远远不够每一项都通过才是完成。【免费下载链接】gpt-computer-assistantBuild autonomous AI agents in Python.项目地址: https://gitcode.com/GitHub_Trending/gp/gpt-computer-assistant创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考