Claude Codeに古いLangChain記法を書かせない──CLAUDE.md + llms.txt で最新コードを強制する方法

はじめに

LangChainはv0.1→v1.0と短期間で大きく変化し、Web上には旧記法のサンプルが大量に残っている。Claude Codeがそれらを学習しているためLLMChainや旧State定義を生成しやすい。2025年3月28日に公式のllms.txtとMCPDocサーバーがリリースされた。CLAUDE.mdと組み合わせると、最初から最新記法のコードが生成される。


Claude CodeがLangChainで生成しやすい古いパターンを正す

`LLMChain`→LCEL pipe記法

JS版LLMChainはv1.0で@langchain/classicに移管され、メインパッケージから削除された。


// ❌ LLMChain(@langchain/classicに移管済み)
const chain = new LLMChain({ prompt: chatPrompt, llm: model });
const result = await chain.call({ role: "アシスタント", text: "こんにちは" });

// ✅ LCEL pipe記法(v1.0標準)
const chain = prompt.pipe(model).pipe(new StringOutputParser());
const result = await chain.invoke({ role: "アシスタント", text: "こんにちは" });

chain.call()は旧記法。chain.invoke()を使う。

LangGraph StateのInterface→Annotation


// ❌ TypeScript interfaceによるState定義(旧API)
interface AgentState { messages: BaseMessage[]; next: string; }
const graph = new StateGraph<AgentState>({ channels: {} });

// ✅ Annotation.Root(現在の推奨)
import { StateGraph, Annotation, MessagesAnnotation } from "@langchain/langgraph";

const graph = new StateGraph(MessagesAnnotation); // メッセージのみ

// カスタムフィールドがある場合
const State = Annotation.Root({ ...MessagesAnnotation.spec, nextStep: Annotation<string> });
const graph2 = new StateGraph(State).addNode("agent", fn).compile();

createReactAgentの正しいimportとMemorySaver


// ❌ 旧エージェント初期化
import { initializeAgentExecutorWithOptions } from "langchain/agents";
const executor = await initializeAgentExecutorWithOptions(tools, model, {
  agentType: "chat-conversational-react-description",
});

// ✅ createReactAgent
import { createReactAgent } from "@langchain/langgraph/prebuilt";
import { MemorySaver } from "@langchain/langgraph";

const agent = createReactAgent({
  llm: model, tools: [searchTool],
  checkpointSaver: new MemorySaver(),
});

ツール呼び出しのみならcreateReactAgent、複数ノード・条件分岐・human-in-the-loopが必要ならStateGraphで構築する。


CLAUDE.mdで制御する完全テンプレート


# LangChain/LangGraph 開発ルール

## パッケージ
- 必須: `@langchain/core`(明示インストール)・`@langchain/anthropic`・`@langchain/langgraph`
- 禁止: `langchain`(旧)・`@langchain/classic`(レガシー専用)

## チェーン構築
- LLMChain / ConversationChain 禁止(v1.0でmainパッケージから削除)
- LCEL pipe記法必須: `prompt.pipe(model).pipe(parser)`
- `chain.call()` 禁止 → `chain.invoke()`

## LangGraph State定義
- TypeScript interface によるState定義禁止
- `Annotation.Root({})` を使う
- メッセージのみ: `new StateGraph(MessagesAnnotation)` ショートカット

## Import パス
- createReactAgent: `@langchain/langgraph/prebuilt`
- MemorySaver: `@langchain/langgraph`
- ツール呼び出しのみ → createReactAgent、複数ノード → StateGraph

PostToolUseフックで型エラーを自動検出する

TypeScriptファイル編集後にtsc --noEmitを実行して古い型定義エラーを検出する。


{
  "hooks": {
    "PostToolUse": [{
      "matcher": "Edit|Write",
      "hooks": [{
        "type": "command",
        "command": "npx tsc --noEmit --skipLibCheck",
        "timeout": 60,
        "block": true
      }]
    }]
  }
}

block: trueで型エラーがあればClaude Codeがその場で修正する。--skipLibCheck@langchain/coreの内部型定義の衝突を無視するために有効だ。


EM視点──llms.txtとMCPDocをチームで標準化する

LangChain公式ブログによるとCLAUDE.md単独はMCPのみより約2.5倍コスト効率が高く精度も良い。CLAUDE.mdをベースに使い、必要に応じてMCPDocで最新ドキュメントを参照すれば十分だ。MCPDocのセットアップはプロジェクトローカル(-s local)に設定する。


claude mcp add-json langgraph-docs \
  '{"type":"stdio","command":"uvx","args":["--from","mcpdoc","mcpdoc","--urls","langgraph:https://langchain-ai.github.io/langgraphjs/llms.txt","LangChainJS:https://docs.langchain.com/llms.txt"]}' \
  -s local

CLAUDE.mdと.claude/settings.jsonはリポジトリにコミットしてチームで共有する。LangChainのマイナーアップデートのたびにCLAUDE.mdの禁止パターンを見直す習慣を作っておく。AIが古い記法を生成し続ける問題を防ぐためだ。


まとめ

Claude CodeがLangChainで踏む地雷はLLMChain・旧interface State定義・createReactAgentの誤importだ。CLAUDE.mdに本記事のテンプレートを追記して今すぐリポジトリにコミットしてほしい。MCPDocを追加すれば、公式llms.txtを参照した最新記法のコードがClaude Codeから直接生成される。

コメント

タイトルとURLをコピーしました