강좌Apache Doris 해커톤자기 주도 과제 · 언제든 시작 · 등록 불필요

트랙 A · 과제 A4

에이전트 트레이스 탐색기

AI 에이전트의 JSON은 릴리스마다 구조가 바뀝니다. VARIANT에 저장하고 일반 열처럼 쿼리하세요.

  • 60~120분
  • 중급
  • 언어 자유 · CLI, 노트북 또는 웹
  • AI 도구 사용 환영

막히는 부분이 있나요? 질문할 곳: #dev 참여할 곳: Apache Doris Slack. 유지 관리자와 다른 참가자가 도와드립니다.

1

환경 준비

만들 결과물과 Doris로 간단히 구현하는 이유를 알아보고 클러스터를 실행합니다.

만들 결과물

제각각인 에이전트 JSON도 그대로 쿼리하세요.

LLM 호출, 도구 호출, 오류, 최종 답변은 각각 다른 필드를 가지며 릴리스마다 새 필드가 추가됩니다. Doris의 VARIANT 는 JSON을 타입이 있는 열로 자동 변환하므로 일반 SQL로 필터링, 검색, 집계할 수 있습니다. 스키마 마이그레이션이 필요 없습니다.

다음을 위한 트레이스 탐색기: AI 에이전트 세션 1,000개(약 20,000개 이벤트):

  • 검색용 세션 목록 (이벤트 수, 오류, 토큰, 지연 시간 표시),
  • 검색용 세션 타임라인: 세션을 클릭하면 에이전트의 동작을 단계별로 재생,
  • 도구 및 모델 통계: p95 지연 시간, 오류율, 토큰 사용량,
  • JSON 내부 검색: ‘timeout’이 포함된 모든 도구 오류를 찾습니다.

그리고 다음에 답하세요: 13:00에 배포된 에이전트 v2로 상황이 좋아졌나요, 나빠졌나요?

개략도만들 결과물 · 와이어프레임(스크린샷 아님)

개략도는 코드 패널 상단에 있습니다

Doris로 구현할 때의 장점

  • 스키마 정의 없이 쓰기 시점에 타입 결정. VARIANT는 각 JSON 경로의 타입을 추론하고 자주 쓰는 경로를 실제 컬럼형 하위 열로 저장합니다. 따라서 payload['latency_ms'] 는 문서 전체를 파싱하지 않고 열 하나만 읽습니다.

  • 새 필드는 자동으로 나타납니다. 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 : 에이전트 이벤트마다 한 행이며 이벤트 본문은 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;
    확인 사항

    도구는 다섯 개이며 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 및 도구 호출(실패 후 재시도한 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 수행하지 않았습니다.

    확인 사항

    세 번째 버전이 나타납니다: v2.1: 해당 버전의 LLM 호출에만 다음이 포함됩니다: cost_usd, 그리고 DESC 에 다음이 표시됩니다: payload.cost_usd 및 payload.retries.

3

완성하기

체크리스트를 확인하고 결과물을 공유한 뒤 배지를 받으세요.

완료 기준

체크리스트

제출하고 배지 받기

참여 → 제출 → 배지 받기.

  1. 다음 이름의 폴더에 결과물을 넣으세요: 본인의 GitHub ID. 코드와 README를 포함하고, README에 기능, 실행 방법, 스크린샷 또는 GIF 한 개, 사용한 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)를 내보내 한 줄에 하나의 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 해커톤

전체 과제

강좌로 돌아가기
  1. A160~120분하이브리드 검색 앱과제 개요 열기
  2. A245~90분MCP로 Doris에 질문하기과제 개요 열기
  3. A360~120분로그 검색 탐색기과제 개요 열기
  4. A460~120분에이전트 트레이스 탐색기현재 위치
  5. B30~60분트랙 B · 문서에서 데모로과제 개요 열기