AIのモデルを使う処理を書いていると、提供元ごとに引数も返り値も違うことに気づきます。乗り換えるたびに呼び出し側を直すことになります。
呼び出し箇所が5か所ある状態で1社増やすと、直に書いていれば5か所すべてに手を入れます。共通の口をはさんでいれば1か所です。
形の違う2社を実際に用意して確かめました。呼び出しが5か所あるとき、直に書けば5か所、共通の口なら1か所です。
LangChainが掲げる共通の口という考え方が、どれだけ効くのかを実際に書いて確かめました。用意したのは引数も返り値も形の違う2社の応答APIです。
2通りの実装は本当に動かしており、返り値がそろうことも確かめています。変更箇所の数のほうは、呼び出し箇所から数え上げたものです。
const providerA = {
name: 'A社',
call: (o) => ({ output: { text: `A: ${o.prompt}`, tokens: o.prompt.length } }),
};
const providerB = {
name: 'B社',
call: (o) => ({ result: [{ content: `B: ${o.input}` }], usage: { total: o.input.length } }),
};
// 共通の口をはさむ。形の違いをここ1か所に閉じ込める
const adapters = {
A社: (p, prompt) => { const r = p.call({ prompt });
return { text: r.output.text, tokens: r.output.tokens }; },
B社: (p, prompt) => { const r = p.call({ input: prompt });
return { text: r.result[0].content, tokens: r.usage.total }; },
};
A社 直に書く: {"text":"A: こんにちは","tokens":5}
共通の口: {"text":"A: こんにちは","tokens":5} 一致: true
B社 直に書く: {"text":"B: こんにちは","tokens":5}
共通の口: {"text":"B: こんにちは","tokens":5} 一致: true
方式 変更する箇所 内訳
直に書く 5か所 問い合わせの分類・議事録の要約・請求書の点検・見積の下書き・日報の整形
共通の口 1か所 adapters に1つ足すだけ
呼び出し箇所 直に書く 共通の口
5か所 5か所 1か所
20か所 20か所 1か所
50か所 50か所 1か所
100か所 100か所 1か所
返り値はどちらの方式でもそろいました。差が出るのは、次の1社を足すときです。
直に書く方式では、output.text なのか result[0].content なのかという判断が、呼び出し箇所ごとに書かれます。5か所あれば5か所に散ります。
共通の口をはさむと、その判断は1か所に閉じ込められます。呼び出し側は { text, tokens } だけを見ればよくなります。
この差は箇所の数に比例します。100か所あれば100か所と1か所です。LangChainも、最小限のコード変更でモデルを切り替えられ、要件が変わってもアプリケーションを持ち運べる状態に保てるとしています。
つなぎ先の数が増えるほど共通化が効く、という構造はMCPの記事でも同じでした。あちらは12本が7本、規模を広げて1000本が70本という数字が出ています。
呼び出し箇所が増えても、共通の口なら触るのは1か所のまま。
Switch models with minimal code changes and keep your application portable as requirements evolve.原文Docs by LangChain「LangChain overview」 この内容の有効期限2027-02-18
提供元ごとに違う呼び方を1つの口にそろえ、そこに機能を足していく枠組みです。実行の面倒は別の層が見ています。
LangChainは、提供元ごとに違うモデルの呼び方を1つの口にそろえる枠組みです。そのうえに、道具の呼び出しや検査といった機能を足していきます。
公式の説明では、提供元をまたいで、対話用のモデルや埋め込みなどに1つの口を使うとされています。モデルだけでなく、周辺の部品も同じ考え方で扱われます。
前の節で書いた adapters のような部分を、あらかじめ用意してあるものだと考えると分かりやすいはずです。
全部入りの道具ではありません。最小限の骨組みから始めて、必要な機能を少しずつ足していく形が案内されています。
足せるものとして挙げられているのは、検査や再試行、振り分け、道具の扱いに関する決まりなどです。検査の置き方はガードレールの記事で扱っています。
名前が並ぶので整理しておきます。LangChainのエージェントはLangGraphの上に作られていると明記されており、状態の持ち回りや再開といった実行の面倒はそちらが見ています。
つまり層が違います。実行の土台の話はLangGraphの記事で扱っています。
使ってみて感じたのは、何をそろえたいのかを先に決めないと、枠組みの形に引きずられるということでした。モデルの呼び出しだけそろえたいのか、道具の扱いまでそろえたいのか。範囲を決めておくと、足す機能を選びやすくなります。
Use one interface for chat models, embeddings, and more across providers.原文Docs by LangChain「LangChain overview」 この内容の有効期限2027-02-18
片方にしかない機能が通しにくくなります。抜け道を書くことになるので、そろえた意味がその分だけ薄れます。
LangChainのような共通の口には代償があります。すべての提供元にある機能しか、素直には通せません。
前の節の実演では、A社だけにある機能を2つ、B社だけにある機能を1つ置きました。合計3件は共通の口の形に収まりません。
こうした機能を使いたい場合、共通の口をすり抜ける書き方をすることになります。すると、その箇所だけ提供元に縛られます。
4番目を避けてください。抜け道が散らばると、そろえた意味がなくなります。前の節の5か所が1か所になるという効果も、抜け道の数だけ目減りします。
呼び出し箇所が1つか2つなら、直に書くほうが速く終わります。共通の口を用意する手間は、最初の1か所では回収できません。
この構造は他の共通化とも同じで、MCPの記事でも小規模では差が出ないという結果が出ています。
全部を共通の口に押し込むと、抜け道が散らばって元に戻る。
LangChain’s agents are built on top of LangGraph.原文Docs by LangChain「LangChain overview」 この内容の有効期限2027-02-18
同じ課題を持つ会社にとって、動いている設定は「作る時間」を買えるということです。ServiceDockは自作のワークフローやテンプレートを出品できるマーケットプレイスです。手数料や出品の流れは出品者向けページにまとまっています。
出品の仕組みを見る