コースApache Doris Hackathon自分のペースで進めるタスク · いつでも開始 · 登録不要

トラック A · タスク A4

エージェントトレース エクスプローラー

AI エージェントが出力する JSON はリリースごとに構造が変わります。VARIANT に保存し、通常の列のようにクエリします。

  • 60~120 分
  • 中級
  • 言語自由 · CLI、ノートブック、Web
  • AI ツールの利用歓迎

困ったときは? 質問はこちら: #dev 参加先: Apache Doris Slack。メンテナーやほかの参加者がサポートします。

1

環境を準備

何を作るか、Doris ならどう簡単になるかを学び、クラスターを起動します。

作成するもの

エージェントの不揃いな JSON も、そのままクエリ。

LLM 呼び出し、ツール呼び出し、エラー、最終回答。それぞれに独自のフィールドがあり、リリースごとに新しいフィールドも増えます。Doris の VARIANT は JSON を型付きの列に自動変換するため、通常の SQL でフィルター、検索、集約できます。スキーマ移行は不要です。

次を対象にしたトレースエクスプローラー: 1,000 件の AI エージェントセッション(約 20,000 イベント):

  • 検索用の セッション一覧 (イベント数、エラー、トークン数、レイテンシを表示)、
  • 検索用の セッションのタイムライン:セッションをクリックすると、エージェントの動作を順に再現、
  • ツールとモデルの統計:p95 レイテンシ、エラー率、トークン使用量、
  • JSON 内の検索:「timeout」を含むツールエラーをすべて検索します。

そして次に答えます: 13:00 にデプロイされたエージェント v2 によって、状況は改善しましたか、それとも悪化しましたか?

概略図作成するもの · ワイヤーフレーム(スクリーンショットではありません)

概略図はコードパネルの上部にあります

Doris で取り組む利点

  • スキーマ定義不要の書き込み時スキーマ処理。 VARIANT は JSON の各パスの型を推論し、よく使うパスを実際の列指向サブカラムとして保存します。そのため、 payload['latency_ms'] は全ドキュメントを解析せず、1 列を読むだけで済みます。

  • 新しいフィールドは自動で現れます。 v2 のイベントが次を追加すると、 cost_usd、次のロードで新しいパスがサブカラムとして現れます。次の操作は不要です: ALTER TABLE.

  • JSON 内を検索。 VARIANT 列の転置インデックスにより、すべてのテキストパスを次で検索できます: MATCH_*.

パネル:テーブル定義のインデックス行

始める前に

  • docker pull apache/doris:all-in-one-4.1.3
  • docker run -d --name doris -p 9030:9030 -p 8030:8030 -p 8040:8040 apache/doris:all-in-one-4.1.3
  • docker exec -it doris mysql -uroot -h127.0.0.1 -P9030
  • curl -LO https://github.com/morningman/demo-env/releases/download/for-hackathon/doris-hackathon-glasgow-2026.zip && unzip doris-hackathon-glasgow-2026.zip && cd doris-hackathon-glasgow-2026
ホスト
127.0.0.1
ポート
9030
ユーザー
rootパスワードなし
データベース
hackathon

データ

hackathon.agent_events :エージェントのイベントごとに 1 行を保存し、イベント本体を VARIANT 列に保持します:

テーブルhackathon.agent_events · sql
CREATE TABLE agent_events (  session_id  VARCHAR(40)  NOT NULL,  ts          DATETIME(3)  NOT NULL,  event_id    BIGINT       NOT NULL,  event_type  VARCHAR(32)  NOT NULL,   -- user_message / llm_call / tool_call / error / final_answer  payload     VARIANT      NOT NULL,  INDEX idx_payload (payload) USING INVERTED PROPERTIES ("parser" = "english"))DUPLICATE KEY(session_id, ts)DISTRIBUTED BY HASH(session_id) BUCKETS 1PROPERTIES ("replication_num" = "1", "storage_format" = "V3");

ペイロード例:構造の違いに注目してください:

ペイロード例json
{"text": "Why did checkout fail at 11:40?", "lang": "en", "agent_version": "v1"}{"model": "model-large", "usage": {"input_tokens": 812, "output_tokens": 96}, "latency_ms": 1430, "agent_version": "v1"}{"tool": "sql_query", "args": {"sql": "SELECT ..."}, "latency_ms": 37, "status": "ok", "agent_version": "v1"}{"tool": "http_get", "args": {"url": "..."}, "latency_ms": 3012, "status": "error", "agent_version": "v1", "error": {"type": "Timeout", "message": "read timeout after 3000 ms calling https://api.internal/orders"}}

13:00 以降に始まるセッションは次を実行します: エージェント v2。ペイロードには次が含まれ、 "agent_version": "v2"、v2 の LLM 呼び出しには次のフラグが追加されます: cache_hit 。マイルストーン 5 では、テーブルにまだ存在しないフィールドを持つイベントをロードします。

パネル → テーブル:テーブル定義の全体

AI を使って作る

AI コーディングエージェントとの共同作業を推奨しています。 Doris 4.x の検索機能と AI 機能は、多くのモデルの学習データより新しいため、SQL を書かせる前に適切な情報を渡してください:

  1. 次の コンテキストプロンプト をエージェントに貼り付けます。

  2. 参照先として次を指定: このページに掲載した参考資料 および AGENTS.md (スターターキット内)。多くのコーディングエージェントはこのファイルを自動で読み込みます。

  3. コードに組み込む前に、すべての SQL 文を実際のクラスターで実行させてください。

  4. さらに、次を接続すると便利です: Doris MCP Server (参照: タスク A2)。エージェント自身でスキーマを確認し、クエリをテストできるようになります。

コンテキストプロンプトエージェントに貼り付け
I'm building an agent trace explorer on Apache Doris 4.1 for a hackathon.Connection: MySQL protocol, 127.0.0.1:9030, user root, empty password, database `hackathon`.Use a plain MySQL driver and raw SQL.Table `agent_events`: session_id, ts DATETIME(3), event_id, event_type(user_message / llm_call / tool_call / error / final_answer), payload VARIANT(inverted index, english parser). Payload shapes differ by event_type. Every payload hasagent_version: "v1" before 13:00, "v2" from 13:00; v2 llm_calls add cache_hit.Doris SQL rules:1. Read JSON paths as payload['a']['b']. CAST to a concrete type before comparing,   sorting or aggregating: CAST(payload['latency_ms'] AS DOUBLE).2. VARIANT cannot be a key, a sort key or a join key.3. Text search inside JSON: payload['error']['message'] MATCH_ANY 'timeout'. Never LIKE.4. Percentiles: percentile_approx(expr, 0.95).5. `SET describe_extend_variant_column = true; DESC agent_events;` lists inferred subcolumns.6. To insert JSON yourself, CAST the text: CAST('{"a": 1}' AS JSON).Build: sessions list, session timeline, tool/model stats, and JSON search.Run every SQL statement against the live cluster first.

AI エージェントが陥りやすい Doris の落とし穴

TrapWhat to do instead
キャストせずに VARIANT のパスを比較するCAST(payload['latency_ms'] AS INT)。VARIANT はキー列や結合列にできません
次に期待すること: DESC による JSON パスの一覧表示実行: SET describe_extend_variant_column = true; を先に実行します。その後、 DESC に推論されたすべてのサブカラムと型が表示されます
次の使用: LIKE '%term%' によるテキスト検索col MATCH_ANY 'a b' (OR)、 MATCH_ALL (AND)、 MATCH_PHRASE 'a b' 。これらは転置インデックスを使います
ORM を使う通常の MySQL ドライバーと生の SQL を推奨します。ORM は Doris がサポートしない文を生成する場合があります
2

実装する

6 マイルストーン、 M0 → M5。パネルは読んでいるステップに追従します。

  1. マイルストーン 010 分

    ロードして調べる

    スターターキットのフォルダー内で実行:

    M0 · ロードbash
    docker exec -i doris mysql -uroot -h127.0.0.1 -P9030 < seed/a4_agent_events.sql

    続いて SQL シェルで実行:

    M0 · 調査sql
    USE hackathon;SET describe_extend_variant_column = true;DESC agent_events;     -- see the subcolumns Doris inferred: payload.tool, payload.usage.input_tokens, ...
    確認ポイント

    ロード結果の表示: 1,000 セッション、20,401 イベント; DESC には約 20 個の payload.* パスが、それぞれ推論された型とともに表示されます。

  2. マイルストーン 115 分

    JSON パスをクエリ

    M1 · JSON パスをクエリsql
    SELECT CAST(payload['tool'] AS STRING) AS tool, COUNT(*) AS callsFROM agent_eventsWHERE event_type = 'tool_call'GROUP BY toolORDER BY calls DESC;
    確認ポイント

    ツールは 5 つあり、 sql_query が最も多く呼び出されています(3,506 回)。

  3. マイルストーン 215 分

    推論されたサブカラムを集約

    M2 · 推論されたサブカラムを集約sql
    SELECT CAST(payload['tool'] AS STRING) AS tool,       COUNT(*) AS calls,       percentile_approx(CAST(payload['latency_ms'] AS DOUBLE), 0.95) AS p95_ms,       SUM(CASE WHEN CAST(payload['status'] AS STRING) = 'error' THEN 1 ELSE 0 END) AS errorsFROM agent_eventsWHERE event_type = 'tool_call'GROUP BY toolORDER BY p95_ms DESC;
    確認ポイント

    python_exec の p95 が最も悪く(約 2.1 秒)、 http_get の失敗が最も多い(425 エラー)。

  4. マイルストーン 310 分

    JSON 内を検索

    M3 · JSON 内を検索sql
    SELECT session_id, ts, CAST(payload['error']['message'] AS STRING) AS error_messageFROM agent_eventsWHERE payload['error']['message'] MATCH_ANY 'timeout'ORDER BY tsLIMIT 20;
    確認ポイント

    合計 398 イベントに timeout が含まれます。時間ごとに集計すると、v2 に関する最初の手掛かりが得られます。

  5. マイルストーン 420 分

    セッションのタイムライン

    M4 · セッションのタイムラインsql
    SELECT ts, event_type,       CAST(payload['tool'] AS STRING)      AS tool,       CAST(payload['status'] AS STRING)    AS status,       CAST(payload['latency_ms'] AS INT)   AS latency_ms,       CAST(payload['text'] AS STRING)      AS textFROM agent_eventsWHERE session_id = 's-0042'ORDER BY ts;

    これらのクエリを使って、セッション一覧 → タイムライン → 統計の UI を作ります。

    確認ポイント

    セッション s-0042 には 25 イベントがあります。質問、LLM とツールの呼び出し(1 回失敗した sql_queryは再試行)、最終回答で構成されています。

  6. マイルストーン 510 分

    スキーマの変化を観察

    M5 · スキーマ変更バッチをロードbash
    docker exec -i doris mysql -uroot -h127.0.0.1 -P9030 < a4/drift_batch.sql   # events with new fields
    M5 · 新しいフィールドをクエリsql
    SELECT CAST(payload['agent_version'] AS STRING) AS version,       COUNT(*) AS llm_calls,       ROUND(SUM(CAST(payload['cost_usd'] AS DOUBLE)), 2) AS cost_usdFROM agent_eventsWHERE event_type = 'llm_call'GROUP BY versionORDER BY version;

    実行: DESC agent_events を再実行すると、新しいパスが表示されます。次の操作は ALTER TABLE 実行していません。

    確認ポイント

    第 3 のバージョンが現れます: v2.1。そのバージョンの LLM 呼び出しだけに次が含まれます: cost_usd、かつ DESC に次が表示されます: payload.cost_usd および payload.retries.

3

完成させる

チェックを済ませ、成果を共有し、バッジを獲得しましょう。

完了条件

チェックリスト

提出してバッジを獲得

参加 → 提出 → バッジを獲得。

  1. 成果物は次の名前のフォルダーにまとめてください: ご自身の GitHub ID。コードと README を含め、README に内容、実行方法、スクリーンショットまたは GIF 1 点、使用した Doris の機能を記載します。

  2. プルリクエストを作成 次の場所に追加してください: morningman/demo-env 配置先: doris-hackathon-glasgow-2026/<your-github-id>/。フォークして push するか、GitHub の次の操作を使ってください: Add file → Upload files。ほかに入力する項目はありません。

  3. 共有する 共有先: #dev 参加先: Apache Doris Slack:プルリクエストまたはリポジトリへのリンクと、スクリーンショットまたは短いデモを共有します。質問、提出、バッジの案内はすべてこちらで行います。

タスクに参加した方全員に次のバッジを贈ります: Apache Doris Contributor バッジ。Doris 本体へのプルリクエストがマージされている必要はありません。締め切りはないので、ご自身のペースで進めてください。チーム参加も可能ですが必須ではありません。全員の GitHub ID を次に記載してください: README.

追加の挑戦

  • 自分のトレースを使う。 ご自身の AI コーディングエージェントのローカルセッションログ(JSONL)をエクスポートし、1 行に 1 つの CAST('…' AS JSON) をロードします。データはローカルの Doris インスタンスに保存されます。

  • Schema Template。 よく使うパスを次で固定します: VARIANT<'latency_ms': INT, 'tool': STRING> (テーブルのコピーで実行)。次の結果と DESC クエリの挙動を比較します。データの投入方法: INSERT … SELECT …, CAST(payload AS JSON):VARIANT はテンプレート付きの VARIANT に直接キャストできません。

  • アシスタントに探索させる。 Doris MCP Server を接続し(タスク A2)、最も問題のあるセッションを探すようアシスタントに依頼します。

  • SQL でエラーを分類 (API キーはご自身で用意): AI_CLASSIFY(CAST(payload['error']['message'] AS STRING), ['timeout', 'auth', 'bad input', 'other'])。参照: LLM SQL 関数.

トラブルシューティングと参考資料

SymptomFix
docker: command not found (macOS)Docker Desktop を起動してください。起動済みなら CLI へのリンクを作成します: sudo ln -s /Applications/Docker.app/Contents/Resources/bin/docker /usr/local/bin/docker
error getting credentials (イメージ取得時)削除する項目: credsStore のフィールドを次から削除: ~/.docker/config.json (ローカル開発環境のみ)
port is already allocated別のプロセス(多くは別の Doris)が 9030、8030、8040 のいずれかを使っています。実行中のコンテナーを確認してください(docker ps)。または別のホストポートを公開します。例: -p 19030:9030。その場合は 19030 に接続してください。
The container name "/doris" is already in use以前に起動したことがあります: docker start doris。最初からやり直すには、 docker rm -f doris (データが削除されます)
コンテナーが終了する、または状態が変わらない: (healthy)確認: docker logs doris。多くはメモリが原因です。Docker Desktop に 6 GB 以上を割り当ててください(Settings → Resources)。Apple Silicon では次を追加しないでください: --platform linux/amd64
permission denied: ./doris.sh解凍ツールによって実行権限が失われています: chmod +x doris.sh、または次を実行: bash doris.sh start
Current database is not set実行: USE hackathon; を先に実行するか、次で接続します: -Dhackathon
score() function requires WHERE clause with MATCH function, ORDER BY and LIMIT次を追加: MATCH_* の述語、 ORDER BY score() DESC および LIMIT、さらに次は score() を式で包まないでください(上記の落とし穴を参照)
10 分以上解決できない場合投稿先: #dev 参加先: Apache Doris Slack

参考資料

VARIANT データ型VARIANT SQL リファレンス全文検索LLM SQL 関数

Apache Doris Hackathon

すべてのタスク

コースに戻る
  1. A160~120 分ハイブリッド検索アプリ課題の概要を開く
  2. A245~90 分MCP で Doris に質問課題の概要を開く
  3. A360~120 分ログ検索エクスプローラー課題の概要を開く
  4. A460~120 分エージェントトレースエクスプローラー現在位置
  5. B30~60 分トラック B · ドキュメントからデモへ課題の概要を開く