04 人が調査する
否定的なユーザーシグナルを、フィードバックを正解データと取り違えることなく、人がレビューした診断と修正へと変えます。
出発点
Module 03 は
How many active customers do we have? に対する正典となる Chat trace を 1 つ生み出しました。
そこには意図的な食い違いが含まれています:
| エビデンス | 期待される値 |
|---|---|
| ルートの observation | chat_turn |
sql-execution-success | true |
user-thumbs | false |
メタデータ policyversion | policy-v1 |
その trace の ID/URL と、ワークシートに記録した 2 つの参照カウントを手元に残しておいてください。 Module 03 の、評価を付けなかった curl 診断は使いません。
人による調査が必要な理由
👎 はチームにどこを見るべきかを教えますが、何が失敗したのかは教えません。ユーザーが別のことを 意図していたのかもしれず、リクエストが曖昧なのかもしれず、生成された SQL が不正なのかもしれず、 あるいは 2 つのビジネス定義が食い違っているのかもしれません。否定的なシグナルをすべてそのまま ゴールデンデータセットに昇格させれば、当て推量が正解データに化けてしまいます。
このモジュールでは、レビュアーはまず観測できることを記録し、次に考えられる説明を検証し、 そのあとで初めて診断と修正を記録します。👎 ではなくその レビューされた判断 が、Module 05 に 引き渡される正解データです。
ゴール
Module 03 のルート chat_turn に対して、production-investigation-<session> の annotation タスクを
1 つ完了させます。完了したタスクには、観測、失敗カテゴリ、正確な修正済み SQL、ゴールデン
データセットへの承認、そして本番の由来が含まれていなければなりません。
ステップ 1 — 該当するフィードバックのインシデントを正確に見つける
Langfuse で Tracing を開き、Boolean の score user-thumbs = false でフィルタします。
以下のすべてに一致する trace を開いてください:
- 名前/ルートの observation が
chat_turn; - 質問が
How many active customers do we have?; - Module 03 で記録した勝者の
config_idと trace ID; - メタデータ
policyversion=policy-v1; そして - score が
sql-execution-success=trueとuser-thumbs=false。
serving のソースは policy_version を送出しますが、OpenTelemetry のアダプターがアンダースコアを
取り除くため、Langfuse のメタデータキーは policyversion になります。
annotation を付けるのはルートの chat_turn であり、その子の llm_call generation では
ありません。ルートには、調査に必要なエンドツーエンドの質問と構造化された出力 — SQL、列、行、
エラー、outcome — が含まれています。子にはモデルのトランスクリプトと生成された SQL しかなく、
正典となるフィードバックのインシデントではありません。
ステップ 2 — レビュー用の 3 つの score config を作る
このセットアップは意図的に UI だけで行う人によるレビューのステップ です。ワークショップの リポジトリには、この annotation タスクを代わりに作成したり完了させたりするコマンドは 含まれていません。
キューを作る前に、Settings → Scores → Create を開いて次の config を作成します:
| 名前 | データ型 | 許可される値/目的 |
|---|---|---|
observed-issue | TEXT | trace と比較で目に見えるエビデンスだけを記述する。 |
failure-category | CATEGORICAL | stale-business-policy, incorrect-sql, ambiguous-request, not-actionable |
approved-for-golden | BOOLEAN | 修正が検証されてから初めて承認する。 |
名前とハイフンの位置は示されたとおりに正確に使ってください。config を先に作るのが最も安全な 手順です。キューに紐づく score config の ID の集合は、キューが作成された時点で固定される ためです。もし紐づけの集合から config が漏れていた場合は、新しいサフィックスを付けたキューを 作り直します。score config そのものは変更可能です。名前、スキーマ、カテゴリの、サポートされた 編集は監査される score config の更新として行う必要があり、そうした編集はすでに存在する score を 書き換えることはありません。
ステップ 3 — キューを作り、論理的なルートを対象にする
Annotations → Queues → Create を開いて:
production-investigation-<session>という名前を付けます。<session>は短くて一意な ワークショップ識別子に置き換えます。- ステップ 2 の 3 つの score config すべてを紐づけます。
- キューを作成します。
- Module 03 の trace に戻り、そのルートの
chat_turnobservation を選択し、Annotate ドロップダウンを開いて、このキューを選びます。 - 新しいタスクを開き、その対象が
llm_callではなくchat_turnであることを確認します。
キューは、作成後に紐づく score config の ID を変更できません。作り直すのは、その紐づけの集合が 間違っているときだけにしてください。すでに紐づいている config に対するサポートされた編集には、 監査される score config の更新を使います。
ステップ 4 — 観測できることをオープンコーディングする
Module 03 は仕込みのセットアップを意図的に開示していました。この調査では、その事前のワークショップ
知識をいったん括弧に入れて、未知のインシデントに対してレビュアーが取るであろうワークフローを
練習してください。原因を名指しする前に、質問、生成された SQL、返ってきたカウント、
モデル/プロンプト、そして 2 つの score を調べます。observed-issue にはエビデンスのみのメモを
入れます。たとえば:
The answer returned a count and its SQL executed. The observed count differs from the
second reference count recorded in Module 03. The generated query uses a 90-day
customer signup window, and the trace metadata reports policy-v1.この書き方はまだ、モデル、SQL エンジン、ユーザー、ポリシーのいずれに責任があるとも主張して いません。この切り分けが、エビデンスを確認する前に仕込まれた診断がレビューに持ち込まれるのを 防ぎます。
ステップ 5 — trace のエビデンスをすべて調べる
ルートの chat_turn のまま、次を確認します:
- メタデータが
policyversion=policy-v1; - 生成された SQL が
v_customersと 90 日のsignup_dateウィンドウを使っている; - 構造化された結果に Module 03 で観測した trace のカウントが含まれている;
- 運用 score が Boolean の
sql-execution-success=true; そして - ユーザーのシグナルが Boolean の
user-thumbs=false。
生成された SQL は、リリースが与えた policy-v1 の指示と整合しています。実行成功の score も、
意図的に狭められたその範囲の中では正しいものです。この時点では、どちらの事実も、デプロイされた
そのポリシーが現在の統制された定義と一致するかどうかを立証していません。
ステップ 6 — 2 つのポリシー定義を並べて検証する
ClickHouse_Demos/workshops/agent_arena から、同じ環境で読み取り専用の定義を両方実行します:
source .env
.venv/bin/python - <<'PY'
from arena.config import load_config
from agents.chclient import ROClickHouseClient
queries = {
"policy-v1": """SELECT count() FROM v_customers
WHERE signup_date >= today() - INTERVAL 90 DAY""",
"policy-v2": """SELECT uniqExact(customer_id) FROM v_orders
WHERE order_ts >= now() - INTERVAL 30 DAY
AND status NOT IN ('cancelled', 'returned')""",
}
client = ROClickHouseClient(load_config().clickhouse)
for version, sql in queries.items():
result = client.query(sql)
print(f"{version}: {result.rows[0][0]}")
PY2 つのカウントはワークシートの値と一致し、かつ互いに異なっていなければなりません。これで、
デプロイされたビジネス定義が古びていると診断するのに十分なエビデンスが揃いました。trace は
policy-v1 を掲げており、その SQL はそのポリシーに従っており、検証した現在のクエリは
policy-v2 を実装しています。
ステップ 7 — annotation、修正、承認、完了
annotation タスクに戻り、次を記録します:
| フィールド | 値 |
|---|---|
observed-issue | エビデンス優先のメモを残したまま、検証したポリシー比較を追記する。 |
failure-category | stale-business-policy |
| Corrected Output | 下記の正確な SQL |
approved-for-golden | true |
Corrected Output を plain-text モード に切り替え、この生の SQL をそのまま入力します:
SELECT uniqExact(customer_id) FROM v_orders
WHERE order_ts >= now() - INTERVAL 30 DAY
AND status NOT IN ('cancelled', 'returned')Langfuse はこの修正を記録します。SQL を実行はしません。承認の前に、ステップ 6 の読み取り専用 ClickHouse クライアントがまさにそのテキストを正常に実行できていなければなりません。修正を 編集した場合は、そのテキストを同じクライアントで再実行してください。そのうえで Complete (あるいは Complete + next)を選びます。壊れていたり、実行できなかったり、検証されていない 修正を、ゴールデンな正解データとして承認してはいけません。
ステップ 8 — Module 05 のための由来を記録する
これらの値をワークシートに写します。ID はワークショップのプロジェクト内に留めてください:
| 由来のフィールド | 記録する値 |
|---|---|
source | production-feedback |
source_trace_id | 正典となる Module 03 の Chat trace ID |
failure_category | stale-business-policy |
source_policy_version | policy-v1 |
annotation_id | 取得できる場合、完了した annotation タスクの ID |
| レビュー済みの修正 | 上記の現在のポリシーの SQL そのまま |
source_trace_id、failure_category、source_policy_version は、本番由来のゴールデンレコードに
必須です。annotation_id はランタイム上は任意ですが、UI がそれを見せている場合は記録して
おくと、判断が監査可能なまま残ります。
完了したかどうかの確認
user-thumbs=falseを持つ Module 03 の Chat trace 1 件を調査した。- annotation の対象がルートの
chat_turnであり、子のllm_callではない。 - キューの名前が
production-investigation-<session>で、正しい型の 3 つの score config を すべて含んでいる。 observed-issueが診断より前に振る舞いを記録している。- 古いポリシーと現在のポリシーの SQL を並べて実行し、カウントが異なることを確認した。
- 完了したタスクが
stale-business-policy、正確な修正済み SQL、approved-for-golden=trueを 記録している。 - 生きた trace ID やプロジェクト URL を公開せずに、ワークシートが Module 05 のための本番の由来を 保持している。
- 👎 が人によるレビューの優先度を上げるが、それ自体が正解データにはならない理由を説明できる。
レビュー済みの修正を昇格させ、ポリシーのバージョンを比較し、同じ種類の失敗をオンラインで 防ぐために、Module 05 — ループを閉じる に進んでください。