「コンテキスト指向開発(Context Oriented Development)」で調べると、出どころの違う2つの考え方に行き当たります。原典の名称は別々で、この記事ではこの2つを比べます。1つは2008年に論文化されたコンテキスト指向プログラミング(COP)で、実行中の状況に応じてプログラムの振る舞いを部品ごと切り替える言語技術です。もう1つは、Googleが2025年12月に公開したConductorが掲げるコンテキスト駆動開発(Context-Driven Development)で、AIエージェントに渡す前提情報をリポジトリ内のファイルとして管理する開発の進め方です。この記事では両者を分けて、原典の定義、Pythonでの実行例、AIエージェントでの使い方、向かない場面を順に整理します。
まとめ:2つの「コンテキスト指向」と使い分け
- COPは、Hirschfeld・Costanza・Nierstraszが2008年にJournal of Object Technologyで論文化した言語技術です。状況ごとの振る舞いの差分を「レイヤ」にまとめ、実行時にレイヤを有効・無効にして切り替えます。
- コンテキスト駆動開発は、製品の目的・技術スタック・作業手順をMarkdownにしてコードと一緒に管理し、AIエージェントに毎回同じ前提で作業させる進め方です。GoogleのConductorが2025年12月17日にこの名前で公開しました。
- 名前は似ていますが、COPの「コンテキスト」は実行時の状況(時間帯・端末・権限など)、コンテキスト駆動開発の「コンテキスト」は開発の前提情報(要件・規約・計画)で、扱う対象が違います。
- COPの実装は言語ごとの研究用の拡張が中心で、Python版のContextPy3はPyPIの最新が2018年の1.0です。本番のコードで状況による切り替えが必要なら、Strategyパターンや機能フラグで足りるかを先に検討するのが現実的です。
- コンテキスト駆動開発は、複数人・複数セッションでAIエージェントを使う中規模以上の開発で効きます。数行の修正や使い捨てのスクリプトでは、文書を整える手間とトークン消費の増加が見合いません。
「コンテキスト指向開発」が指す2つの系統
検索で同じ言葉に見えても、学術の言語研究とAIエージェントの実務では意味がずれています。違いを並べると次のとおりです。
| 観点 | COP(コンテキスト指向プログラミング) | コンテキスト駆動開発 |
|---|---|---|
| 英語名 | Context-oriented Programming | Context-Driven Development |
| 主な発表 | 2005年ContextL・2008年JOT論文 | 2025年12月17日Conductor公開 |
| コンテキストの中身 | 実行時の状況(時間帯・端末・権限) | 製品の目的・技術スタック・手順 |
| 切り替わるもの | メソッドの振る舞い | AIエージェントが生成するコード |
| 成果物 | レイヤ(部分メソッドの集まり) | product.md・spec.md・plan.mdなど |
| 使う人 | 言語・ライブラリの利用者 | AIエージェントを使う開発チーム |
このほか、似た名前の別物が2つあります。ソフトウェアテストのContext-Driven Testingは、Cem Kaner・James Bach・Bret Pettichordが2001年に宣言した学派で、「実践の価値はその文脈に依存する」「文脈に応じた良い実践はあっても、ベストプラクティスは無い」など7原則を掲げます。テスト手法の考え方であり、COPともAIの開発手法とも関係はありません。また、Go言語のcontextパッケージのような「プログラミングでいうコンテキスト」は、キャンセルや期限を関数間で受け渡すための値を指します。こちらはGo言語のcontext入門で扱っています。
COP(コンテキスト指向プログラミング)の仕組み:レイヤと活性化
COPを提案した論文は、Robert Hirschfeld(ハッソ・プラットナー研究所)、Pascal Costanza(ブリュッセル自由大学)、Oscar Nierstrasz(ベルン大学)による「Context-oriented Programming」で、Journal of Object Technology第7巻3号(2008年3・4月号、125〜151ページ)に掲載されました。論文は、主流の言語には実行中の状況に合わせて振る舞いを変える仕組みが無く、開発者が入り組んだ設計で柔軟性を作り込んでいると問題を指摘しています。
レイヤ・活性化・動的スコープの定義
論文が挙げる中心の概念は3つです。
- レイヤ(layer):状況に依存する振る舞いの差分をまとめた単位です。論文は「Layers group related context-dependent behavioral variations」と定義し、プログラムから名前で参照できる第一級の値として扱います。
- 活性化(activation):レイヤを実行時に有効・無効にする操作です。有効なレイヤに含まれる部分メソッドが、元のメソッドの前後や代わりに呼ばれます。
- 動的スコープ:レイヤを有効にする範囲を明示できます。論文は、同じ実行中のアプリケーションでも、範囲が違えば同じ差分が有効にも無効にもなりうると書いています。
if文で分岐を書く場合との違いは、状況ごとの差分が1か所(レイヤ)に集まり、呼び出し側は「この範囲ではこのレイヤを有効にする」と宣言するだけで済む点です。分岐の条件がメソッドごとに散らばりません。
ContextPy3で動かすレイヤ活性化の例
PythonでCOPを試せるライブラリに、ハッソ・プラットナー研究所のContextPy 1.1(2008年)をPython 3向けに移植したContextPy3 1.0(PyPI、MITライセンス)があります。通知の送り方を「深夜帯」「海外ローミング中」という2つの状況で変える例を、Python 3.9.6とContextPy3 1.0で実行しました。送信や予約は文字列で模しただけで、実際の通知処理は行いません。
python3 -m venv venv
./venv/bin/pip install ContextPy3==1.0
./venv/bin/python cop_demo.py
import threading
from contextpy3 import Layer, active_layer, around, base, proceed
quiet_hours = Layer("quiet_hours") # 深夜帯
roaming = Layer("roaming") # 海外ローミング中
class Notifier:
@base
def send(self, msg):
return f"push+画像: {msg}"
@around(quiet_hours)
def send(self, msg):
return f"翌朝7時に延期 ({proceed(msg)})"
@around(roaming)
def send(self, msg):
return proceed(msg).replace("push+画像", "テキストのみ")
n = Notifier()
print("1:", n.send("在庫が入荷"))
with active_layer(quiet_hours):
print("2:", n.send("在庫が入荷"))
with active_layer(roaming):
print("3:", n.send("在庫が入荷"))
print("4:", n.send("在庫が入荷"))
print("5:", n.send("在庫が入荷"))
def other():
print("6 別スレッド:", n.send("在庫が入荷"))
with active_layer(quiet_hours):
t = threading.Thread(target=other); t.start(); t.join()
実行結果は次のとおりです。
1: push+画像: 在庫が入荷
2: 翌朝7時に延期 (push+画像: 在庫が入荷)
3: 翌朝7時に延期 (テキストのみ: 在庫が入荷)
4: 翌朝7時に延期 (push+画像: 在庫が入荷)
5: push+画像: 在庫が入荷
6 別スレッド: push+画像: 在庫が入荷
@baseが状況に依存しない元の振る舞い、@around(レイヤ)がそのレイヤを有効にしたときだけ差し込まれる部分メソッドです。proceed()で内側の振る舞いを呼び出します。with active_layer(...)のブロックを抜けるとレイヤは自動で無効に戻り(4と5)、sendの呼び出し側には分岐が1つもありません。
ContextPy3で確かめた合成の順序とスレッドの境界
レイヤを重ねたときの順序と、有効範囲の広がり方は、使う前に確かめておくべき挙動です。どちらもCOP一般の規則ではなく、ContextPy3 1.0で確認した結果です。
- 後から有効にしたレイヤが外側に来る:レイヤAの中でBを有効にすると
B(A(base))、逆の順ではA(B(base))になりました。上の例の3は、外側のroamingがquiet_hoursの結果の文字列を置き換えています。差分同士が干渉する処理を重ねるときは、有効にする順番が結果を左右します。 - 有効範囲はスレッドをまたがない:6のとおり、深夜帯レイヤを有効にしたブロックの中で起動した別スレッドには、レイヤが引き継がれませんでした。ContextPy3は有効なレイヤの一覧をスレッドローカルで持っているためです。ワーカースレッドやタスクキューに処理を渡す設計では、渡し先でもう一度レイヤを有効にする必要があります。
COPの主な実装と保守の状況
COPは言語ごとに拡張として実装されてきました。主な実装の入手先と、配布物やリポジトリの日付は次のとおりです(2026年10月3日に確認)。採用する場合は、使うPythonやLispの版で動くかを各自で確かめる必要があります。
| 実装 | 言語 | 入手先 | 配布版・更新情報 |
|---|---|---|---|
| ContextL | Common Lisp | Quicklisp | 配布識別子 20241012-git |
| ContextPy | Python 2 | PyPI 1.1 | 公開 2008年11月24日 |
| ContextPy3 | Python 2・3 | PyPI 1.0 | 公開 2018年2月21日 |
| ContextJS | JavaScript | GitHub(LivelyKernel) | 最終push 2016年11月18日 |
ContextLはCLOS(Common Lispのオブジェクトシステム)の拡張で、2005年にCOPを明示的に支える最初の言語拡張として発表されました。ほかにSqueak(Smalltalk)向けのContextS、Java向けにハッソ・プラットナー研究所が配布するJCop(v0.4)があります。2008年の原典が例に使ったJava向けのContextJは当時まだ構想段階で、付録にライブラリとして部分実装したContextJ*が載っています。原典は、ContextLが商用アプリケーションで使われるWebフレームワークLisp on Linesに組み込まれていると紹介しています。
if文・Strategy・AOP・機能フラグとの違い
状況によって振る舞いを変える手段は、COP以外にもいくつもあります。どれを選ぶかは、切り替えの単位と、切り替えが及ぶ範囲で決まります。
| 手段 | 切り替えの単位 | 切り替える場所 | 及ぶ範囲 |
|---|---|---|---|
| if文・switch | 分岐1つ | 各メソッドの中 | その分岐だけ |
| Strategyパターン | オブジェクト1つ | 生成時・注入時 | そのオブジェクト |
| AOP | 横断的な処理 | ポイントカット定義 | 条件に合う結合点 |
| 機能フラグ | 機能1つ | 設定・配信サービス | フラグを読む箇所 |
| COP | レイヤ(差分の束) | 呼び出し側のブロック | そのブロックの実行中 |
Strategyパターンは差し替える相手を1つのオブジェクトとして渡すため、複数のクラスにまたがる差分を一括で切り替えるのは苦手です(Strategyパターンとは?PHP・Java・TypeScriptの実装例と使いどころ)。AOPはログや権限確認などの横断的な関心事を1か所にまとめる技術で、AspectJではcflowやifのポイントカットにより実行時の状況も条件にできます(AOP(アスペクト指向プログラミング)とは)。COPの原典もこの点を認めたうえで、違いを2つ挙げています。AOPは横断的な関心事をコード上で1か所にまとめることを目指すのに対し、COPはレイヤの定義を各クラスの中に置いてもよいこと。そして、AOPのポイントカットはプログラムが公開している結合点でしか発火しないのに対し、COPはソースコードの任意の場所でレイヤを有効・無効にできることです。機能フラグは本番で機能を段階的に公開する運用の道具で、切り替えの判断を設定側に置きます(フィーチャートグル(機能フラグ)とは)。
AI時代のコンテキスト駆動開発:Conductorの成果物と手順
AIエージェントの文脈で「コンテキスト駆動開発」という名前を広めたのは、Googleが2025年12月17日にGoogle for Developersのブログで公開したGemini CLI拡張のConductor(Apache-2.0)です。v0.4.1のREADMEは、チャットのログに頼らず、仕様と計画をコードと同じリポジトリのMarkdownに残すことで「リポジトリを、エージェントの作業をすべて方向づける唯一の情報源に変える」と説明しています。作業の流れは「Context → Spec & Plan → Implement」の順です。
Conductorが作るファイルとコマンド
公開版のv0.4.1(2026年3月11日)では、次の6つのコマンドを使います。
| コマンド | 役割 | 作る・更新するファイル |
|---|---|---|
| /conductor:setup | プロジェクトに1回だけ実行 | product.md など5ファイル |
| /conductor:newTrack | 機能追加・修正の単位を開始 | tracks/<id>/spec.md・plan.md |
| /conductor:implement | plan.mdのタスクを実行 | plan.md・tracks.md |
| /conductor:status | 進捗の表示 | tracks.mdを読む |
| /conductor:revert | トラック・フェーズ単位で戻す | gitの履歴 |
| /conductor:review | 規約と計画に照らして確認 | plan.mdなどを読む |
setupで作る5ファイルは、conductor/product.md(利用者・目的・主要機能)、product-guidelines.md(文章の調子やブランド表現)、tech-stack.md(言語・データベース・フレームワーク)、workflow.md(TDDの有無やコミットの方針)、tracks.md(作業単位の一覧)で、言語ごとのコーディング規約を置くconductor/code_styleguides/ディレクトリも作られます。この記事で説明しているv0.4.1を入れるなら、--refでタグを固定します。READMEの例は版を固定せず--auto-updateを付けており、その場合は更新のたびに手順が変わりえます。
gemini extensions install https://github.com/gemini-cli-extensions/conductor --ref conductor-v0.4.1
新しい機能に着手するときは/conductor:newTrack "設定画面にダークモードの切り替えを追加"のように説明を付けて実行し、生成されたspec.mdとplan.mdを人が確認してから/conductor:implementに進みます。コードを書かせる前に計画を承認する手順が、仕組みとして組み込まれている点が要です。
公開版v0.4.1とmainブランチの違い
Conductorは2026年7月14日のコミット「upgrade Conductor to agent plugin」で、Gemini CLI専用の拡張から、AntigravityやClaude Codeでも動くエージェント用プラグインへ作り替えられました。Googleは7月16日に「Evolving Spec-Driven Development: Conductor Now Supports Antigravity」としてブログで発表しています。2026年10月時点のmainのREADMEは自らを「Spec-Driven Development(仕様駆動開発)」を実現するプラグインと説明しており、「Context-Driven Development」という呼び方は消えています。2026年10月3日時点の最新リリースはv0.4.1のままです。
| 項目 | v0.4.1(2026年3月) | main(2026年7月以降) |
|---|---|---|
| 位置づけ | Gemini CLI拡張 | エージェント用プラグイン |
| 掲げる名前 | Context-Driven Development | Spec-Driven Development |
| 対応環境 | Gemini CLI | Antigravity・Claude Code |
| 初期設定のコマンド | /conductor:setup | /conductor:conductor-setup |
| トラック開始 | /conductor:newTrack | /conductor:conductor-new-track |
解説記事や動画で見たコマンド名が手元で通らない場合は、どちらの版を入れたかを確かめてください。名前が仕様駆動開発へ寄せられたことからもわかるとおり、コンテキスト駆動開発は独立した手法というより、仕様駆動開発の「前提情報を先に固める」部分に付いた呼び名と捉えるのが実態に近いでしょう。
コンテキスト駆動開発の4原則
Claude Code向けのプラグイン集wshobson/agentsに収録された「Conductor – Context-Driven Development Plugin for Claude Code」は、スキルの解説で原則を次の4つに整理しています。
- Context precedes code:何をどう作るかを、実装の前に定義する。
- Living documentation:前提の文書はプロジェクトと一緒に更新し続ける。
- Single source of truth:情報の種類ごとに正となる置き場所を1つに決める。
- AI alignment:同じ前提を渡せば、AIの振る舞いもそろう。
同じスキルは運用の注意として「文書の変更はコードの変更と一緒にコミットする」「コードレビューで前提の文書も確認する」「意思決定や振る舞いに影響しない項目は書かない」なども挙げています。前提の文書が古いままだと、AIはそこに書かれた廃止済みのAPIや変更前の要件に沿ってコードを書きます。文書を更新する手順をworkflow.mdとレビューに組み込めるかが、この方式の成否を分けます。
仕様駆動開発・コンテキストエンジニアリング・AGENTS.mdとの関係
AIエージェントに前提を渡す考え方には、近い名前がいくつも並んでいます。守備範囲の違いは次のとおりです。
- 仕様駆動開発(SDD):要件を仕様書に起こし、計画とタスクに分解してから実装させる進め方です。GitHubのSpec Kit(2026年10月時点の最新はv1.1.0)などのツールがあります。コンテキスト駆動開発は、このうち製品・技術スタック・手順の前提を常設のファイルにする部分を強調した呼び方です。定義は仕様駆動開発(SDD/Spec-Driven Development)とは?、ツールの選び分けは仕様駆動開発ツール比較で扱っています。
- コンテキストエンジニアリング:1回ごとの推論でモデルに何を、どの順で、どれだけ渡すかを設計する技術です。開発手順ではなく、プロンプトや検索結果、ツールの出力を組み立てる側の話です(コンテキストエンジニアリングとは?)。
- AGENTS.md・CLAUDE.md:エージェントがリポジトリで最初に読む指示ファイルです。AGENTS.mdはLinux Foundation傘下のAgentic AI Foundationが管理する形式で、公式サイトは6万以上のオープンソースプロジェクトで使われているとしています。ディレクトリごとに置くと、作業中のファイルに最も近いものが優先されます。コンテキスト駆動開発の前提ファイルを、エージェントに確実に読ませる入口として使えます(copilot-instructions.mdとは?AGENTS.mdとの違い、Claude Codeの使い方|CLAUDE.md設定)。
コンテキスト指向開発が向かない場面と失敗パターン
どちらの系統も、導入して得をする条件ははっきりしています。次のような場面では採用を見送るべきです。
- 分岐が2〜3か所しかないのにCOPを入れる:レイヤの合成順やスレッド境界という新しい落とし穴を持ち込むわりに、得るものがありません。この記事で動かしたContextPy3はPython 3.9.6でしか確認しておらず、PyPIの最新も2018年の1.0のため、新しいPythonでの動作は自分で確かめることになります。
- 別スレッドへレイヤが自動で引き継がれる前提でContextPy3を使う:ContextPy3では、レイヤを有効にしたブロックの中で起動したスレッドにレイヤが引き継がれませんでした。ワーカースレッドに処理を渡す設計では、状況を引数などで明示的に渡すか、渡し先でレイヤを有効にし直す必要があります。
- 1人・1回限りの小さな修正にConductorの手順を通す:setupで5ファイル、トラックごとにspec.mdとplan.mdを作り、承認を挟みます。READMEも、前提・仕様・計画を読み込むためトークン消費が増えると注意しています。数行の修正なら、AGENTS.mdに規約を書いておくだけで足ります。
- 前提ファイルを作って更新しない:tech-stack.mdに古いライブラリの版が残れば、エージェントはその版でコードを書きます。前提ファイルの変更をコードの変更と同じプルリクエストで扱う決まりが無いチームでは、時間とともに逆効果になります。
よくある質問
コンテキスト駆動開発とは何ですか?
AIエージェントに渡す前提(製品の目的、技術スタック、作業手順、機能ごとの仕様と計画)をMarkdownファイルにしてリポジトリで管理し、毎回同じ前提で作業させる開発の進め方です。GoogleのConductorが2025年12月にこの名前で公開しました。
Context-oriented Programming(COP)とは何ですか?
状況ごとの振る舞いの差分を「レイヤ」にまとめ、実行時にレイヤを有効・無効にして振る舞いを切り替えるプログラミング技術です。2008年にHirschfeld・Costanza・NierstraszがJournal of Object Technologyで論文化しました。
プログラミングでいう「コンテキスト」とは何ですか?
処理が置かれている状況や、処理に付随して受け渡される情報を指します。COPでは時間帯や端末のような実行時の状況、Go言語のcontextではキャンセルや期限の情報、AIエージェントではモデルに渡す前提情報を指し、分野によって中身が違います。
コンテキスト駆動開発と仕様駆動開発は何が違いますか?
重なる部分が大きく、明確な境界はありません。仕様駆動開発は機能ごとの仕様から計画・タスクへ落とす流れ全体を指し、コンテキスト駆動開発はそのうち製品・技術スタック・手順という常設の前提を強調した呼び方です。Conductor自身も2026年7月にmainの説明を仕様駆動開発へ改めています。
COPは実務で使われていますか?
2008年の原典は、ContextLが商用アプリケーションで使われるWebフレームワークLisp on Linesに組み込まれていると紹介しています。一方で、Python版のContextPy3はPyPIの最新が2018年の1.0、JavaScript版のContextJSはGitHubの最終pushが2016年で、依存先として選ぶ前には動作確認が要ります。同じ目的は、Strategyパターン、AOP、機能フラグでも実現できます。