はじめに
OpenCode + Ollama の記事の最終回です。今回はaider同様、実際にコード生成させた結果をまとめます。
- インストール編(第 1 回)
- オプション編(第 2 回)
- 実践編(今回)
aider の実践編と同じ条件(課題とモデル)とすることで、ツールの違いによる差を比較します。
対象者
- OpenCode + Ollama を入れたけど、実際どの程度使えるのか知りたい人
- aider との違いを具体的に知りたい人
- ローカル LLM でのコード生成の限界を理解したい人
環境
| 項目 | スペック |
|---|---|
| OS | WSL2 Ubuntu |
| CPU | Intel Core i7-4790 @ 3.60GHz |
| メモリ | 8GB(うちスワップ 2GB) |
| GPU | なし(CPU 推論のみ) |
| モデル | qwen2.5-coder:7b(4.7GB) |
| OpenCode | v1.17.9 |
やったこと
お題
aider の実践編と同じお題です。
「CSV ファイルを読み込んで、縦と横に合計と平均を追加して出力する Python スクリプトを作成して」という指示を OpenCode に出しました。
仕様書(Spec.md)を用意する
aider の実践編と同じ Spec.md を使います。
# 仕様: CSV集計スクリプト
## 概要
CSVファイルを読み込み、縦横の合計と平均を追加して出力するPythonスクリプト
## 入力
- 引数: CSVファイルのパス
- 1行目: ヘッダー行(文字列)
- 2行目以降: 数値データ(カンマ区切り)
## 出力
- CSV形式で標準出力
- 各行の右側に「合計」「平均」列を追加
- 最下部に各列の「合計」行と「平均」行を追加
## 出力例
A,B,C,合計,平均
1,2,3,6,2.00
4,5,6,15,5.00
合計,5,7,9,21,7.00
平均,2.50,3.50,4.50,10.50,3.50
## 制約
- 言語: Python
- 外部ライブラリは使わない(標準ライブラリのみ)
- 平均は小数点以下2桁
## コーディング規約
- インデント: スペース4つ
- 変数名: スネークケース(file_path)
- 関数名: スネークケース(calc_sum)
- コメントは日本語で記載
実行コマンド
-f オプションで Spec.md を添付し、非対話モードで実行しました。
opencode run -m ollama/qwen2.5-coder:7b -f Spec.md -- "添付したSpec.mdの仕様通りにcsv_summary.pyとsample.csvを作成して"
生成結果
トークン数
| 項目 | 値 |
|---|---|
| 入力トークン | 4,095 |
| 出力トークン | 288 |
結果: ファイルは生成されなかった
OpenCode のツール(write)が実行されず、ツール呼び出しの JSON がテキストとしてそのまま出力されました。
{
"name": "write",
"arguments": {
"content": "import csv\ndef generate_csv_report(input_file, output_file):\n ...",
"filePath": "/path/to/csv_summary.py"
}
}
実際のファイルシステムにはファイルが作られていません。
生成されたコードの内容
テキストとして出力された JSON の中にコードは含まれていましたが、内容にも問題がありました。
| # | 問題 | 内容 |
|---|---|---|
| 1 | ツールが実行されない | write ツールの JSON がテキストとして出力され、ファイルが作成されない |
| 2 | 仕様の制約違反 | 「標準ライブラリのみ」なのに pandas を import している |
| 3 | ロジックの不一致 | 縦横の合計・平均ではなく、1 列の合計だけを計算している |
| 4 | ファイルパスがプレースホルダー |
filePath が /path/to/csv_summary.py のまま |
| 5 | 複数回のやり直し | 5 回の「Follow up」を出力するが、どれも仕様を満たさない |
なぜこうなったのか
OpenCode は ツール呼び出し(Function Calling) 方式でファイルの読み書きを行います。モデルが所定の形式でツールを呼び出すと、OpenCode がそれを検知して実際のファイル操作を実行します。
しかし qwen2.5-coder:7b は、ツール呼び出しの形式を正しく生成できず、JSON をただのテキストとして出力してしまいました。OpenCode はこれをツール呼び出しと認識できないため、ファイルは作成されません。
aider ではなぜ動いたのか
aider は Edit Format 方式を採用しています。モデルにファイルの全内容(whole)や差分(diff)をテキストとして出力させ、aider 側がそれをパースしてファイルに書き込みます。
| 比較項目 | OpenCode | aider |
|---|---|---|
| ファイル編集方式 | ツール呼び出し(Function Calling) | Edit Format(whole / diff) |
| モデルに求める能力 | ツール呼び出し形式の正確な生成 | コードのテキスト出力 |
| 7B モデルとの相性 | ツール形式を正しく生成できず失敗 | テキスト出力なので動作する |
これが 同じモデルなのに aider では動いて OpenCode では動かなかった 根本的な原因です。
aider の実践結果との比較
同じお題・同じモデルでの比較です。
| 比較項目 | OpenCode | aider |
|---|---|---|
| ファイル生成 | 失敗(ツール実行されず) | 成功(2 ファイル生成) |
| コード品質 | 仕様無視(pandas 使用、ロジック不一致) | 骨格は正しいがバグ 4 つ |
| 仕様の理解 | 合計・平均の概念すら反映されず | 縦横の合計・平均は理解 |
| 出力トークン | 288 | 319 |
| そのまま動くか | 動かない(ファイルが存在しない) | 動くがバグあり |
OpenCode + ローカル LLM の使いどころ
今回の結果から、OpenCode + 7B モデルの組み合わせには明確な限界があることが分かりました。
OpenCode が力を発揮する場面
- 商用 API モデル(Claude、GPT 等)との組み合わせ — ツール呼び出しを正確に生成できるモデルであれば、bash 実行やファイル検索などの高度な機能が活きる
- MCP 拡張との連携 — 外部ツールとの統合は aider にない強み
ローカル 7B モデルで使うなら
- aider の方が向いている — Edit Format 方式はテキスト出力だけで済むため、小さなモデルでも動作する
- OpenCode でローカル LLM を使う場合は、ツール呼び出しに対応した大きめのモデル(32B 以上)が必要になる可能性がある
まとめ
| 項目 | 内容 |
|---|---|
| テスト内容 | aider 実践編と同じ CSV 集計スクリプトを OpenCode + qwen2.5-coder:7b で生成 |
| 結果 | ファイル生成に失敗。ツール呼び出しがテキスト出力された |
| 原因 | 7B モデルが OpenCode のツール呼び出し形式を正しく生成できなかった |
| aider との違い | aider は Edit Format 方式のため同じモデルでも動作した |
| 教訓 | OpenCode は商用 API モデル向き。ローカル 7B モデルなら aider が現実的 |
ツールの設計思想の違いが、ローカル LLM との相性に直結するという結果でした。OpenCode は高性能モデル前提の設計、aider は小さなモデルでも動くように工夫されている、という棲み分けが見えてきます。