OpenCodeでマルチエージェントを動かす方法(プラグインなし)
OpenCodeには複数エージェントを利用した開発フローを構築する機能があります。本記事では、実装・テスト・検証をエージェントごとに分担し、Pythonコード生成を行う例を紹介します。DS4(DeepSeek V4 Flash)やQwen系モデルを使った実行例も掲載しています。
OpenCodeのエージェント機能について
OpenCodeでは、組み込みエージェントをカスタマイズしたり、独自のエージェントを作成する機能をデフォルトで備えています。
今回は、この機能を使って独自エージェントを作成し、マルチエージェントで処理を行ってみます。
ここでは、仕様に基づいて関数を実装、テスト、検証する処理をエージェントを使って行う例を示します。用意するエージェントは以下の4つです。
- Orchestrator
指示を受け取って全体を動かすエージェントです - Coder
仕様に従ってコードを生成するエージェントです - Tester
テストコードを作成するエージェントです - Verifier
コードを検証し、テストを実行するエージェントです
今回は、Orchestrator がタスクを管理し、Coder・Tester・Verifier に処理を委譲する、比較的オーソドックスなマルチエージェント構成を試しています。
なお、モデルはローカルLLMのds4(DeepSeek v4 Flash)またはLMStudio(Qwen 3.6)を使いました。なお、マルチエージェントで実行する際は、ある程度賢いモデルでなければうまく連携できないみたいなので注意が必要です。
「マルチエージェントってどうやって設定すればいいの?」と悩んでいる方の参考になればと思います。
opencode.jsonを利用する方法
設定ファイルの作成
1つ目は、エージェントの設定をopencode.jsonに記述する方法です。例えば以下のようなファイルを準備します。
.
├── AGENTS.md
└── opencode.json
AGENTS.md
エージェントへの指示です。他のエージェントを利用して作業することを指示しています。
## @orchestrator
# 開発ワークフロー標準手順書 (SOP)
あなたはプロジェクトの進行を管理する Orchestrator です。
ユーザーから提供された仕様書(タスク)に対して、必ず以下のマルチエージェント・ワークフローを自律的に実行してください。
## 設計フェーズ
1. ユーザーから関数の設計指示を受け取り、関数の設計仕様書を作成してください。また、ユーザーの指示に実装に必要な情報が不足している場合は対話により不足部分を埋めてください。
2. 十分な情報が得られたら、設計仕様書とTo-Doリストを作成し、To-Doリストに従って、開発フェーズと検証フェーズを繰り返してください。
## 開発フェーズ
1. **実装依頼**:
`coder` サブエージェントに仕様書を渡し、「仕様を満たすコードを `src/` 配下に実装すること」を指示してください。
2. **テスト作成依頼**:
`coder` の作業完了後、`tester` サブエージェントに仕様書を渡し、「`pytest` を用いたテストコードを `tests/` 配下に作成すること」を指示してください。
## 検証フェーズ
3. **テスト実行とレビュー**:
コードとテストが揃ったら、`verifier` サブエージェントに `pytest` を実行させ、コードとテストの妥当性を検証させてください。
4. **修正ループ**:
`verifier` の検証でエラーや仕様漏れが発覚した場合、エラー内容に応じて `coder` または `tester` に修正を指示してください。
5. **完了条件**:
すべてのテストがパスし、`verifier` が承認するまで、この修正ループを回し続けてください。完了したら最終報告を行ってください。opencode.json
LLMモデルの設定と、agent設定です。
LLMモデルは、小さいモデルだとうまくエージェント切り替えができないので、今回はDS4(DeepSeek V4 Flash)を利用しています。

agentの設定では、orchestrator, coder, tester, verifierの4つのエージェントを設定しています。マルチエージェントを行う場合は、それぞれが得意なモデルを設定した方が良いのですが、ローカルでDS4を動かすとメモリが厳しかったので、全て同じモデルにしています。
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"ds4": {
"name": "ds4.c (local)",
"npm": "@ai-sdk/openai-compatible",
"options": {
"baseURL": "http://127.0.0.1:8000/v1",
"apiKey": "dsv4-local"
},
"models": {
"deepseek-v4-flash": {
"name": "DeepSeek V4 Flash (ds4.c local)",
"limit": {
"context": 100000,
"output": 384000
}
}
}
}
},
"agent": {
"orchestrator": {
"mode": "primary",
"description": "全体の進行管理とサブエージェントへのタスク委譲を行うリーダー",
"model": "ds4/deepseek-v4-flash",
"permission": {
"delegate": "allow",
"bash": "allow",
"file_edit": "allow"
}
},
"coder": {
"mode": "subagent",
"description": "Pythonコードの実装を担当するプログラマー",
"model": "ds4/deepseek-v4-flash"
},
"tester": {
"mode": "subagent",
"description": "pytestを用いたテストコード作成を担当するQA",
"model": "ds4/deepseek-v4-flash"
},
"verifier": {
"mode": "subagent",
"description": "コードとテストをレビューし、テストを実行するテスター",
"model": "ds4/deepseek-v4-flash"
}
}
}実行テスト
以下のコマンドでopencodeを起動します。
opencode
tabキーを何回か押して、Orchestratorに切り替えます。

とりあえず、ここでは以下の指示を実行してみました。
nまでの素数を列挙する関数primesをpythonで作成して
すると、まず設計仕様の作成が始まります。本当は、ここで、nの範囲を聞いて来るかと思ったのですが、特にそのようなことはなく、以下のToDoリストを作成しました。

あとは、これに従ってcoder, tester, verifierを起動し、今回は簡単だったので修正ループはなしで終了しました。

実行後のフォルダは以下の通りです。
.
├── AGENTS.md
├── opencode.json
├── src
│ ├── __pycache__
│ │ └── primes.cpython-312.pyc
│ └── primes.py
└── tests
├── __pycache__
│ └── test_primes.cpython-312-pytest-8.3.4.pyc
└── test_primes.py
作成されたファイルは以下の通りです。
def primes(n: int) -> list:
if n < 2:
return []
sieve = [True] * (n + 1)
sieve[0] = sieve[1] = False
for i in range(2, int(n ** 0.5) + 1):
if sieve[i]:
step = i
start = i * i
sieve[start : n + 1 : step] = [False] * ((n - start) // step + 1)
return [i for i, is_prime in enumerate(sieve) if is_prime]from src.primes import primes
def test_n_less_than_2_returns_empty_list():
assert primes(0) == []
assert primes(1) == []
def test_n_equals_2():
assert primes(2) == [2]
def test_n_equals_10():
assert primes(10) == [2, 3, 5, 7]
def test_n_equals_30():
known = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
assert primes(30) == known
def test_n_equals_100_all_primes_start_from_2():
result = primes(100)
assert result[0] == 2
for i in range(1, len(result)):
assert result[i] > result[i - 1]
def test_n_equals_1_edge_case():
assert primes(1) == []
def test_result_is_ascending():
result = primes(1000)
for i in range(1, len(result)):
assert result[i] > result[i - 1]
def test_n_equals_1000_performance():
import time
start = time.time()
result = primes(1000)
elapsed = time.time() - start
assert elapsed < 2.0
assert len(result) > 0自動生成されたテスト項目を見ると、少し荒い気もしますので、ここは指示を追加した方がよいかもしれません。
**テストすべき項目**:
1. n < 2 のとき空リストが返ること (n=0, n=1)
2. n=2 のとき [2] が返ること
3. 小さなn (n=10 → [2,3,5,7])
4. n=30 の正しさ (既知の素数リストと比較)
5. 中程度のn (n=100) で全ての素数が2から始まる昇順であること
6. n=1 (エッジケース)
7. 返り値が昇順であること
8. 大きな n (n=1000) での動作確認 (時間がかかりすぎないこと)
作成されたテストコードをpython -m pytest tests/ -vで実行すると以下のようになりテストがパスできていることも確認できました。


マルチエージェントで動かすと、DS4のプロンプト処理高速化用SSDキャッシュの不整合が発生し、キャッシュ再構築が走ることがありました。そのため、一時的に処理がかなり重くなるケースがありました。設定次第かもしれませんが、DS4をローカルで利用する場合は、マルチエージェントよりシングルエージェント構成の方が高速な場合もありそうです。
.opencode/agents を使う方法
初期設定
設定ファイルの作成
1つ目は、エージェントの設定を.opencode/agentsに記述する方法です。以下のようなフォルダ構成でファイルを準備します。
.
├── AGENTS.md
└── opencode.json
├── .opencode
└── agents
├── coder.md
├── orchestrator.md
├── tester.md
└── verifier.md
opencode.json
今回は、LMStudioを使って見ます。モデルはqwen/qwen3.6-35b-a3bです。このモデルは小さいながらもかなり優秀です。
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"lms": {
"name": "LM Studio (local)",
"npm": "@ai-sdk/openai-compatible",
"options": {
"baseURL": "http://127.0.0.1:1234/v1",
"apiKey": ""
},
"models": {
"qwen/qwen3.6-35b-a3b": {
"name": "qwen3.6-35b-a3b",
"limit": {
"context": 100000,
"output": 100000
}
}
}
}
}
}AGENTS.md
# AGENTS.md
# 開発ワークフロー標準手順書 (SOP)
あなたはプロジェクトの進行を管理する Orchestrator です。
ユーザーから提供された仕様書(タスク)に対して、必ず以下のマルチエージェント・ワークフローを自律的に実行してください。
## 設計フェーズ
1. ユーザーから関数の設計指示を受け取り、関数の設計仕様書を作成してください。また、ユーザーの指示に実装に必要な情報が不足している場合は対話により不足部分を埋めてください。
2. 十分な情報が得られたら、設計仕様書とTo-Doリストを作成し、To-Doリストに従って、開発フェーズと検証フェーズを繰り返してください。
## 開発フェーズ
1. **実装依頼**:
`coder` サブエージェントに仕様書を渡し、「仕様を満たすコードを `src/` 配下に実装すること」を指示してください。
2. **テスト作成依頼**:
`coder` の作業完了後、`tester` サブエージェントに仕様書を渡し、「`pytest` を用いたテストコードを `tests/` 配下に作成すること」を指示してください。
## 検証フェーズ
3. **テスト実行とレビュー**:
コードとテストが揃ったら、`verifier` サブエージェントに `pytest` を実行させ、コードとテストの妥当性を検証させてください。
4. **修正ループ**:
`verifier` の検証でエラーや仕様漏れが発覚した場合、エラー内容に応じて `coder` または `tester` に修正を指示してください。
5. **完了条件**:
すべてのテストがパスし、`verifier` が承認するまで、この修正ループを回し続けてください。完了したら最終報告を行ってください。.opencode/agents/orchestrator.md
---
description: 全体の進行管理とサブエージェントへのタスク委譲を行うリーダー
mode: primary
model: lms/qwen/qwen3.6-35b-a3b
temperature: 0.1
tools:
write: true
edit: false
bash: true
question: true
---
あなたはPython開発チームの進行を管理するプライマリエージェント(リーダー)です。
自身でコードを書くことはせず、必ず以下のサブエージェントにタスクを委譲(Delegate)して進行してください。
- `@coder`: Python言語でのプロダクションコード実装を依頼する
- `@tester`: `pytest` を用いたテストコード作成を依頼する
- `@verifier`: ビルド、テストの実行、およびコードレビューを依頼する
ユーザーから渡された手順書と仕様書に従ってチームを動かし、タスクを完遂してください。.opencode/agents/coder.md
---
description: コードの実装を担当するプログラマー
mode: subagent
model: lms/qwen/qwen3.6-35b-a3b
temperature: 0.1
tools:
write: true
edit: true
bash: true
---
あなたは優秀なGo言語(Golang)エンジニアです。
Orchestratorから渡された仕様書に基づき、要件を完全に満たす実装コードを作成してください。
【ルール】
1. テストコードは書かないこと(Testerの仕事です)。
2. 指定がない限り`.py` ファイルとして保存すること。
3. Pythonの標準的な命名規則や、エラーハンドリングのベストプラクティスに従うこと。
4. 実装が完了したら、速やかにOrchestratorに完了報告を行うこと。.opencode/agents/tester.md
---
description: コードの実装を担当するプログラマー
mode: subagent
model: lms/qwen/qwen3.6-35b-a3b
temperature: 0.1
tools:
write: true
edit: true
bash: true
---
あなたはPythonに精通した品質保証(QA)エンジニアです。
仕様書に基づき、正常系・異常系・境界値を網羅したテストコードを作成してください。
【ルール】
1. 外部ライブラリは使わず、`pytest` パッケージを使用すること。
2. Pytestを用いて、複数のテストケースを簡潔かつ網羅的に記述すること。
3. テストファイル名は必ず対象コードのファイル名に `_test.py` を付けたものにし、対象コードと同じディレクトリに保存すること。
4. コードの実装完了を待たず、仕様書を正としてテストを設計・実装すること。.opencode/agents/verifier.md
---
description: コードとテストをレビューし、テストを実行するテスター
mode: subagent
model: lms/qwen/qwen3.6-35b-a3b
temperature: 0.1
tools:
write: true
edit: false
bash: true
---
あなたは厳格なPythonのコードレビュアーであり、CI/CDパイプラインの管理者です。
【ルール】
1. コードとテストが揃ったら、ターミナルで以下のコマンドを実行し、静的解析とテストを行うこと。
2. テストが失敗した場合、または `pytest` などで警告が出た場合は、原因を特定してOrchestratorに報告すること。
3. 自身ではコードを直接修正せず、Orchestratorまたは各担当エージェントに対して修正指示だけを出すこと。
4. すべてのチェックをパスし、仕様を満たしていると確認できた場合のみ承認(Approve)を出すこと。実行テスト
以下のコマンドでopencodeを起動します。
opencode
tabキーを何回か押して、Orchestratorに切り替えます。

とりあえず、ここでは以下の指示を実行してみました。
nまでの素数を列挙する関数primesを作成して
LMStudioの画面を見ると頻繁に処理が行われていることが確認できます。ちなみに、DS4より軽いモデルなので、コーディング完了までの時間も短かったです。

実行時のログです(一部省略)
nまでの素数列挙関数primes作成
Session ID: ses_1c216049affeJlnDs1ir2mfCih
Created: 5/19/2026, 10:46:44 AM
Updated: 5/19/2026, 10:55:18 AM
User
nまでの素数を列挙する関数primesを作成して
Assistant (Orchestrator · qwen3.6-35b-a3b · 30.4s)
Thinking:
ユーザーは n までの素数を列挙する関数 primes を作成したいと言っています。これは比較的シンプルなタスクですが、AGENTS.md に従ってマルチエージェント・ワークフローを実行する必要があります。
まず設計フェーズとして:
- 関数の設計仕様書を作成
- 必要な情報が不足していないか確認
関数の仕様:
- 関数名:
primes - 引数: n(整数)
- 戻り値: 2 から n までの素数のリスト
これは明確なリクエストなので、追加質問は不要でしょう。設計仕様書とTo-Doリストを作成して、タスクを進めます。
実装アプローチ:
- エラトステネスの篩(ふるい)を使用するのが効率的
- src/primes.py に実装
- tests/test_primes.py にテスト
まず設計仕様書を作成し、To-Doリストを作ってサブエージェントにタスクを委譲していきます。
設計フェーズに入ります。まず関数の設計仕様書を作成します。
設計仕様書
関数名: primes
| 項目 | 内容 |
|---|---|
| 引数 | n: int — 上限値(含む) |
| 戻り値 | list[int] — 2以上n以下の素数のリスト(昇順) |
| アルゴリズム | エラトステネスの篩(ふるい) |
| 特殊ケース | n < 2 の場合は空リスト [] を返す |
使用例
primes(10) # [2, 3, 5, 7]
primes(2) # [2]
primes(1) # []
primes(0) # []
primes(-5) # []
To-Doリストを作成し、タスクを進めていきます。
:
(途中省略)
:
Thinking:
検証フェーズが完了しました。すべてのテストがパスし、コードレビューも承認されました。タスクを完了として報告します。
完了報告
タスクが完了しました。以下に結果をまとめます。
実装ファイル
src/primes.py — エラトステネスの篩で n 以下の素数を列挙する関数を実装
| 項目 | 内容 |
|---|---|
| 関数名 | primes(n: int) -> List[int] |
| アルゴリズム | エラトステネスの篩 |
| 戻り値 | 2以上 n 以下の素数を昇順に並べたリスト(n < 2 の場合は []) |
テストファイル
tests/test_primes.py — 31件のテストケースを作成(3テストクラス)
| テストクラス | ケース数 | 内容 |
|---|---|---|
TestPrimesNormal | 11 | 正常系: 代表的な値、型チェック、ソート順、重複なし、合成数不含 |
TestPrimesEdgeCases | 9 | 境界値・異常系: n < 2、合成数、大規模値 |
TestPrimesParametrized | 11 | n=2〜30 の全数データドリブンテスト |
テスト実行結果
31 passed in 0.02s
すべてのテストがパスし、@verifier によりコードレビューも Approve(承認) されました。修正は不要です。
上記のように、エージェントを呼びながら実装が完了しました。

実行する度に結果が異なる(プログラムはちゃんと生成されるが、テスターが失敗したり、いろいろ発生する)ので、この通りになるかは不明です。
まとめ
OpenCodeを使って、マルチエージェントの動作を確認してみました。「OpenCodeでマルチエージェントを試したい」という人の参考になれば幸いです。
エージェントごとに役割を分けながら開発を進めるのは面白いのですが、実際にはモデル性能への依存も大きく、ローカルLLMではキャッシュ再構築などで重くなることもありました。個人的には現状では小規模なコード生成向けかなという印象でした。
