ζ3の覚書
カテゴリ: [開発日記]
⏱️ 10 MIN

AI時代な今ならブログ作れるんじゃね?

AI時代な今ならブログ作れるんじゃね?

自分で文章書くのがめんどくさすぎて、今まで何一つ続かなかったけど、 AIがいい感じにやってくれる今ならなんとか続けられんじゃねーかなって


1. なんとなくな背景

普段業務ではバリバリClaudeCode使ってる. ありがたいことに、遠慮なくAIリソース使わせてもらってるおかげで、 ここ1年間、手でコードを書いた回数はマジで片手で数えるほどしかないかも.

んでまぁ、個人の方では普段使わないスタックで普段しないことしようかなと

OpenCode x DeepSeek V4 (OpenCode Go) が、普段のClaudeCodeに比べて、どの程度使えるかを試してみようかってところ.

なんかコスパいいらしいじゃん?

ClaudeCodeノウハウの流用で、そこそこな数のカスタムskillがごちゃついてるので、 その辺を統合・最適化してどこまで効果が出るかみたいなのを試せればいいなって


2. 技術スタック選定

とりあえず、OpenCode x DeepSeek V4 なのは確定.

あとは、最近気に入ってるスタックをピックして

Astro/StarwindUI(tailwindCSS)/cloudflare でなんか作ろうかなと

余裕があればEmDashを試してみたい

OpenCodeもなんかプラグインやらいくつもあるみたいだし、 その辺、良い感じにつかってみようってところ

デザイン・レイアウトはChatGPTと雑談しながら決めたやつを流用. その流れで要件定義書もどきまで作ってもらって、そのままOpenCodeに突っ込んで実装開始した.


以下、セクション3〜7は実際にOpenCode(DeepSeek V4)が行った作業の報告です。開発プロセスをAI自身の視点で記述します。

3. 環境セットアップ — OpenCode × Obsidian

3.1 OpenCode の導入

環境は WSL2 on Windows です。起動は source .env && opencode . だけで完了します。これだけです。

プラグインについては、当初13個程度が有効になっていましたが、superpowerspr-review-toolkit など、custom skill で代替可能なものが多く含まれていることがわかりました。精査の結果、13個から9個に削減し、44MB の容量を節約しました。

3.2 Obsidian vault 統合

Obsidian MCP サーバーを接続し、vault を OpenCode から読み書きできるようにしました。使用したのは cyanheads/obsidian-mcp-server で、14個のツールが利用可能です。

ここで最初の障害に遭遇しました。WSL2 の 9P プロトコルと fs.watch() に非互換があり、EISDIR エラーが発生したのです。解決策として、vault を vault/ サブディレクトリに移動しました。Obsidian 自体は WSLg(snap install)で起動しています。

skill 構成は以下の通りです:

  • obsidian-skills: Markdown / Bases / Canvas / CLI / Defuddle の一式
  • opencode-obsidian-knowledge: AKU パイプライン(inbox-triage → connection-review → weekly-synthesis → note-promotion)

3.3 階層化されたskillモデル

skill には built-in、global、project、plugin の4つのレイヤーが混在していました。各所で必要に応じて作成・導入されたため、内容の重複や相互連携は後回しになっていました。

具体的には以下のような状態です:

Layer 4: Plugin(document-skills, LSPs) → インフラ・ツール
Layer 3: Project(code-philosophy, obsidian-skills) → プロジェクト固有
Layer 2: Global(session-orchestrator, TDD, adversarial-review) → 横断的
Layer 1: Built-in(playwright, git-master) → 標準

同じ「コードレビュー」の知識が code-review(project) と adversarial-review(global) と review-work(builtin) の3箇所に重複しているケースが頻繁に見られました。

そこで、重複マップを生成して整理した結果、superpowerspr-review-toolkitsecurity-guidanceexample-skills の4プラグインを削除しました。すべて custom skill かビルトインでカバー可能な状態になりました。


4. ブログ構築プロセス

Phase 1: MVP(初日)

まずは動作するブログを構築しました。テーマは「観測記録所」です。

ユーザーから「こんなスタックでブログ作って」という大まかな要件のみを受け取り、あとは OpenCode が自律的に実装を進めました。

選定されたスタック:

  • Astro 6 SSG(Content Collections v6)
  • Tailwind CSS v4(@theme directive)
  • Starwind UI(shadcn/ui の Astro 移植)
  • pnpm(厳格モード)
  • Pagefind 1.5.2(日本語全文検索)

このフェーズで生成されたのは5ページ(index, about, archive, 記事2)+ダークテーマ+検索です。category: deep にタスクを投入したところ、ほぼ一発で完了しました。

Phase 2: Reading Session(2日目)

ローカルストレージを使用した読書履歴機能を実装しました。「どの記事を読んだか」「どこまでスクロールしたか」を保存する仕組みです。仕様のみを指示として伝え、実装させたところ、比較的スムーズに完了しました。

Phase 3: 全機能(3日目)

ここから一気に機能を追加しました。Orchestrator が並列で SubAgent にタスクを投入します。

  • D: タグフィルタ強化
  • E: アクセシビリティ(a11y)
  • C: ゲーム記録テンプレート
  • F: ライトモード
  • A: OGP(Open Graph)
  • H: robots.txt + sitemap

ユーザーが行った作業は結果の確認だけです。1回の並列 dispatch で5〜7分で完了しました。直列で処理していれば軽く30分はかかっていた計算になります。

デプロイ(同日)

完成後、デプロイも OpenCode が自動で実行しました。

npx wrangler pages deploy dist --project-name=observation-log --branch=main

wrangler の使い方も Cloudflare Pages の設定も含めて、ほとんど指示だけで完了しました。Cloudflare Pages の observation-log プロジェクトが作成され、https://observation-log.pages.dev で 200 が返ってくることを確認しています。カスタムドメイン zeta3.net も設定済みです。

Cloudflare の Global API Key を .env に保存した以外は、DNS の CNAME レコード設定からカスタムドメインのプロキシ有効化まで、すべて OpenCode が自動で実行しました。トークンを渡してしまえば、あとは任せきりで完了します。

期待以上の結果でした。

画像生成

アバター画像は Codex CLI が内蔵する image_gen(gpt-image-2)で生成しました。結果は ζ(ゼータ)をモチーフにしたサイバーパンク調の512x512のアバターです。記事のサムネイル表示も、この仕組みを応用して対応しています。


5. 技術スタックと選定理由

以下の表は、採用した技術スタックとその評価をまとめたものです。

技術選んだ理由使ってみて
Astro 6SSG 最強、Content Collections が便利ビルドが非常に高速です。ISR が不要なら第一選択肢です
Tailwind CSS v4@theme directive でデザイントークンを整理可能v3 より直感的で、設定ファイルが不要な点が優れています
pnpm厳格モードで依存関係の不整合を早期発見onlyBuiltDependencies でセキュアに運用できます
Pagefind日本語対応、静的サイトに最適--site フラグ周りに少し癖があります
jj (jujutsu)git より直感的な変更管理コミットを変更のスナップショットとして扱う概念が自然です

6. Agent Orchestration なワークフロー

Parallel fan-out(最も効果的だった方式)

Orchestrator(本レポートを記述している OpenCode 自身です)が SubAgent に対して並列で指示を出します。Phase 3 の D・E・C・F、A・G・H はすべて同時に投入され、5〜7分で完了しました。直列処理であれば軽く30分はかかっていたはずです。

各 SubAgent が自律的に実装を進め、結果を持ち帰ったら検証して通過させる。このループを回すだけでブログが完成しました。

task_id 継続

SubAgent は stateless であり、一度終了すると会話を忘れます。しかし task_id を指定して再開すると、前回のコンテキストをすべて保持したまま続きを実行できます。

これが地味に効果的です。「これ直して」と task_id 付きで指示を送るだけで、前回読んだファイルや失敗した試行を踏まえて修正を実施します。毎回ゼロから説明する必要がありません。

カテゴリ振り分け

最終的な routing はすべて opencode-go/* で統一しました。

  • quick(軽タスク): ほぼ100% 成功。typofix、config変更、RSS、OGP はすべてこれで対応
  • deep(重い自律タスク): 一度任せたら放置で完了。プロジェクト初期化や考察が必要なタスクに最適
  • visual-engineering(UI/複数ファイル): 安定稼働中
  • writing(ドキュメント): 精度が高いです

compress 定期実行

セッションが長くなると context が膨張します。そこで compress 機能を使用して古い会話を要約し、破棄します。

具体的には、議論が終了したタイミングで「これこれこういう決定をした」という2〜3行の要約に圧縮します。これを習慣化することで、セッションが半日以上続いても context が破綻しません。


7. ハマったポイント

以下は、開発中に遭遇した障害とその解決策です。

  • WSL2 9P × fs.watch(): EISDIR エラーが発生しました。vault をサブディレクトリに移動して解決しました
  • Obsidian MCP 認証: OBSIDIAN_API_KEYinsecureServer: true が必要でした
  • Pagefind —site フラグ: ドキュメント通りでは微妙にハマりました。Vite 外生化が必要です
  • Astro 6 キャッシュ: node_modules/.astro/data-store.json にパース済みコンテンツがキャッシュされます。記事を削除しても残るため、手動削除が必須です
  • jj の git 互換: まれに git との間にミスマッチが発生しますが、慣れれば問題ありません

8. 所感とこれから

もともと、普段のClaudeCodeの使い方も 指示を出して、並列作業させまくって、最終の出口をとりまとめて…みたいなスタイルでやってるので それを、OpenCode上で再現しつつ、最適化した感じ.

なのでまぁ、新鮮さとかその辺はないかな.普段からやってることの延長って感じ.

ただ、ClaudeCodeでやってることを、ここまでOpenCodeで再現できるのかってのと DeepSeek V4コスパええやん ってのは良かった.

あとは、思い切ってwranglerでぜーんぶお任せしてみたんだけど 勝手にドメインも紐つけてくれるし、何から何まで任せられるのはよきかな.

つっても、今回扱った技術領域・作業内容、普段から業務で触れている部分がほとんどなわけで 「変なことしてないか?」をいつでもジャッジできるからこその結果ってのはそう.

賛否あるのは承知してるけど、当面はこの「Agentに雑投げ -> 人間が最終監査」みたいな流れを最適化していくことになりそう. ※監査自体もAgentに任せてる事実はある.コミットログとかスクショベースのレポートのみで判断することもある. ※テストコード充実させろって話だわな.

今後は、せっかくcloudflareなわけだし、EmDash試したい.