はじめに

この蚘事は Google ADK によるマルチ゚ヌゞェント瀟内ITヘルプデスク構築 をテヌマにした党4回シリヌズの第4回です。

回 テヌマ
第1回 Gemini CLI で゚ヌゞェントを動かしおみる
第2回 ADK でマルチ゚ヌゞェントを構築し Google Cloud にデプロむする
第3回 ADK マルチ゚ヌゞェントを BigQuery ず連携させる
第4回本蚘事 Gen AI evaluation service で ADK マルチ゚ヌゞェントの応答品質を枬る

第3回たでで、ルヌタヌ・FAQ怜玢・゚スカレヌションの3぀の゚ヌゞェントが BigQuery ず連携しお動き、inquiry_log に問い合わせ履歎が残る状態が完成したした。
手元で動かす限り「だいたいうたくいっおいる」ようには芋えたす。
しかし、その状態ではどの皋床うたくいっおいるのか、どこから改善すべきなのかを説明できたせん。
本蚘事では Gen AI Evaluation Service を䜿い、マルチ゚ヌゞェントの応答品質を3぀の軞で定量評䟡したす。
最終的に「耇数の指暙で実枬倀を持぀ → 改善の優先順䜍が぀けられる」状態に持っおいきたす。

䜕を評䟡するか3軞

瀟内ITヘルプデスクのマルチ゚ヌゞェントで「品質」ず蚀ったずき、実は1぀の数字には収たりたせん。
最䜎限、次の3぀の軞で別々に枬る必芁がありたす。

軞 枬りたいこず 評䟡方法
① ルヌティング粟床 ルヌタヌが正しい゚ヌゞェントに振り分けたか Exact Match期埅倀 vs 実枬倀
② 回答品質 FAQ怜玢゚ヌゞェントの回答が質問に察しお適切か Gen AI Evaluation の coherence銖尟䞀貫性、暙準メトリクス+ faq_groundednessFAQ に基づくか、カスタムメトリクス+ expected_faq_id の Exact Match自前チェック
③ フォヌルバック刀定 解決䞍胜な質問を正しく゚スカレヌションできたか Exact Matchexpected_resolved vs 実枬倀

3軞に分けるのは、それぞれスコアが萜ちた時の改善ポむントが違う からです。
ルヌティング粟床が䜎ければ instruction やルヌタヌ偎の刀断ロゞックを盎す。回答品質が䜎ければ FAQ の䞭身か instruction を盎す。
フォヌルバック刀定が甘ければ「迷ったら゚スカレ」のような instruction を匷化する。䞀぀の総合スコアにたずめおしたうず、どこを盎せばいいかが芋えなくなりたす。

評䟡デヌタセットの蚭蚈

12 ケヌスの内蚳

なお、今回の12ケヌスは評䟡蚭蚈を説明するための小芏暡な怜蚌デヌタセットです。
そのため、ここでの粟床は本番党䜓の品質を統蚈的に保蚌するものではなく、改善ポむントを発芋するためのベヌスラむンずしお扱いたす。

皮別 ケヌス数 備考
第3回の inquiry_log ず同じケヌス 4 シリヌズ間の連続性
゚ッゞケヌス誀刀定誘発・冗長/極短質問・新カテゎリ等 8 ゚ヌゞェントが取りこがしやすいケヌスを炙り出す

なお、これ以降登堎する NW-001 AC-001 などの FAQ ID は、第3回で䜜った faq_master テヌブルの䞻キヌです。カテゎリ略号NWネットワヌクACアカりントHWハヌドりェアSW゜フトりェア 連番の圢匏で、䟋えば AC-001 は「パスワヌドを忘れたアカりントがロックされた」ずいう FAQ を指したす。

゚ッゞケヌスは意図的に「゚ヌゞェントが取りこがしそうな問い合わせ」を混ぜおいたす。䟋えば

  • C05: 「新しくアカりントを䜜成しおほしい」 — 「アカりント」ずいうキヌワヌドに匕っかかっお AC-001パスワヌド忘れに誀マッチしないか
  • C07: 「プリンタヌのトナヌが切れたので泚文したい」 — 「プリンタヌ」キヌワヌドで HW-001印刷できないに誀マッチしないか実態は調達系
  • C08: 「瀟内 Wi-Fi が突然党員繋がらなくなった」 — Wi-Fi キヌワヌドで NW-002 に行くか、それずも「党員」ずいう圱響範囲で党瀟障害扱いするか
  • C10: 冗長な前眮きで質問するケヌス — 長文の䞭から意図を拟えるか
  • C11: 「Teams のチャンネル䜜成暩限がほしい」 — Teams キヌワヌドで SW-002 に行くか、それずも暩限管理ずしお別案件扱いするか

eval_dataset.jsonl のスキヌマ

各ケヌスに ground truth期埅倀 ず contextFAQ 解決時の参照テキスト を持たせたす。

{
"case_id": "C01",
"question": "VPN に接続しようずするず認蚌゚ラヌが出お接続できたせん",
"expected_category": "ネットワヌク系",
"expected_resolved": true,
"expected_faq_id": "NW-001",
"expected_routed_to": "faq_searcher_agent",
"context": "以䞋の手順を詊しおください。\n1. Caps Lock がオフになっおいるか確認する\n..."
}

context は察応する FAQ の answer を入れたす。埌述するカスタム評䟡メトリクスfaq_groundednessが「応答がこの context に基づいおいるか」を刀定するための reference になりたす。゚スカレヌション期埅ケヌスexpected_resolved=falseでは context は空にしおおきたす。

評䟡メトリクスの遞び方

暙準メトリクスを詊したら groundedness が党件 0 だった

最初は Gen AI Evaluation の暙準メトリクスだけで枈たせようず考えたした。

from vertexai.evaluation import EvalTask, MetricPromptTemplateExamples

metrics = [
MetricPromptTemplateExamples.Pointwise.COHERENCE,
MetricPromptTemplateExamples.Pointwise.GROUNDEDNESS,
]

ずころが実行しおみるず groundedness が党件 0.0、std も 0.0 ずいう䞍自然な結果に。原因を調べるず、暙準 GROUNDEDNESS のプロンプトには次のように曞かれおいたした。

groundedness, which measures the ability to provide or reference information included only in the user prompt.
本蚘事執筆時点で確認した暙準 GROUNDEDNESS のテンプレヌトでは、user prompt に含たれる情報を参照できおいるかを評䟡する蚭蚈になっおいたした。
そのため、今回のように FAQ の answer を context ずしお別途持たせる構成では、期埅した評䟡になりたせんでした。
ナヌザヌの質問は短く「VPN に接続できたせん」、応答は長いFAQ の手順なので、暙準メトリクスでは 0 になったず考えられたす。

カスタム pointwise メトリクスを曞く

そこで PointwiseMetric でカスタムメトリクスを定矩したした。

from vertexai.evaluation import PointwiseMetric, PointwiseMetricPromptTemplate

faq_groundedness = PointwiseMetric(
metric="faq_groundedness",
metric_prompt_template=PointwiseMetricPromptTemplate(
criteria={
"groundedness": (
"The response should be based only on the FAQ context provided. "
"It must not introduce facts, URLs, system names, or contact "
"information that are absent from the FAQ context."
),
},
rating_rubric={
"5": "Fully grounded in the FAQ context. No extra information.",
"3": "Mostly grounded but introduces minor reformulations or extras.",
"1": "Largely diverges from the FAQ context or fabricates information.",
},
input_variables=["question", "context", "response"],
),
)

input_variables で question / context / response の 3 ぀を指定するず、評䟡デヌタセット偎に同名の列を甚意するだけで、自動的にプロンプトに差し蟌たれたす。
最終的に䜿うメトリクスは coherence暙準+ faq_groundednessカスタム+ expected_faq_id の Exact Match の 3 皮類になりたした。

評䟡実装のキモ

評䟡察象の゚ヌゞェントは、再デプロむの時間ずコストを節玄するため、ADK の Runner を䜿っお手元のプロセスから実行したす。Runner は ADK の実行ルヌプを担うコンポヌネントで、run_async() により゚ヌゞェント実行䞭のむベントを逐次取埗できたす。
今回はこのむベントから、最終応答だけでなく function_call / function_response の情報も拟いたす。

評䟡に必芁なメタデヌタを ADK むベントから取り出す

゚ヌゞェントの応答テキストだけでは、ルヌティング先・カテゎリ・FAQ ID ずいったメタデヌタが取れたせん。これらは ADK のむベントから盎接拟いたす。

async for event in runner.run_async(...):
for part in event.content.parts:
# 1. log_inquiry の匕数からカテゎリ・routed_to・resolved を取埗
if part.function_call and part.function_call.name == "log_inquiry":
log_args = dict(part.function_call.args)
# 2. search_faq の戻り倀から FAQ ID を抜出
if part.function_response and part.function_response.name == "search_faq":
m = re.search(r"FAQ ID:\s*([A-Z]+-\d+)", str(part.function_response.response))
if m:
faq_id = m.group(1)
# 3. 応答テキストは重耇排陀し぀぀蓄積
if part.text and part.text not in seen_texts:
response_text_parts.append(part.text)
seen_texts.add(part.text)

最埌の重耇排陀がポむントです。ADK の芪゚ヌゞェントず子゚ヌゞェントは同じ text を流すこずがあるため、玠盎に蓄積するず応答が2回繰り返されたたた評䟡に流れおしたいたす。

Gen AI Evaluation の呌び出し

eval_df = pd.DataFrame([
{
"prompt": r["question"], # COHERENCE 甹
"question": r["question"], # カスタム faq_groundedness 甹
"response": r["actual_response"],
"context": r["context"],
}
for r in faq_results
])

eval_task = EvalTask(
dataset=eval_df,
metrics=[
MetricPromptTemplateExamples.Pointwise.COHERENCE,
faq_groundedness,
],
)
result = eval_task.evaluate()

返っおくる result.summary_metrics に集玄スコア、result.metrics_table に各ケヌスのスコアが入りたす。12ケヌス分の評䟡は玄 20 秒で完了したした。

実行結果

数字サマリ

========== 評䟡結果サマリ ==========
総ケヌス数: 12
① ルヌティング粟床: 83.3%10/12
② FAQ ID 䞀臎率: 80.0%FAQ解決が期埅される5ケヌス䞭 4件䞀臎
③ フォヌルバック刀定粟床: 83.3%10/12

【回答品質】
coherence/mean: 4.0
coherence/std: 1.41
faq_groundedness/mean: 2.6
faq_groundedness/std: 0.89

coherence銖尟䞀貫性は 4.0 ず高めである䞀方、faq_groundedness は 5段階評䟡の䞭では䜎めでした。
応答を読みやすく敎えるこずは LLM の埗意分野ですが、FAQ ぞの忠実さには改善䜙地があるこずが分かりたす。

誀刀定したケヌスの分析

ルヌティングずフォヌルバックで誀刀定が出たのは2件、どちらも゚ッゞケヌスでした。

C08: 「瀟内 Wi-Fi が突然党員繋がらなくなりたした」

期埅 実枬
ルヌティング ゚スカレヌション党瀟障害 FAQ怜玢NW-002 で回答

LLM は「Wi-Fi」ずいうキヌワヌドに反応しお NW-002 をヒットさせ、そのたた回答しおしたいたした。「党員繋がらない圱響範囲が倧きい゚スカレすべき」ずいう文脈刀断が、キヌワヌドマッチに負けた圢です。
第3回で耇合語キヌワヌドを採甚しおマッチング粟床は䞊げたのですが、圱響範囲のような業務文脈は別軞で芋る必芁がありたす。

C10: 「い぀もお䞖話になっおおりたす。実は先週から パスワヌドを忘れお どうすればリセットできるのでしょうか」

期埅 実枬
ルヌティング FAQ怜玢AC-001 ゚スカレヌション

冗長な前眮きで質問したケヌス。本来は AC-001パスワヌドリセットでヒットすべきずころが、゚スカレに流れたした。「業務が滞っおしたっおいたす」のような前眮きが゚スカレを誘発した可胜性がありたす。

䞀芋誀刀定だが実は賢い動䜜C07・C11

逆に興味深かったのが C07プリンタヌトナヌ泚文ず C11Teams のチャンネル䜜成暩限です。どちらも search_faq がキヌワヌドで䞀旊 FAQ をヒットさせたものの、゚ヌゞェントが内容を芋お「これは印刷できない問題ではなく泚文の話」「これは暩限管理で別案件」ず刀断し、゚スカレに振り盎したした。
怜玢が匱マッチになっおも、最終応答で LLM が正しく振り分ける挙動が確認できた良い䟋です。

coherence 4.0 / faq_groundedness 2.6 の差は䜕か

coherence は文の論理的な流れを芋るので圱響を受けにくい䞀方、faq_groundedness は「FAQ context にない衚珟が混じったか」を厳しく芋たす。
応答に「以䞋の手順をお詊しください」のような䞁寧語ぞの蚀い換えが入る、【FAQ ID: NW-001】 のような ID 衚蚘が応答の本文䞭に混入する、ずいった芁因で枛点される構造です。
2.6 ずいうスコアは完党な逞脱ハルシネヌションではなく、自然な応答生成の結果ずしお䞀定の蚀い換えが入った状態ず読めたす。
「FAQ を䞀字䞀句コピペさせる」のが目的なら instruction を厳栌化、「読みやすさを優先しお蚀い換えを蚱容する」なら珟状維持、ず方針刀断の材料になりたす。

結果の解釈ず改善の方向性

ここでの数倀は、前述の12ケヌスに察するベヌスラむンずしお解釈したす。

指暙 実枬倀 解釈
ルヌティング粟床 83.3% 単玔な誀マッチC08ず前眮き混入C10が原因 instruction で「圱響範囲・前眮き・本題の切り分け」を匷化する䜙地
FAQ ID 䞀臎率 80% FAQ解決期埅ケヌスのうち C10 が誀ルヌティング ルヌティング粟床の改善ずほが連動
フォヌルバック刀定 83.3% C08 で「Wi-Fi 党員」を芋逃した 圱響範囲党員/党瀟を刀定するルヌルを instruction に远加する䜙地
coherence 4.0 応答は読みやすい 維持
faq_groundedness 2.6 応答に FAQ context 倖の情報が混入FAQ ID 衚蚘・補足衚珟など search_faq の戻り倀から FAQ ID 衚蚘を陀く、たたは応答敎圢ルヌルを instruction で厳栌化

特に「圱響範囲党員/党瀟はキヌワヌドマッチでは捉えられない」ずいう気付きが、評䟡を通しお数字付きで蚀えるようになりたした。

たずめずシリヌズ党䜓に぀いお

第4回で達成したのは、マルチ゚ヌゞェントの品質を数字で継続的に確認するための土台を䜜ったこず です。

  • ルヌティング・回答・フォヌルバックの3軞で別々に枬るこずで、改善の優先順䜍が぀けられるようになった
  • Gen AI Evaluation の暙準メトリクスcoherenceずカスタムメトリクスfaq_groundednessを組み合わせれば、業務芁件にぎったり寄せた評䟡ができる
  • 評䟡結果を芋るこずで、第3回たでは芋えおいなかった匱点圱響範囲の刀定・冗長な前眮きが炙り出された

シリヌズ党䜓の総括

å…š4回を通しお、瀟内ITヘルプデスクのマルチ゚ヌゞェントを段階的に䜜っおきたした。
最初はファむル1枚から始め、次にコヌドベヌスのマルチ゚ヌゞェントぞ広げ、その埌 BigQuery ず連携しおデヌタ駆動の構成にし、最埌に評䟡で品質を数倀化するずいう流れです。

回 できるようになったこず
第1回 Gemini CLI に GEMINI.md 1枚枡せば゚ヌゞェントが動く
第2回 ADK でルヌタヌ・FAQ怜玢・゚スカレの3゚ヌゞェント構成を䜜っお Google Cloud にデプロむ
第3回 FAQ をテヌブル化し、問い合わせ履歎を inquiry_log に貯めるデヌタ基盀を敎備
第4回 評䟡デヌタセットず Gen AI Evaluation で品質を3軞で数倀化

ここたで来るず、実運甚に乗せるための準備が䞀通り揃った状態です。
次のステップは、評䟡結果に基づく instruction の改善・FAQ の拡充・実ナヌザヌからの満足床フィヌドバックsatisfaction_score カラムの収集を回す改善サむクルになりたす。

LLM ベヌスの゚ヌゞェントは「動かす」たでは比范的すぐ行けたすが、「品質を担保し続ける」フェヌズに入った瞬間に評䟡デヌタセットず評䟡指暙が必須になりたす。
たた、今回は12ケヌスの小芏暡な評䟡でしたが、実運甚に近づけるには、実際のinquiry_logから倱敗䟋・曖昧な問い合わせ・頻出カテゎリを定期的に抜出し、評䟡デヌタセットぞ远加しおいく必芁がありたす。
評䟡デヌタセット自䜓を育おるこずで、instruction 改善や FAQ 拡充の効果を継続的に比范できたす。
本シリヌズがそのスタヌト地点ずしお参考になれば幞いです。

参考リンク