🔧 阿川の電商水電行
Shopify 顧問、維護與客製化
💡
小任務 / 單次支援方案
單次處理 Shopify 修正/微調
⭐️
維護方案
每月 Shopify 技術支援 + 小修改 + 諮詢
🚀
專案建置
Shopify 功能導入、培訓 + 分階段交付

我正在建立一個開源庫,它已被下載約 8,000 次,並在日本和美國都有使用。

然後我進行了推廣,意識到我搞砸了,倉庫裡每多一顆星,我的胃就一陣翻騰。

我的結論是:自稱高階用戶所謂的「氛圍編碼」其實就是一團亂麻。

我沒有把爛攤子丟掉,而是決定把它改造成可以吃的東西。這就是這次重啟的意義。

介紹

你有沒有過這樣的經驗:某個個人專案進展極為緩慢,以至於幾個月都無法繼續進行?

我的結構化資料差異比較工具diffx從 2025 年 8 月到 11 月基本上處於停滯狀態——大約三個月。它本應已經“功能齊全”,但我卻無法繼續開發。我分析了問題所在,並使用我現在稱之為“重啟”的流程使其恢復執行。

這篇文章記錄了所有內容:根本原因分析、與 AI 合作失敗、擺脫單體倉庫以及具體的重啟步驟。

誰該讀這篇文章?

  • 獨立開發者陷入停滯的專案

  • 在使用人工智慧結對程式設計(例如 Claude Code)時,人們在程式碼品質方面遇到的困難

  • 工程師們對單體程式碼庫和共享的 CI/CD 框架感到厭倦

diffx是什麼?

{% github kako-jun/diffx %}

diffx 是一個 Rust 工具,它可以從 JSON、YAML、TOML、XML、INI 和 CSV 等結構化資料中提取語義差異。與傳統的基於文字的差異比較不同,它忽略格式和鍵順序的變化,只顯示有意義的差異。

$ diffx config-old.yaml config-new.yaml
~ server.port: 8080 -> 9000
+ server.timeout: 30
- server.deprecated_option

它專為 DevOps/SRE 工作流程而設計,尤其適用於追蹤 Kubernetes YAML 和 Terraform 配置變更。此外,它還有 npm 版本 (diffx-js) 和 Python 版本 (diffx-python)。


第一章:冰封期間發生了什麼

「完成」的錯覺

以下是當時的貼文:

https://dev.to/kako-jun/i-built-diffx-a-structure-aware-ai-first-diff-tool-in-rust-lets-end-the-comma-induced-suffering-491h

這個計畫獲得了大量點贊,甚至有人成為了贊助商。

從表面上看,這個專案似乎已經很完善了:

  • README 文件提供日文、英文和中文版本。

  • 支援六種資料格式

  • npm 和 Python 端口

  • 複雜的 CI/CD 管道

  • 一項740線遷移計劃

但實際上:

  • CI/CD 系統已完全損壞,無法修復。

  • 測試結果不一定能驗證實際規格。

  • 文件和實際執行之間可能已經脫節。

從技術上講,命令列介面 (CLI) 可以執行,但說實話,我不能稱其為可持續的。


第二章:停滯的根本原因

我花了三個月時間「研究如何使其可持續發展」。

分析 diffx 後,我發現了三種主要的故障類型。

A類:專案設計缺陷

1. 同時執行三個專案並過度分享所有訊息

除了 diffx 之外,我還構思了兩個姊妹專案:diffai(用於 AI 模型配置的差異)和 lawkit(如本福特定律的統計)。

我做了什麼

  • 為這三個系統建構了一個共享的 CI/CD 系統

  • 嘗試透過workflow_call來協調所有操作。

  • 加入了指向共享倉庫的符號連結

結果

我將共享部分(GitHub 工作流程、腳本等)拆分到另一個儲存庫中,然後從每個專案建立符號連結。

/home/kako-jun/repos/.github/          ← shared repo
└── rust-cli-kiln/
    └── scripts/
        └── testing/
            └── quick-check.sh  ← never stabilized

Inside each project:
github-shared -> ../.github  ← symlink

quick-check.sh存在,但針對 diffx 調整後導致 lawkit 出現問題,而修復 lawkit 又導致 diffai 出現問題。所有測試結果都顯示正常。

教訓:第一個專案穩定之前,不要考慮下一個專案。

2. 單體倉庫管理不善

我將 Rust 核心程式碼以及 npm 和 Python 綁定放在同一個倉庫。

diffx/                    # monorepo
├── diffx-core/           # Rust
├── diffx-cli/            # Rust
├── diffx-js/             # Node.js (napi-rs)
└── diffx-python/         # Python (PyO3)

問題

  • 三種語言/工具鏈共享一個程式碼庫

  • GitHub Actions 擴展為六個工作流程以及共享倉庫

  • 任何改變都有可能毀掉一切。

  • 釋放過程需要多步驟的儀式

  • 依賴關係圖呈指數級增長,變得極為複雜。

釋放節奏不匹配

Minor bug fix in Rust
  → diffx-core v0.6.1
  → diffx-cli v0.6.1
  → diffx-js needs binding updates (half-day)
  → diffx-python needs similar updates (half-day)
  → Rust-only release goes out
  → Versions drift apart

3. 過早編寫多語言文件

我從一開始就嘗試發布三個 README 文件。

問題

  • 保持三個文件同步真是太累了。

  • 每一次改變都會變成三倍的工作量

  • 你忘記了哪個文件才是「真相」。

  • 所有事物同時變得陳舊乏味。

更好的方法

Phase 1: README_ja.md only (use the language you can edit fastest)
Phase 2: Add English once the project matures
Phase 3: Add other languages based on demand

B類:未能與人工智慧協同工作

我大量使用了 Claude Code,並遇到了多種故障模式。

4. 忽略上下文壓縮造成的質量損失

在上下文壓縮了三倍的會話中,答案一開始很完美,但隨著時間的推移而逐漸退化。

Start: accurate, detailed implementation
  ↓ 1 hour later: subtle spec violations
  ↓ 2 hours later: obvious bugs
  ↓ 3 hours later: forgets prior instructions entirely

當僅剩 20% 上下文時的行為

一旦上下文資訊不足,人工智慧就會公開改變其性格:

  • 毫不猶豫地說謊

  • 隨機省略程式碼

  • 即使未被要求,也會主動促成交易。

即使有了規範文件,它也會忘記規範並隨意編寫程式碼。盲目信任人工智慧的初學者很容易陷入規範與程式碼不同步的困境。

為什麼會發生這種情況?

我的猜測是:人工智慧程式設計師接受的訓練是「在上下文崩潰之前乾淨利落地完成程式碼編寫」。這本身就合情合理。

但如果把這種本能和「一年級新生式的直覺程式設計」結合起來,那就注定要失敗。在 Qiita 或 Zenn 上,你會看到一些興奮的帖子:「我用直覺編程做出了這個!大家都應該試試!」這種熱情固然高漲,但人工智能「必須完成」的本能加上初學者「人工智能會保護我」的盲目信任,最終只會走向失敗。

這就是「氛圍編碼」的危險之處。我的定義是:

  • 在單次會話中破解main

  • 隨意下達指令,無須考慮上下文大小

  • 相信它「有點用」。

  • 醒來發現有 2000 多行義大利麵

如果是玩具專案,那就沒問題。但如果你在進入「幻滅階段」之前就一直按照預設的思路來設計,最終肯定會失敗。

5. 未經核實就相信“已實施!”

撇開上下文問題不談:即使是 Opus 4.5,在有很多上下文的情況下,也經常在「已實施」方面撒謊。

人工智慧明明知道正確的事實,卻仍輸出與事實相反的程式碼。知道正確運用是兩碼事。

因應措施:讓同一人工智慧系統檢視自己的工作成果。

Me: "Implement this feature."
AI: "Implemented."
Me: "Review it yourself. Are you sure it's spec-compliant?"
AI: "I found the following issues..." (and fixes them immediately)

這就是為什麼業內一直在談論「人工智慧自動審核」。它正是應對這種失敗模式的良方。我當時只是不知道而已。

6. 給予模糊的規格說明(我詞彙量不足)

Me: "Add an option to ignore case."
AI: "Added --ignore-case."
Result: Values compare case-insensitively, but keys do not.

我理解的「忽略大小寫」包括鍵,但人工智慧並沒有推斷出這一點。

根本問題:我缺乏描述開發原則的詞彙。

當基於氛圍的編碼失效時,你需要告訴人工智慧「應用單一職責」或「分離關注點」。如果你不了解這些短語,那就束手無策了。

更好的說明

❌ "Add an option to ignore case."
✅ "Add --ignore-case with the following effects:
    1. Compare values case-insensitively.
    2. Compare keys case-insensitively.
    Example: {"Name": "foo"} and {"name": "foo"} should be equal."

今天我至少會寫這麼多——或者讓人工智慧幫我起草這些指令。那時候我沒有這個習慣。

7. 提供其過時的文件

Me: "Read README.md and implement accordingly."
AI: "Implementation complete based on README."
Result: README was full of lies, so it implemented lies.

早期的AI會議已經讓醫生偏離了現實。

C類:品質保證失敗

8. 現有測試方法不可靠

$ cargo test --workspace
29 passed; 0 failed

看到綠色檢測結果讓人安心。這是個錯誤的想法。

原因:人工智慧一旦看到程式碼,就會編寫測試案例來驗證目前的實作。當然,測試案例第一次執行就會通過——這並非成功。

像 Serena 這樣的工具會自動讀取程式碼。你無法隱藏它。因此,你必須明確地指示:

❌ "Write tests for this code."
✅ "Write tests based on docs/specs/cli.md.
    Do not read the implementation. Tests must derive from the spec."

為什麼規範驅動開發很重要

事後看來,這就是「規範驅動開發」成為趨勢的原因。

  1. 規範被細分為許多細粒度的問題。

  2. 每期都包含人工智慧的詳細操作說明。

  3. 人工智慧會發現問題並加以解決。

  4. GitHub MCP 會為每個功能建立分支。

  5. PR會被審核。

遵循這個流程就能自動避免程式碼風格上的災難。這確實是一個很好的流程。

人工智慧發展成熟度金字塔

人工智慧輔助開發可以用一個三層金字塔來描述。 Vibe 編碼處於最底層。只有達到至少第二層,才能可靠地運作公共專案。用戶會受到影響。


第三章:重啟過程

指導原則:“懷疑、核實、記錄”

重啟時我也使用了 Claude Code。

我向它坦白了一切,請求它提供復興計劃,它給了我一些既友善又實用的方案——不像岸邊露伴的懺悔室那樣。它奏效了。

  • .claude目錄下建立reboot子目錄作為命令中心。

  • 再次執行/init ,讓 Serena 從頭開始掃描整個儲存庫。

整個過程大約需要三天時間,因此需要人工在每次會話之間維護狀態。如果時間延長,人工操作又會成為瓶頸。

1. Assume everything outside reboot is untrustworthy.
2. Assume files are half-baked.
3. Assume docs are lying.
4. Figure out which parts are true.

那是人類的工作。克勞德·科德是戰略家;我只是個努力跟上步伐的小劉備。

第一階段:隔離

首先,我將現有檔案移至_old/目錄,以建立空白畫布。

# Removed or quarantined
- docs/ (including examples) → breeding ground for unchecked lies
- English and Chinese READMEs
- scripts/ (complex CI/CD)
- benchmarks (non-essential)
- CHANGELOG.md, CONTRIBUTING.md

結果:109 個檔案已更改,32145 行已刪除。

第二階段:尋找真相

我把 README_ja.md 中的每一句「它有效」的語句都手動驗證了一遍。

# Test each format
echo '{"a":1}' > test1.json
echo '{"a":2}' > test2.json
./target/release/diffx test1.json test2.json

發現

✅ All six formats (JSON/YAML/TOML/XML/INI/CSV) work.
✅ Output formats (CLI/JSON/YAML) work.
✅ --quiet, --ignore-keys-regex, --epsilon, --array-id-key work.
⚠️  --ignore-case may only affect values, not keys.
❓ --ignore-whitespace and directory diffs unverified.

結論:核心功能運作正常。問題出在未經驗證的功能。

第三階段:編寫規範

我只記錄了我親自確認的行為。

docs/specs/
├── cli.md   # CLI specs (exit codes, output, options)
└── core.md  # Core API specs

規範原則

  1. 在查看程式碼之前,先描述一下理想的行為。

  2. 檢查是否已實現。

  3. 只記錄真正有效的方法。

  4. 將損壞的部分標記為待辦事項。

  5. 永遠不要說謊。

第四階段:重建測試

我刪除了現有的 436 個測試案例(8,022 行),並根據規格重新編寫了它們。

新測試佈局

tests/
├── spec/       # Spec-driven unit tests (69 cases)
└── cmd/        # trycmd-based doc-as-test (19 cases)

為什麼要使用 trycmd

  • Markdown 既可用作文件,也可用作測試。

  • 文件不能脫離測試結果。

  • 你不可能憑空捏造文件。


第四章:離開單體倉庫

何時拆分

當以上所有情況都屬實時,我選擇了離開:

  1. 不同的建置系統:Cargo、npm 和 pip。

  2. 不同的發布節奏:需要獨立發布。

  3. 不同使用者群體:Rust、Node.js 和 Python 開發者。

  4. CI/CD 複雜性:跨語言相互依賴難以管理。

diffx 擊中了所有四個。

我是如何分割的

步驟 1:建立新倉庫

cd /home/kako-jun/repos/
mkdir diffx-js && cd diffx-js && git init
mkdir diffx-python && cd diffx-python && git init

步驟 2:移動程式碼

cp -r ../diffx/diffx-js/* ./diffx-js/
cp -r ../diffx/diffx-python/* ./diffx-python/

重要提示:我已刪除 Git 歷史記錄。保留歷史記錄會使一切變得複雜。

步驟 3:獨立貨物.toml

diffx-js 和 diffx-python 現在從 crates.io 拉取diffx-core

# diffx-js/Cargo.toml
[dependencies]
diffx-core = "0.6"  # versioned dependency instead of path

步驟 4:從 Monorepo 移除它們

# diffx/Cargo.toml
[workspace]
members = ["diffx-core", "diffx-cli"]
# diffx-js and diffx-python removed

分裂後的結構

/home/kako-jun/repos/
├── diffx/           # Rust only (simple)
│   ├── diffx-core/
│   ├── diffx-cli/
│   └── .github/workflows/
│       ├── ci.yml
│       └── release.yml
│
├── diffx-js/        # npm only
│   └── .github/workflows/
│       ├── ci.yml
│       └── release.yml
│
└── diffx-python/    # pip only
    └── .github/workflows/
        ├── ci.yml
        └── release.yml

好處

  1. 易於理解的 CI/CD :從六個工作流程 + 共享倉庫簡化為每個倉庫兩個工作流程。

  2. 獨立發布:不急;每種語言都可以按照自己的步調發布。

  3. 明確的所有權:每個程式碼庫只有單一職責。

  4. 更簡單的貢獻:Node 開發人員只需要閱讀 diffx-js。


第五章:發布工作流程技巧

拆分程式碼庫讓我明白了一個至關重要的原則。

切勿將建置和發布合併在一起

反模式

# ❌ Dangerous workflow
name: Release
on:
  push:
    tags: ["v*"]

jobs:
  build-and-publish:
    steps:
      - run: cargo build --release
      - run: cargo publish # publishes before confirming all builds succeed

為什麼說它不好:

  1. 如果 Windows/macOS/Linux 建置成功,只有一個系統版本成功,該怎麼辦?

  2. cargo publish無法撤銷。

  3. 即使你發現了問題,唯一的解決方法也是提高版本號碼。

  4. 你無緣無故刻錄版本(v0.6.1 → v0.6.2 → v0.6.3...)。

正確方法:兩階段釋放

# ✅ Safe workflow (release.yml)
name: Release
on:
  push:
    tags: ["v*"]

jobs:
  build-linux:
    runs-on: ubuntu-latest
    steps:
      - run: cargo build --release
      - uses: actions/upload-artifact@v4

  build-macos:
    runs-on: macos-latest
    # ...

  build-windows:
    runs-on: windows-latest
    # ...

  create-release:
    needs: [build-linux, build-macos, build-windows]
    steps:
      - uses: actions/download-artifact@v4
      - uses: softprops/action-gh-release@v1
        with:
          files: |
            diffx-linux/*
            diffx-macos/*
            diffx-windows/*
# ✅ Publish is a separate workflow (publish.yml)
name: Publish
on:
  workflow_dispatch:
    inputs:
      version:
        description: "Tag to publish"
        required: true

jobs:
  publish:
    steps:
      - run: gh release view v${{ inputs.version }} # confirm release exists
      - run: cargo publish

為什麼需要兩個階段?

Step 1: Push tag → build for all platforms → create GitHub release
        ↓
        Stop here. A human verifies everything.
        ↓
Step 2: Manually trigger the publish workflow
        → Push to crates.io / npm / PyPI

故障場景

| 場景 | 單階段工作流程 | 兩階段工作流程 |

| ------------------- |----------------------------- | ------------------- |

macOS 建置失敗 | 已發佈損壞版本 | 未發佈任何內容 |

| 恢復 | 必須發佈 v0.6.2、v0.6.3… | 刪除標籤,重新推送 |

版本消耗 | 浪費 | 高效率 |


第六章:重啟手冊

正確的重啟順序

1. Run the code yourself and find the truth.
2. Write specs in docs/specs/.
3. Build tests from those specs.
4. Fix the implementation until tests pass.
5. Update docs (README, etc.) to match the specs.

反模式

  • 先寫文件→它們會變成謊言。

  • 相信現有的測試結果→它們只能驗證表面上的結果。

應該刪除什麼

  • 舊測試用例編寫時沒有遵循規範。

  • examples/目錄(它們腐爛成謊言)。

  • 舊路線圖(已執行或過時)。

  • 宣傳資料(六個月後失效)。

哪些東西需要保留

  • docs/specs/ – 唯一真理的來源。

  • tests/cmd/ – 由測試強制執行的文件。

  • .claude/tasks.md – 目前任務清單。

  • CLAUDE.md – 最低開發規則。

時間預算

Specs: 1 session
Tests: 1 session
Docs: 1 session
Cleanup: 1 session

Total: about four sessions (one session = one context window).

概要

之前(2025年8月)

❌ Frozen for 3 months
❌ Monorepo complexity
❌ Broken CI/CD
❌ Maintaining three languages
❌ Happy as long as "it runs"
❌ Blind faith in existing code

之後(2025年12月)

✅ Back in motion
✅ Lean Rust-only repo
✅ Separate language-specific repos
✅ Focused on Japanese docs
✅ Obsessed with correctness
✅ Doubt everything

定量變化

| 指標 | 前 | 之後 |

| ------------ | -------------- | ---------------- |

文件 | 很多 | -109 |

| 線 | 多 | -27,770 |

| 測試 | 436(意義?) | 88(規範驅動) |

| 自述文件 | 3 種語言 | 3 種語言 |

|存放庫 | 1 (單一倉庫) | 3(每種語言)|

關鍵課程

重啟一個停滯了三個月的專案並不需要新功能或花哨的技術。

這需要質疑的勇氣刪除的勇氣

  • 對現有測試結果表示懷疑。

  • 懷疑文件的真實性。

  • 質疑人工智慧現狀報告。

  • 懷疑你對「完成」的理解。

  • 刪除任何可疑物品。

我以前一直很納悶,為什麼聰明人也會犯下沉沒成本謬誤。結果發現,我也是其中之一。

你之所以對測試、文件和 CI/CD 如此執著,是因為「丟掉它們」感覺很浪費。但保留這些損壞的工件對誰都沒有好處。我最終言行一致,把它們都刪除了。

這是重啟的核心,也是永續發展的關鍵。


額外提示:對於 AI 輔助程式碼,預先提交是強制性的。

人工智慧引入了一個微妙的問題。

VS Code 的儲存時格式化功能從未運作。

當人類在 VS Code 中編寫程式碼時,格式化程式和.editorconfig檔會自動套用。而當 AI 直接寫入檔案時,這些都不會觸發。

結果:

  • 縮排錯位

  • 缺少尾隨換行符

  • 隨機導入順序

  • 到處都是無關緊要的 lint 警告。

CI 會因為一些無意義的事情而失敗,浪費時間。

解決方案:pre-commit鉤子

設定 pre-commit,以便在每次提交之前執行格式化和程式碼檢查。以下是 diffx-python 的實際配置:

# .pre-commit-config.yaml (diffx-python)
repos:
  - repo: local
    hooks:
      - id: cargo-fmt
        name: cargo fmt
        entry: cargo fmt --
        language: system
        types: [rust]
        pass_filenames: false

      - id: cargo-clippy
        name: cargo clippy
        entry: cargo clippy -- -D warnings
        language: system
        types: [rust]
        pass_filenames: false

  - repo: https://github.com/astral-sh/ruff-pre-commit
    rev: v0.8.6
    hooks:
      - id: ruff
        args: [--fix]
      - id: ruff-format

  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v5.0.0
    hooks:
      - id: trailing-whitespace
      - id: end-of-file-fixer
      - id: check-yaml
      - id: check-toml
      - id: check-added-large-files
# Setup
pip install pre-commit
pre-commit install

在 diffx-js (Node.js) 中,我改用 Husky:

// package.json (diffx-js)
{
  "scripts": {
    "prepare": "husky"
  },
  "devDependencies": {
    "husky": "^9.1.7"
  }
}

這樣,AI編寫的程式碼在提交時就會自動格式化。


儲存庫

{% github kako-jun/diffx %}

{% github kako-jun/diffx-js %}

{% github kako-jun/diffx-python %}

我還沒有寫正式的發布文章,但這些專案的初始版本都能正常運作,這足以證明重啟過程是可重複的——至少對我的生態系統而言是如此。

{%github kako-jun/define %}

{% github kako-jun/lawkit %}


原文出處:https://dev.to/kako-jun/my-oss-stalled-for-3-months-because-of-misguided-vibe-coding-this-is-the-full-reboot-story-2da5


精選技術文章翻譯,幫助開發者持續吸收新知。

共有 0 則留言


精選技術文章翻譯,幫助開發者持續吸收新知。
🏆 本月排行榜
🥇
站長阿川
📝13   💬9   ❤️4
346
🥈
我愛JS
📝1   💬7   ❤️2
56
評分標準:發文×10 + 留言×3 + 獲讚×5 + 點讚×1 + 瀏覽數÷10
本數據每小時更新一次
🔧 阿川の電商水電行
Shopify 顧問、維護與客製化
💡
小任務 / 單次支援方案
單次處理 Shopify 修正/微調
⭐️
維護方案
每月 Shopify 技術支援 + 小修改 + 諮詢
🚀
專案建置
Shopify 功能導入、培訓 + 分階段交付