BaseCallbackHandler 를 상속한 FileTracer 를 실행 config 의 callbacks 에 넣으면, Supervisor → handoff → 서브 Agent → 도구 → 복귀를 지나는 동안
모델·도구 호출이 시작하고 끝날 때마다 메서드가 불려 trace.jsonl 에 한 줄씩 쌓입니다. 이벤트의 순서, run_id 로 짝을 맞추는 법, 기록되지 않는 것을 단계별로 봅니다.
그래프 코드는 그대로 두고, 실행할 때 넘기는 config 에 tracer 를 실을 뿐입니다. 그 실행에서 파생된 모든 모델 호출과 도구 호출이 같은 핸들러의 메서드를 부릅니다.
transfer_to_… 도구 호출 (기록됨)
복귀: transfer_back_to_supervisor 메시지 쌍 (도구 실행이 아니라 기록 없음)
콜백 메서드 호출과 파일 쓰기
FileTracer (day7_practice/local_tracer.py) | LLMLogger (day6_practice/final_scenario.py) | |
|---|---|---|
| 있는 곳 | 별도 모듈. 필요할 때 바깥에서 config 로 붙임 | 그래프 파일 안. main() 의 astream config 에 붙임 |
| 잡는 이벤트 | 모델 시작·끝·오류 + 도구 시작·끝 | 모델 시작·끝·오류만 (도구 메서드 없음) |
| 형식 | JSONL. 한 줄에 dict 하나라 프로그램으로 세기 쉬움 | 사람이 읽는 텍스트. 콘솔과 llm_calls.log 에 같이 |
| 내용 길이 | 메시지·결과마다 앞 200자 | 전문 |
| 누가 불렀나 | 적지 않음 | metadata["langgraph_checkpoint_ns"] 의 앞부분 (supervisor, data_agent …) |
| tool_calls | 적지 않음 (llm_end 는 gen.text 만) | 입력 메시지와 출력 모두에 <tool_calls: …> 로 표시 |
| 파일 다루기 | 쓸 때마다 "a". 실행을 거듭하면 계속 쌓임 | 만들 때 "w" 로 비우고, 줄마다 "a". 실행마다 새로 시작 |
| 짝 맞추기 | run_id → time.time() | run_id → (순번, perf_counter(), 누가) |
원고가 짚은 대로 FileTracer 에는 호출 주체 칸이 없습니다. LLMLogger 처럼 콜백이 함께 받는 metadata 를 읽으면 같은 방법으로 보강할 수 있습니다.
parent_run_id, tags, metadata 도 받지만 FileTracer 는 모두 **kw 로 받고 버립니다. 노드 실행(체인 런)을 알리는 on_chain_start 도 구현하지 않았으므로 trace.jsonl 은 시간순으로 늘어선 평평한 줄 목록이고, 어느 호출이 어느 Agent 안에서 일어났는지는 줄 순서와 입력의 첫 메시지로 미루어 볼 뿐입니다."output": "" 입니다. llm_end 는 gen.text 만 적고 tool_calls 는 적지 않습니다. 무엇을 주문했는지는 바로 뒤 tool_start 줄의 tool 로 확인합니다.tool_end 에는 도구 이름이 없습니다. 같은 run_id 의 tool_start 와 맞춰 봐야 합니다. 설치된 langchain_core 소스를 보면 on_tool_end 를 부를 때 name= 도 키워드로 넘기지만, 이 역시 **kw 로 버려집니다.tool_start 를 남깁니다. on_tool_error 가 없어서 끝 줄이 생기지 않고, _starts 에 넣은 시작 시각도 꺼내지지 않은 채 남습니다."a" 모드라 실행을 거듭하면 한 파일에 섞입니다. 실행을 구분하는 칸이 없고 ts 는 초 단위라, 연달아 돌리면 어디서 새 실행이 시작됐는지 가르기 어렵습니다.thread_id 는 쓰이지 않습니다. 7일차판 final_scenario.py 는 supervisor.compile() 로 체크포인터 없이 만들어지므로 "trace-demo" 는 저장할 곳이 없습니다. 추적을 켜는 것은 "callbacks": [tracer] 쪽입니다.day7_practice/local_tracer.py 모델·도구 호출의 시작과 끝을 JSONL 한 줄씩 남기는 FileTracer 와 get_textday7_practice/trace_run.py build_app() 으로 만든 Supervisor 그래프에 tracer 를 config 로 붙여 질문 하나를 실행day7_practice/final_scenario.py 추적 대상인 7일차판 Supervisor 그래프 (체크포인터·Store 없이 compile)day6_practice/final_scenario.py 모델 호출만 콘솔과 llm_calls.log 에 남기는 LLMLogger 가 들어 있는 6일차 판day7_practice/integration_check.py 같은 FileTracer 를 integration_trace.jsonl 로 붙여 쓰는 통합 점검