Command A ReasoningをAiderのテスト生成で評価
Command A ReasoningでGoのユニットテストを生成し、Aiderの編集形式違反とtoken limitを記録しました。LLM導入で確認すべきテスト設計と編集ループの安定性を整理します。
テスト生成の結果
command-a-reasoning-08-2025-nvfp4をAiderで使い、knowledge/service.goのユニットテスト生成を評価しました。テスト観点と雛形は作れましたが、edit formatの違反が起き、最後はtoken limitで停止しました。
- テスト観点の整理と雛形生成に使えました。
- 長いセッションではAiderのedit formatを守れない場面がありました。
- 大きな編集を一度に任せるより、観点整理と下書きを分担させる使い方が合いそうです。
LLMを開発作業へ導入する際は、reasoningの質と差分編集ループの安定性を分けて評価する必要があります。
評価対象
既存ファイルを読み、編集対象を限定し、Aiderの編集プロトコルに沿って差分を返せるかを確認しました。モデルはcommand-a-reasoning-08-2025です。
対象はinternal/domain/knowledge/service.goとinternal/domain/knowledge/service_test.goです。Chat、Retrieve、Compose、PublishPipeline、SubscribePipelineのテストを整備するタスクでした。
LLM・Vectorstore・Pipeline呼び出し、streamとnon-streamの分岐、goroutineとchannelを含みます。設計理解とコード生成を確認できる題材です。
テスト観点の整理
最初にservice_test.goで検証する契約を整理しました。
Chatでは次の観点を挙げています。
- stream 応答では
Answer.Stream != nil、Answer.Textは空、Sourcesは空 - non-stream 応答では
Answer.Text、Usage、検索結果Sourcesを確認 LLMService.ChatCompletionが 1 回呼ばれる- model ごとの backend 切り替え前提を意識している
- 非 stream 時のみ
Vectorstore.Searchが呼ばれる - LLM error をそのまま返す
Retrieve、Compose、PublishPipeline、SubscribePipeline、helper関数も整理していました。呼び出し境界とサービスの契約を分けて見られています。
モデルは未検証項目も挙げました。
ChatResultの異常形Choices空やText空RetrieveのQuery空やTopK=0PublishPipelineの JSON marshal 失敗SubscribePipelineのctx cancel
初案の不足を残件として示せる点は、設計レビューで役立ちます。
service_test.goの生成
続いてknowledge/service_test.goを生成しました。knowledge_testパッケージにテストを置き、依存サービスをtestify/mockでモック化する案です。
モックの構成です。
type mockLLMService struct { mock.Mock }
type mockVectorstoreService struct { mock.Mock }
type mockPipelineService struct { mock.Mock }
生成したテスト関数は次のとおりです。
func TestChat(t *testing.T)
func TestRetrieve(t *testing.T)
func TestCompose(t *testing.T)
func TestPublishPipeline(t *testing.T)
func TestSubscribePipelineWithCorrelation(t *testing.T)
func TestSelectAnswerFromResult(t *testing.T)
func TestExtractUserMessage(t *testing.T)
主要機能のテスト雛形は揃いました。
TestChatの初案はstream、non-stream、llm errorの基本3ケースでした。修正版では、non-stream時にuser messageでVectorstore検索し、Sourcesへ反映する検証を追加しました。
vsSvc.On("Search", mock.Anything, "user message", 3).
Return([]vectorstore.Hit{{ID: "hit1"}}, nil)
回答文の確認に加え、non-stream時だけretrievalを実行する契約も検証しています。
edit formatの違反
Aiderが適用できる出力形式を、セッション中に守れなくなりました。
ログに残ったメッセージです。
The LLM did not conform to the edit format.
No filename provided before ```` in file listing
提案コードはあっても、ファイルへ適用する形式が崩れたため、差分をそのまま取り込めず再試行になりました。
Aiderで使うモデルには、コードの内容と適用可能な差分の両方が必要です。
修正版で追加した検証
後の提案ではencoding/jsonを追加し、SubscribePipelineWithCorrelationを独立したテストにしました。SelectAnswerFromResultのno choicesと、ExtractUserMessageの空入力も追加しています。
PublishPipelineではmock.MatchedByでpipeline.TriggerRequestの内容を検証していました。
mock.MatchedBy(func(req pipeline.TriggerRequest) bool {
return req.Name == "test-pipeline" &&
string(req.Payload) == string(expectedPayload) &&
req.CorrelationID == "corr-1"
})
依存サービスへ渡す要求の確認まで進められています。
token limitで停止
画面ログ、過去のコード、修正版、説明、ファイル一覧、commit message生成が積み重なり、次のエラーで止まりました。
Model openai/Firworks/command-a-reasoning-08-2025-nvfp4 has hit a token limit!
Input tokens: ~13,597 of 0 -- possibly exhausted context window!
この記録では、初期の提案が使えても、長い編集ループでは出力形式と追従性が落ちました。単発のreasoningとは別に確認すべき点です。
モデルの得意・不得意
強い点
- テスト対象の仕様整理が上手い
- モックを使ったユニットテストの骨組みを作れる
- 改善フィードバックを受けて、2 回目の提案で不足ケースを補える
弱い点
- edit format を守り切れない場面がある
- 長いセッションで出力が冗長化しやすい
- context が膨らむと、適用可能な差分より説明文の比率が上がる
- 最終的に token limit に達して止まる
command-a-reasoning-08-2025のreasoningは使えました。AiderやCodexで長く編集を続ける用途では、プロトコル順守とセッション継続性も評価する必要があります。
次回は小さい単位で依頼する
次回は短いセッションで作業を分けます。
service_test.go全体を一度に依頼せず、次の単位で進める案です。
Chat系だけを追加RetrieveとComposeだけを追加Pipeline系だけを追加- helper 関数だけを追加
読み込むファイルも必要なものに絞ります。今回は同じコードや説明を繰り返し保持したことが、context増大につながりました。
運用で試す項目です。
- 編集対象ファイルを必要最小限に絞る
- 一段落ついたら
/dropで不要ファイルを外す - 履歴が長くなったら
/clearして新しいセッションに切る - モデルには「説明より diff を優先」と強めに要求する
次回の評価項目
評価は2軸で行います。
コード理解とテスト設計の質に加え、edit format準拠率、再説明の量、長い修正ループでの安定性を確認します。今回の課題は後者でした。
残った未検証項目は、短いセッションで個別に確認します。
ChatResultの nil 組み合わせSelectAnswerFromResultの choices 空や text 空PublishPipelineの JSON marshal 失敗SubscribePipelineのctx cancel
