Claude Codeと協働してOSSをゼロから作って公開してみた

Claude Codeと協働してOSSをゼロから作って公開してみた

Clock Icon2025.07.14

こんにちは。サービス開発室の武田です。

世はまさにAI活用時代!っていう感じで、すでにAIどうなの?と様子見するフェーズは過ぎて、どう活用していくかというフェーズになっています。
文書作成やメールの添削、数学の問題を解いてもらうなんてことも簡単にできるようになりました。

さてIT業界にいて気になることといえば、AIコーディングではないでしょうか。たとえば次のようなコーディング用AIエージェントがありますね。

  • Cursor
  • GitHub Copilot Agent
  • Claude Code

私はClaude Codeの業務利用を始めているのですが、今回ひとつのアウトプットとしてゼロからOSSを作成して公開までやってみました。

今回作ったソフトウェア

今回はjqのようにJSONデータをクエリや加工でき、式言語としてJSONataを採用したツールです。jfqというツールも少し使わせていただいたのですが、機能的に不足している部分もあったため、いい機会なので作ってしまおうというモチベーションです。

https://github.com/TAKEDA-Takashi/jt-cli

NPMおよびHomebrewからインストールできますので、興味ある方は使ってもらえるとうれしいです。

(JTといえばユピテルサンダー) JSONata Query Toolでjtです。

最初のプロンプト

今回初期設計からテスト、機能追加、リファクタリングなどすべてClaude Codeで行いました。

「こういったソフトウェアを作りたい」というざっくりとした構想だけ持っている場合、それを具体化するのが最初にするべきことです。具体化が進むほどAIコーディングの品質も上がります。もちろん100%自分で具体化できれば早いのですが、なかなか難しいですよね。そんなわけで、そこもAIと対話して進めましょう。

実際に私が一番初めに入力したプロンプトは次のものです。

このリポジトリは新規プロジェクトです。
以下を目的としています。
1. JSONデータをクエリ、加工するCLIツール
2. 標準入力または指定したファイルのJSONデータをJSONataを使ってクエリする
3. 入力フォーマットについては、JSON、YAML、JSON Linesに対応する。デフォルトはJSONでオプションで切り替えられる
4. パッケージとして公開することを目標とする(Homebrew、NPMなど)
5. 出力はそのままJSONataのクエリ結果でいいが、CSVで出力するモードも欲しい

まずはREADMEとClaude.mdを作成したいです。
必要な項目はヒアリングしてください。

ここでのポイントは次の3点です。

  1. ゴールの明確化(JSONデータをクエリするCLIツール作成)
  2. 求めている結果の明確化(ドキュメント作成)
  3. ヒアリングを求める

AIはぼんやりとしたことを伝えても割とうまくやってくれます。ただしそれが求めていることをきちんとやってくれるかというと、割と迷走することも多いです。そのため、ゴールからのずれをできる限りなくすためには、できる限り具体化する必要があります。

また覚えてほしいこととして、 AIはすぐ前のことを結構忘れる ということです。セッション内のやりとりはある程度引き継いでくれるのですが、clearしたり再起動すると全部忘れます。前述したように、同じセッション内であっても結構忘れます。これの対策は ドキュメント化 です。仕様や方針、ToDoなどあらゆることをAIリーダブルなドキュメントとすることで、このズレを抑えることができます。AIリーダブルと言われると少し身構えてしまいますが、「構造化されたプレーンテキスト」……Markdownを使っておけば大丈夫です。ちなみに必要なドキュメントの作成もAIに依頼すればOKです。

そして最後に、AIは単なるワーカーではなく、根負けしない優秀な壁打ち役と認識しましょう。AIは何度でも根気よく対話してくれますし、見落としがちな視点を補ってくれます。今回「ヒアリングしてください」とプロンプトに含めましたが、こう書くことでAIから情報収集をしてくれます。

先ほどのプロンプトの返答は次のものでした。

新規CLIツールプロジェクトのREADMEとClaude.mdを作成するために、いくつか確認させてください:

## 基本情報について

1. **プロジェクト名**: CLIツールの名前は決まっていますか?(例:jt, jsonata-cli, jqt など)

2. **ターゲット言語**: 実装に使用する言語は何を想定していますか?(Node.js/TypeScript、Go、Rust など)

3. **ライセンス**: どのライセンスを使用予定ですか?(MIT、Apache 2.0、GPL など)

## 機能詳細について

4. **CLIインターフェース**: 基本的な使い方のイメージはありますか?
   - 例:`jt 'query' input.json`
   - 例:`cat data.json | jt 'query'`
   - 例:`jt -f yaml 'query' input.yaml`

5. **出力フォーマット**: CSV出力以外に必要な出力形式はありますか?(整形済みJSON、TSV など)

6. **エラーハンドリング**: 無効なJSONやクエリエラーの場合の動作について要望はありますか?

## 開発・配布について

7. **初期バージョン**: 最初のリリースで必須の機能と、後回しにできる機能の優先順位はありますか?

8. **テスト戦略**: ユニットテスト、統合テストなどの方針はありますか?

9. **CI/CD**: GitHub Actionsなどを使用する予定はありますか?

これらの情報を教えていただければ、プロジェクトに適したREADMEとClaude.mdを作成する計画を立てられます。

ヒアリングの重要性

AIは「簡潔な回答」と「明確な制約」を好むようです。いらない場合は単に 不要 と回答しました。AIとの振り返りで高評価だったのは2の回答です。次のように回答しました。

言語は実装しやすければこだわりはありませんが、JSONataのライブラリは使用したいです

これによってAIは「JSONataライブラリを使用する」という制約と「要件にあった任意の言語」という選択を得るようです。制約と選択って語呂がいいですね(H○NTER×HU○TERみたい)。実はJSONataのライブラリについてはNode.jsが一番成熟(というか公式)なのは知っていたので、おそらくNode.jsになるだろうとは思っていました。なのですが、言語選択をAIに任せてみようということで、先ほどのような回答にしました。

AIは各言語のライブラリを調査し、プロジェクトの要件に合う言語を選定しました。なおその際の評価結果は次の内容でした。ライブラリだけでなく、開発ツール全体で評価していることがわかります。

**TypeScript/Node.js**
- ✅ JSONataの公式実装(最新機能対応)
- ✅ NPM配布が容易
- ✅ CLI開発エコシステムが充実
- ❌ ランタイムが必要

**Go**
- ✅ 単一バイナリ配布
- ✅ 高速実行
- ❌ サードパーティ実装(v1.5.4相当)
- ❌ 最新JSONata機能が使えない可能性

**Rust/Python**
- 実装は存在するが、成熟度や機能完全性に課題

ドキュメントの効果

先ほど、AIは忘れるのでドキュメントに残すんだということを書きました。長期記憶の代わりがドキュメントになるわけですね。今回も一番初めにやったことはドキュメント作成でした。ドキュメントについて心得てほしいこととしては、ドキュメントは常に更新をしていくということです。何か方針の変更や新しいことをやった時に、そのセッション内では引き継いでくれるのですが、新しいセッションでは忘れてしまいます。

特に重要なのはCLAUDE.mdで、Claude Codeはここに書かれていることを基本として動作します。 メモリ とも呼ばれるもので、グローバルメモリとプロジェクトメモリが使用できます。

  • グローバルメモリ
    • ~/.claude/CLAUDE.md
    • ホームディレクトリ配下
  • プロジェクトメモリ
    • .claude/CLAUDE.md
    • プロジェクトルート配下

CLAUDE.mdを書いていく(育てていく)際に、私見として次のようなことに気をつけるとよさそうです。

  • 開発プロセスの指示
  • 採用すべきパターンの具体例を記載する
  • プロジェクトのディレクトリ構成
  • DRY原則やYAGNI原則といったソフトウェア開発のプラクティスを明記する

開発プロセスの指示とは、具体的にはTDD(Test-Driven Development)を記載します。AIが安全にコーディングをするために必要なものは 自動化されたテスト自動化されたLinter です。そのためCLAUDE.mdでテストファーストの実践を具体的に指示し、Linter/Formatterはプロジェクトの初期設定としてセットアップします。

1. test: ❌ 失敗するテストを書く
2. feat: ✅ テストが通る最小限の実装
3. refactor: ♻️ コードを改善(テストは通ったまま)

AIは抽象的な指示でもある程度汲み取って動作をしますが、より具体的な例を示すことで精度が高くなります。たとえば「エラーメッセージはユーザーフレンドリーなものを出力する」とだけ書くよりも、次のように具体的なパターンを書くとこれを踏襲してくれます。

// ❌ 悪い例
throw new Error('Invalid input');

// ✅ 良い例
throw new JtError({
  code: 'INVALID_JSON',
  message: 'Invalid JSON input',
  detail: `Unexpected token '${token}' at position ${position}`,
  suggestion: 'Check for missing quotes or commas in your JSON'
});

プロジェクトのディレクトリ構成を明示するのもAIにとっては重要な情報となります。次の例はsrc以下だけですが、全体を示してもよいでしょう。示すことでAIの情報探索やドキュメント作成の精度が上がります。

src/
├── index.ts        # エントリーポイントのみ
├── cli.ts          # CLI定義(Commander.js)
├── query.ts        # JSONataクエリ実行
├── formats/        # 入出力フォーマット
│   ├── input.ts    # パーサー(JSON/YAML/JSONL)
│   └── output.ts   # フォーマッター(JSON/YAML/CSV等)
└── errors.ts       # エラー定義とハンドリング

ソフトウェア開発のプラクティスはこれまで人間がソフトウェア開発を通して培ってきた知見です。もちろんAIも認識しているのですが、必ずしも実践してくれるとは限りません。そのためCLAUDE.mdに明示することで遵守するように促します。たとえば次のようなものを書いておくとよいでしょう。

  • DRY原則
  • YAGNI原則
  • KISSの原則
  • SOLIDの原則
    • 特に単一責任の原則

個人的にイチオシなのはYAGNI原則です。AIコーディングをしていると、将来に備えて だとか 後方互換性のため残しておく といったコードが現れます。前者はまんまYAGNIなのと、後者は公開APIとかなら分かるんですが、なぜかリファクタリングした際に修正前のメソッドシグネチャを残したりします。こういったケースでは次のように指示するときれいに掃除してくれます。

公開APIなどではないため後方互換は必要ありません

あと原則ではないのですが、コメントについても書いておくのがお勧めです。AIはWHATコメント(何の処理するのか)を書きがちです。DocコメントはWHATでいいのですが、ロジックのコメントはWHY(なぜ)であるべきです。ただこれは、どのプロジェクトでも共通ですので、私はグローバルメモリに書いてしまっています。

AIのクセを知ってうまくカバーする

プロンプトで指示をするだけで、自動的にコードが書かれていく様は結構感動します。私もはじめて触れた時とても感動しました。しかしずっとAIと協働していると よくないクセ が見えてきます。

  • デバッグさせるといきなり3箇所や4箇所修正して動作確認する
  • 「原因がわかりました!」と言って全然違うファイルを修正する
  • 「すべてのテストをパスしています!」というけど直前(すぐ上)のテストで ERROR! って出ている
  • カバレッジが伸び悩むと 目標のカバレッジを下げる
  • 行き詰まると近視眼的になり同じトライ&エラーを繰り返す
  • テストが通らない!もう無理!って判断すると テストをskipする
  • テストが失敗していても「エラーが出ていますが今回の変更には無関係です!」と言って作業を進める
  • pre-commitでエラーになっているのに「今はコミットを優先させましょう」と言って--no-verifyを付けてコミットする

こういった挙動もCLAUDE.mdを工夫したり、いわゆるプロンプトエンジニアリングで対応することになります。場合によっては作業を中断させて指示をし直すこともままあります。

近視眼的になる と言いましたが、これもシンプルなプロンプト一発で打開できることも多いです。具体的にこのプロジェクトでは、カバレッジが60%程度からなかなか上がらないという問題を抱えていました。何度指示をしてもmain関数のカバレッジがいっこうに改善されないという状況です。

カバレッジが低いということはつまり、 テスタビリティが低い わけです。対策は簡単ですね。関数分割などをしてテストしやすくすればいいのです。そこで私が入力したプロンプトは次の単純なものでした。

テスタビリティを向上させるためのリファクタリングはすでに検討済みでしょうか? ultrathink

これを受け、現在の実装となっているPorts-Adaptersパターンの提案があったため、それを受け入れました。ここで重要なのは どのパターンを適用すれば改善できる といった具体案は出していないことです。

AIコーディングにおけるエンジニアの役割

これまでのシステム開発ではアーキテクト、プログラマー、デベロッパー、コーダー、etc.と呼び方は数あれど、設計から実装、テストまで(当たり前ですが)人間が行ってきました。またAIエージェントが出たての頃は、プログラミングの主は人間であり、AIはそのサポートをしていました(ペアプロでいうところの、人間がドライバーでAIがナビゲーター)。AIコーディングではこれが逆になります、AIがコードを書き、人間が間違った方向に進まないようにサポートします。

ではそうなった時に、エンジニアの役割はなんでしょうか?ズバリ 舵取り意思決定 です。AIは高速に提案と実装を繰り返してくれますが、その方向性を指し示すのと、結局どれを採用するのかという責任は人間が負うのです(コ○ン的にいうなら 五稜星 になることです(言いたかっただけ))。そして正しい決定をするためには正しいアーキテクチャ、正しいデザインパターン、正しい原則、正しい開発プロセスの理解が必要不可欠だと考えます。

まとめ

巷ではAIコーディングの登場によってエンジニアは市場からいなくなるといった言説も見られますが、私の考えは違います。たしかに単純ワーカーとしての(いわゆる)コーダーは減るかもしれません(0にならないのはAIが適用できないドメインもあるはずだから)。

しかしシステム開発において 正しい決定 をできる人がどれほどいるでしょうか?今回作成した小さいプロジェクトでさえ、アーキテクチャの変更やオプションの変更など繰り返しています。そして先述したように、それをするためにはソフトウェア開発の知識や経験だけでなく、ドメイン知識なども求められます。将来的にAIがそれらも高い品質、精度で賄えるようになったとしても、エンジニアに求められるものはそう変わらないというのが現時点での私の考えです。

AIの荒波に負けないよう、頑張っていきましょう。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.