テスト生成の結果

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=0
  • PublishPipeline の 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全体を一度に依頼せず、次の単位で進める案です。

  1. Chat 系だけを追加
  2. Retrieve と Compose だけを追加
  3. Pipeline 系だけを追加
  4. helper 関数だけを追加

読み込むファイルも必要なものに絞ります。今回は同じコードや説明を繰り返し保持したことが、context増大につながりました。

運用で試す項目です。

  • 編集対象ファイルを必要最小限に絞る
  • 一段落ついたら /drop で不要ファイルを外す
  • 履歴が長くなったら /clear して新しいセッションに切る
  • モデルには「説明より diff を優先」と強めに要求する

次回の評価項目

評価は2軸で行います。

コード理解とテスト設計の質に加え、edit format準拠率、再説明の量、長い修正ループでの安定性を確認します。今回の課題は後者でした。

残った未検証項目は、短いセッションで個別に確認します。

  • ChatResult の nil 組み合わせ
  • SelectAnswerFromResult の choices 空や text 空
  • PublishPipeline の JSON marshal 失敗
  • SubscribePipeline の ctx cancel