🛺

ClaudeCodeでContext Engineeringに沿った開発フローを探索する

に公開

はじめに

日々変化するAIの世界において、「Context Engineering」という言葉がVibe Codingに続く新たなトレンドとなりつつあります。
トレンドとなったきっかけはこの2人のツイートのようです。
https://x.com/karpathy/status/1937902205765607626
https://x.com/tobi/status/1935533422589399127

Vibe Codingの普及により、POC開発や趣味プロジェクトにおいては、人間が1行もコードを書かなくても動くものが作成されるところまで進化してきています。加えて、企業におけるソフトウェア開発においても、人間の介入なしにAIがコードのほとんどを開発できるケースも増えてきました。

ただ、実際にAIが書いたコードを人間のレビューなしにリリースできるかというと、そこまでには至っていないのが現状です。600人ほどを対象にqodoが実施したレポートを確認したところによると、76%のエンジニアが人間のレビューなしにリリースするほどの信頼感がないと回答しているようです。

https://www.qodo.ai/reports/state-of-ai-code-quality/

今後、企業におけるソフトウェア開発でも人間の介入を減らし、品質の高いコードを生成し続けるためにはどうすべきかを考える上で、Context Engineeringという考え方が非常に参考になると感じています。この記事では、Context Engineeringの簡単な概要と、ClaudeCodeを使った実践例についてご紹介します!

Context Engineeringとは何か

Contextの定義

まず、Contextとは何かについて、12ファクターエージェントの定義から抜粋してみます。

https://github.com/humanlayer/12-factor-agents

prompt

  • システムプロンプト
    • モデルの動作を定義する初期のプロンプトである
    • 従来のプロンプトエンジニアリングの領域であり、いかにLLMの出力品質を高めるプロンプトを提供できるかが重要である
  • ユーザープロンプト
    • ユーザーからのタスクまたは質問である
    • システムプロンプトと同様に従来のプロンプトエンジニアリングの領域である

memory

  • 短期記憶(状態/履歴)
    • ユーザーとモデルの応答を含む現在の会話や会話の状態である
  • 長期記憶
    • 過去の会話履歴や活動履歴の要約であったり、永続的に覚えておくよう指示されたものを含む知識である

RAG

モデルの外部から取得できる知識です。最新の知識であったり、特定領域の質問に答えるためのドキュメントやデータベースなどが含まれます。

Tools

呼び出すことができるすべての関数です。FunctionCallingやMCPなども含まれます。

Structured Output

モデルのレスポンスフォーマットに関する定義です(GPTやClaudeなど基盤モデルプロバイダーのAPIで利用可能)

Context Engineeringとは

いくつかのブログポストを確認しましたが、一言でまとめると、以下の定義がしっくりきています。

「Context Engineering」とは、これらのContextを適切なタイミングかつ適切な形式で提供するシステムを設計・構築する手法

これまでも適切なプロンプトを作ることや、適切なタイミングでToolを呼び出したり、RAGを参照する重要性は説かれていました。1つ1つが新しい概念ではありませんが、いくつかの重要な手法がまとめて概念化されたものといえます。

LLMのパフォーマンスを最大限発揮するためには、プロンプトのやりとりを工夫するだけではなく、Contextを適切に管理することが重要だという考えに基づいています。

コンテキストエンジニアリングの重要性については、Langchainの記事が一番分かりやすかったので抜粋します。(以下日本語訳)

エージェント・システムが失敗するとき、それは主にLLMが失敗するためである。第一原理から考えると、LLMが混乱する理由は2つある:

  1. 基礎となるモデルが混乱している。
  2. 基礎となるモデルが、良い出力をするための適切なコンテキストを渡されなかった。

多くの場合(特にモデルが良くなるにつれて)、モデルのミスは2番目の理由によって引き起こされます。モデルに渡されるコンテキストが、いくつかの理由で間違っている可能性がある:

  • モデルが正しい判断を下すために必要なコンテキストが欠けている。モデルは心を読むわけではない。適切な文脈を与えなければ、彼らはその存在に気づかない。
  • 文脈のフォーマットが適切ではありません。人間と同じように、コミュニケーションは重要です!モデルにデータを渡す際のフォーマットの仕方は、そのモデルの応答に絶対的な影響を与えます。

https://blog.langchain.com/the-rise-of-context-engineering/

1〜2年前までは、AIエージェントのシステムやタスクが失敗する場合、基盤モデルが混乱しているか、有効なプロンプトが渡されていないかの2択に帰着することが多くありました。基盤モデルの性能向上とコンテキストウィンドウの拡大により、基盤モデル側が原因となり失敗するシステムは少なくなっているという言説が増えています。

もちろん、基盤モデル側の性能限界で生じる問題が0になったわけではありません。ただ基盤モデルの性能が上がってきている昨今においては「LLMが期待する結果を出力する上で最高のコンテキスト」を提供できて初めて、基盤モデルの性能限界を語れると言えるのではないでしょうか。

補足)Prompt Engineeringが不要になるということではない

なお、Contextの定義からも分かるとおり、「Context Engineering」は「Prompt Engineering」を置き換えるものではなく、「Context Engineering」の1要素です。「Prompt Engineering」が重要であることは今後も変わらない事実ですが、AIのパフォーマンスを最大化する概念として、Prompt以外も含めて包括的に定義された形だと捉えています。

Context Engineeringの考えに基づく開発をClaudeCodeで

「Context Engineering」の考えに基づき、開発を進めるためのガイドラインとして、注目を集めているリポジトリを見つけました。
このリポジトリで紹介されているワークフローを紹介します。

https://github.com/coleam00/context-engineering-intro

ワークフローの概要

ディレクトリ全体の構造は以下のようになっています。
なお、PRPについては「Product Requirement prompts」と言及されており、PRDの情報を参照した上で、LLMのアウトプットを最大化させるコンテキストの参照先を示したドキュメントとなっています。

PRPという言葉については、このリポジトリの著者が作成したものであり、まだ一般的な用語ではないようです。ドキュメントの名前や概念自体はどのような形式でも良いと思いますが、PRPの中に記載されている項目は非常に参考になるものでした。

context-engineering-intro/
├── .claude/
│   ├── commands/
│   │   ├── generate-prp.md    # Generates comprehensive PRPs
│   │   └── execute-prp.md     # Executes PRPs to implement features
│   └── settings.local.json    # Claude Code permissions
├── PRPs/
│   ├── templates/
│   │   └── prp_base.md       # Base template for PRPs
│   └── EXAMPLE_multi_agent_prp.md  # Example of a complete PRP
├── examples/                  # Your code examples (critical!)
├── CLAUDE.md                 # Global rules for AI assistant
├── INITIAL.md               # Template for feature requests
├── INITIAL_EXAMPLE.md       # Example feature request
└── README.md                # This file

ワークフローの流れ

実際の開発フローとしては、以下のような流れになります。

  1. CLAUDE.mdにプロジェクトの構造やテスト方針などを記載する。プロジェクト全体の設定はここに記述
  2. タスクに着手するタイミングでINITIAL.mdを作成する
  3. /generate-prp INITIAL.mdのコマンドを実行してPRPを作成する
    • .claude/commands にカスタムコマンド用mdファイルを配置します。
  4. PRPの内容が問題ないか確認し、必要に応じて更新する
  5. /execute-prp PRPs/your-feature-name.mdのコマンドでClaude Codeによるコーディング開始
    • 3と同様

実際に作成されたPRP

実際に作ってみたPRPがこちらになります。

EXAMPLE_PRP.md
# External Service Store Status Sync PRP

## Goal
外部サービスの店舗ステータスと内部システムの注文受付ステータスを自動同期する機能を実装し、店舗スタッフが管理画面で現在の受付状況を一目で確認できるようにする。指定環境でのみ有効化し、ステータスの不整合を防ぐ。

## Why
- **ビジネス価値**: 店舗スタッフの手動操作を削減し、注文受付ミスを防止
- **既存機能との統合**: 既存のstore state管理システムに統合し、統一的な管理を実現
- **解決する問題**: 外部サービスと内部システムのステータス不整合による注文受付の混乱を解消

## What
### ユーザーに見える動作
1. 管理画面の注文受付停止画面で外部サービスのステータスが自動的に反映される
2. 外部サービスがOPENの時、内部システムも自動的に注文受付可能になる
3. 外部サービスがCLOSEDの時、内部システムも自動的に注文受付停止になる

### 技術要件
- 外部サービス Store Status APIとの統合
- 指定環境でのみ有効化
- 既存のstore state管理システムとの整合性

## Context
### Documentation
- url: [外部サービスのAPIドキュメントURL]
  why: 外部サービスAPI認証に必要な認証方式の実装方法

### Code Patterns
- pattern: internal/infrastructure/api/external_service/http_client.go
  why: 既存の外部サービス HTTPクライアント実装(認証含む)
  
- pattern: internal/server/application/usecase/store/get_store_state_external.go
  why: 外部APIステータス取得の統合パターン
  
- pattern: internal/server/application/usecase/store/sync_latest_delivery_store_state.go  
  why: ステータス同期の実装パターン(並行処理、差分更新)
  
- pattern: internal/infrastructure/api/similar_service/get_venue_status.go
  why: 類似の外部APIステータス取得実装

### API Specification
```yaml
endpoint: /api/v1/store/status
method: GET
auth: HMAC-SHA256
query:
  - storeCode: string (required)
response:
  code: SUCCESS | 000000 | 400 | 90004 | 90008
  message: string
  content:
    status: OPEN | PREPARING | CLOSED
`​``

### Status Mapping
```yaml
外部サービス -> 内部システム:
  OPEN -> accepting
  PREPARING -> pending
  CLOSED -> pending
`​``

## Implementation Blueprint

### 1. Data Models
```go
// internal/domain/apimodel/external_service/store_status.go
type GetStoreStatusRequest struct {
    StoreCode string
}

type GetStoreStatusResponse struct {
    Status string // OPEN, PREPARING, CLOSED
}

type StoreStatusAccessor interface {
    GetStoreStatus(ctx context.Context, req GetStoreStatusRequest) (*GetStoreStatusResponse, error)
}
`​``

### 2. API Client Implementation
```go
// internal/infrastructure/api/external_service/get_store_status.go
func (c *Client) GetStoreStatus(ctx context.Context, req GetStoreStatusRequest) (*GetStoreStatusResponse, error) {
    // 1. Build request with authentication
    // 2. Execute HTTP GET request
    // 3. Parse response
    // 4. Handle errors
}
`​``

### 3. Application Usecase
```go
// internal/server/application/apiusecase/external_service/get_store_state.go
func (u *GetStoreStateUsecase) Execute(ctx context.Context, storeID, storeCode string) (string, error) {
    // 1. Call external service API
    // 2. Map status (OPEN->accepting, CLOSED/PREPARING->pending)
    // 3. Return mapped status
}
`​``

### 4. Sync Logic Implementation  
```go
// internal/server/application/usecase/external_service/sync_store_status.go
func (u *SyncStoreStatusUsecase) Execute(ctx context.Context, storeID string) error {
    // 1. Get current internal system status
    // 2. Get external service status
    // 3. Apply sync logic:
    //    - Internal pending + External open -> Internal accepting
    //    - Internal accepting + External closed -> Internal pending
    // 4. Update if changed
}
`​``

### Task Order
1. 環境変数の追加(外部サービス関連)
2. API Client層の実装(GetStoreStatus)
3. Domain Model定義(Accessor interface)
4. Application Usecase実装(GetStoreState)
5. Sync Logic実装
6. テスト実装
7. ドキュメント更新

## Validation Loop

### Level 1: Syntax & Style
```bash
# フォーマットチェック
make fmt

# リンターチェック  
make lint
`​``

### Level 2: Unit Tests
```bash
# モック生成
make go-gen

# テスト実行
make test
`​``

### Level 3: Integration Tests
```bash
# API呼び出しテスト(go-vcr使用)
go test -v ./internal/infrastructure/api/external_service/...

# ステータス同期テスト
go test -v ./internal/server/application/usecase/external_service/...
`​``

### Level 4: Manual Verification
```bash
# 指定環境でのみ動作確認
export APP_ENV=target_environment

# APIエンドポイント確認
curl -X GET "http://localhost:8080/api/v1/stores/{storeId}/state"

# ログ確認
tail -f logs/app.log | grep external_service
`​``

## Success Criteria
- [ ] 指定環境でのみ機能が有効
- [ ] ステータス同期ロジックが仕様通り動作
- [ ] エラー時の適切なハンドリング
- [ ] 既存のstore state管理との競合なし
- [ ] テストカバレッジ80%以上

### Error Handling
- API timeout: 10秒
- Retry: 3回(exponential backoff)
- エラー時はログ記録のみ(既存ステータス維持)

### Performance Considerations
- 並行処理: 最大20店舗同時
- キャッシュ: なし(リアルタイム性重視)
- Rate limit: 外部サービスAPIの制限に準拠

## Risk Mitigation
1. **API障害対策**: Circuit breakerパターン実装
2. **データ不整合対策**: トランザクション内での更新
3. **過負荷対策**: 同期処理の並列数制限

## PRP Quality Score: 9/10
高い信頼度で一度の実装で成功可能。既存パターンが充実しており、明確な実装パスが定義されている。

実際にやってみた成果

このPRPを起点に実装をやってみたのですが、ファイルチェンジが10ぐらい、なおかつ既存実装で参考にできるものがあるケースにおいては、AIとのやり取りが往復することなく、ほぼ一発で生成できました!

プロジェクトごとに様々な要件がありますが、PRPのテンプレートファイルを編集すれば問題ありません。
例えば、TDDを導入したい場合、PRPのテンプレートファイルを編集すれば問題ありません。MCPなどの参照を追加したい場合もコンテキストセクションに追加すれば問題ありません。

興味深いポイント

PRPの末尾には「PRP Quality Score: N/10」というセクションがあり、多角的な観点から計画を評価してくれます。以下は自社のプロジェクトを読み込ませた時に生成されたスコアリングの例ですが、ここはプロジェクトの要件に合わせてカスタマイズできます。

### スコアリング基準(10点満点)

| カテゴリ | 配点 | チェック項目 |
|---------|------|------------|
| **コンテキスト完全性** | 3点 | - 参照実装パターンの有無<br>- 外部ドキュメントリンク<br>- エラーハンドリング例 |
| **実装詳細の明確性** | 3点 | - データモデル定義<br>- 擬似コードまたは実装例<br>- バリデーションステップ |
| **テスト戦略** | 2点 | - ユニットテスト例<br>- 統合テスト計画 |
| **DDD準拠** | 2点 | - レイヤー依存性の遵守<br>- 既存パターンの活用 |

### スコアの解釈

- **9-10点**: 一度の実行で高品質な実装が可能
- **7-8点**: 実行可能だが、軽微な調整が必要
- **5-6点**: 追加のコンテキストが必要
- **4点以下**: 大幅な改善が必要

「Contextがすべて」の考えに則った開発ワークフローの構想

PRPのようなスコアリングをしながら計画ドキュメントを作っていく仕組みがチームの標準となった場合、まずこのドキュメントをレビューしてから開発を始めましょうでも良いかもしれませんし、そもそもこの計画ドキュメントがあれば、あとはDevinなり、ClaudeCodeActionに実装してもらう形でも良いかもしれません。

重要なことは「Contextがすべて」であるという考え方であり、言い換えると、AIが活躍できる仕組み作りをいかに上手く設計するかが鍵となります。AIに指示を与え続けて正解を導くのではなく、AIが活躍できる仕組みをひたすら作ってあげる感覚に近いものです。

まとめ

今回の記事では、「Context Engineering」の概要と開発フローに落とし込んだ時にどのような考え方になるのかを紹介しました。

上記プロジェクトではあまり登場しませんでしたが、Contextの参照先としてMCPを使うことも可能ですし、プロダクトのドメイン知識を記載したドキュメントを配置しておくのも良いかもしれません。

AIに指示を出すのではなく、AIが成果を出す仕組みを作るにはどうしたら良いか。この問いに向き合っていくと「Context Engineering」という概念にたどり着きます。
今後この概念は、ツールに依らず汎用的なベストプラクティスとなっていくのかなと感じています。

ぜひ、日々の開発フローに取り入れてみてください〜

参考URL

https://blog.langchain.com/the-rise-of-context-engineering/

https://rlancemartin.github.io/2025/06/23/context_engineering/

https://cognition.ai/blog/dont-build-multi-agents

https://youtu.be/8kMaTybvDUw?si=7OOkzZ5UXIM5TrIv

旧tacomsテックブログ

Discussion