Using LLM Tracing to See Inside an AI Workflow
如果一個 API 回傳:
HTTP/1.1 200 OK
代表系統成功了嗎?
在傳統 Web Service 裡,我們至少可以說:
這次 HTTP Request 成功完成了。
但如果 API 背後站著的是 LLM,事情就沒這麼簡單。
假設公司做了一個內部 HR Assistant。
使用者問:
公司請假規則是什麼?
API 回傳:
HTTP/1.1 200 OK
LLM 回答:
員工每年享有 30 天特休。
乍看一切正常。
唯一的問題是:
公司的規章裡根本沒有這一條。
恭喜。
API 成功了,使用者任務卻失敗了。
這不是虛構的情境。2024 年,加拿大民事裁決庭就判 Air Canada 敗訴,原因是官網 Chatbot 給了乘客錯誤的喪假優惠資訊;航空公司甚至辯稱 Chatbot 是「獨立法律實體」,要自己為自己的回答負責,被裁決庭認為是「remarkable」的說法。API 沒有壞,HTTP 也是 200,公司卻要真的賠錢。(CBC News:Air Canada found liable for chatbot's bad advice)
如果我們只從傳統 Web Service 的角度觀察這個系統,可能會看到:
Status Code: 200
Latency: 1.8s
CPU: 23%
Memory: 41%
Error Rate: 0%
Dashboard 一片綠。
值班工程師甚至可以放心去泡咖啡。
但我們仍然不知道:
這就是 AI Application 開始與一般 API 分岔的地方。
HTTP 200 只能代表技術請求成功,不代表使用者任務成功。
所以 Day 1 我不打算先塞給你:
今天只做一件事:
打開一次 LLM Request,看看它的完整生命週期。
一個傳統服務可能長這樣:
Client
↓
API
↓
Application
↓
Database
↓
Response
如果這次 Request 很慢,Distributed Tracing 可以把整段 Request 拆開:
HTTP Request 820 ms
├── Authentication 20 ms
├── Application Logic 100 ms
└── PostgreSQL Query 700 ms
這時候問題一眼就很明顯:
FastAPI 沒有拖時間,真正卡住的是 PostgreSQL。
Trace 的價值,就是把原本的一個:
Request
拆成:
Request
├── Step A
├── Step B
└── Step C
讓我們知道:
這些資訊讓 Failure Domain 更快縮小,Reliability Engineering 不必靠猜。
這套拆解 Request 的方法不是憑空發明的。Google 在 2010 年發表的 Dapper 論文 首次系統性定義了 Trace、Span 與 Parent/Child 的追蹤模型,後來 Twitter 的 Zipkin、Uber 的 Jaeger 都是延續同一套概念的開源實作。今天 LangSmith 用的 Trace/Run 結構,本質上是同一套邏輯往 AI Workflow 延伸。
當 Application 加入 LLM 後,一條 Request 可能逐漸變成:
Client
↓
API
↓
Prompt Construction
↓
Retriever
↓
LLM
↓
Tool Call
↓
Output Parser
↓
Safety Validation
↓
Response
這條路徑早已超過傳統的:
API → Database → Response
它是一條:
未來一個 AI Application 可能包含:
Prompt
Retriever
Vector DB
Embedding Model
LLM Provider
Tools
Parser
Guardrails
Evaluator
每一個步驟都可能:
但 Day 1 我們先不要搞這麼大。
今天只建立最小 Workflow:
Client
↓
FastAPI
↓
Prompt
↓
Gemini
↓
Response
沒有:
第一天如果全部塞進來,我們最後最熟的東西可能不是 SRE。
而是:
docker compose down
在正式進入 LLM Trace 之前,先建立最基本的 Observability 直覺。
| Telemetry | 最擅長回答 |
|---|---|
| Metrics | 整體系統現在好不好? |
| Logs | 某件事情實際發生了什麼? |
| Traces | 這次 Request 經過哪些步驟? |
| LLM Trace | 這次 AI Workflow 怎麼執行? |
假設 Production 突然出現:
P95 Latency
1.8s → 12.4s
Metrics 可以告訴我們:
系統變慢了。
但接下來的問題是:
哪裡慢?
Logs 可能看到:
Gemini request timeout
我們開始有方向了。
Trace 則可能直接看到:
POST /ask 12.4s
└── ask_workflow 12.2s
├── build_prompt 2ms
└── Gemini 12.1s
這時候至少不用召集五個人開始通靈:
「是不是 FastAPI async 寫壞了?」
不是。
證據就在眼前。
LLM Trace 沒有另開一套 Observability 世界。
比較好的理解方式是:
LLM Tracing 是 Distributed Tracing 往 AI Workflow 內部延伸。
傳統 Trace 關心:
Frontend
↓
Backend
↓
Database
LLM Application 還會多觀察:
Prompt
↓
Retrieval
↓
Model
↓
Tool
↓
Parser
於是除了傳統的:
之外,我們還會開始追蹤:
LLM Trace 用來理解 AI Workflow 的執行路徑,不是偷看模型回答。
第一次看到:
client = wrappers.wrap_gemini(
gemini_client,
)
很容易誤解成:
LangSmith 是不是變成 Gemini 前面的一層 Proxy?
不是。
實際關係比較接近:
┌─────────────────────────┐
│ LangSmith │
│ │
│ Trace / Run / Metadata │
└────────────▲────────────┘
│
│ Telemetry
│
Client │
│ │
▼ │
FastAPI │
│ │
▼ │
ask_workflow ─────────────────────┤
│ │
▼ │
build_prompt ─────────────────────┤
│ │
▼ │
wrap_gemini() ────────────────────┤
│
▼
Google Gen AI SDK
│
│ HTTPS Request
▼
Gemini API
│
▼
LLM Response
│
▼
FastAPI
│
▼
Client
真正負責呼叫 Gemini 的仍然是:
Google Gen AI SDK
LangSmith 的角色比較接近:
Instrumentation
+
Trace Backend
也就是:
Application 照常執行 Gemini Call,同時把這次執行產生的 Telemetry 記錄下來。
Client
↓
FastAPI
↓
Google Gen AI SDK
↓
Gemini API
↓
Response
這條路徑負責真正服務使用者。
Application
↓
LangSmith Instrumentation
↓
Trace / Run
↓
LangSmith
這條路徑負責回答:
剛剛那次 Workflow 到底發生了什麼?
這兩條路徑不要混在一起。
wrap_gemini() 到底在做什麼?原本我們可能直接建立 Gemini Client:
gemini_client = genai.Client(
api_key=settings.gemini_api_key,
)
然後:
response = await gemini_client.aio.interactions.create(
model=settings.model_name,
input=prompt,
)
概念上:
Application
↓
Google Gen AI SDK
↓
Gemini
加入:
client = wrappers.wrap_gemini(
gemini_client,
)
後,可以把它理解成:
Gemini Call 開始
↓
記錄 Start Time
↓
記錄 Input / Model
↓
真正送出 Gemini Request
↓
收到 Gemini Response
↓
記錄 Output
↓
記錄 Token Usage
↓
計算 Latency
↓
如果失敗,記錄 Error
↓
結束 Run
這是 wrap_gemini() 原本設計要做的事——概念上仍然是在:
呼叫 Gemini,同時多了一份 Telemetry。
但這份 Instrument 目前主要覆蓋的是 models.generate_content() 這條路徑。實測會發現,換成 Interactions API(client.aio.interactions.create(...))呼叫時,這層 Telemetry 並沒有真的多出一筆獨立的 Gemini Run——細節留到 ⑨ 用真實 API Key 實測時再說。
@traceable 又是在做什麼?wrap_gemini() 能知道:
這裡發生了一次 Gemini Call。
但 Application 不只有 Gemini Call。
例如:
@traceable(
name="build_prompt",
run_type="chain",
)
def build_prompt(question: str) -> str:
...
代表:
build_prompt()是 Workflow 裡的一個可觀測步驟。
再例如:
@traceable(
name="ask_workflow",
run_type="chain",
)
async def ask_llm(question: str):
...
代表:
整個
ask_llm()是更上層的 Workflow。
所以 ask_workflow 跟 build_prompt 最後不是兩筆互不相關的紀錄,而是:
ask_workflow
│
└── build_prompt
形成 Parent / Child 關係(Gemini 呼叫本身要不要出現在這棵樹裡,取決於 wrap_gemini() 有沒有真的 Instrument 到當下用的這條 SDK 呼叫路徑——見 ⑨)。
如果你有 Distributed Tracing 經驗,可以暫時這樣對照:
LangSmith Trace
≈
Distributed Trace
LangSmith Run
≈
Span
例如:
Trace: Request #A123
ask_workflow 1.8s
│
├── build_prompt 2ms
│
└── Gemini Call 1.7s
整體是一條:
Trace
裡面的:
ask_workflow
build_prompt
Gemini Call
是不同的:
Run
而且 Runs 之間有:
Parent
↓
Child
的關係。
這就是為什麼我們可以知道:
Gemini 的 1.7 秒,屬於哪一次
/askRequest。
而不是只有一條孤零零的:
Gemini latency = 1.7s
把整條 Request 拆開:
① Client 發送 POST /ask
↓
② FastAPI 收到 Question
↓
③ ask_workflow 開始
建立 Parent Run
↓
④ build_prompt 執行
建立 Child Run
↓
⑤ Application 呼叫 Gemini
↓
⑥ Google Gen AI SDK
將 HTTPS Request 送到 Gemini API
↓
⑦ Gemini 產生 Response
↓
⑧ SDK 收到 Response
↓
⑨ ask_workflow 結束
↓
⑩ FastAPI 回傳 JSON
最後 LangSmith UI 實際重建出來的是:
POST /ask
└── ask_workflow
└── build_prompt
拿真實 API Key 跑一次、去 LangSmith 後台核對 Run 後發現:目前(langsmith>=0.12.2,wrap_gemini() 仍是 Beta)用 Interactions API(client.aio.interactions.create())呼叫時,wrap_gemini() 沒有額外生出一筆獨立的 Gemini Run,Trace 樹裡只看得到手動 @traceable 標記的 ask_workflow 跟 build_prompt 兩層,Gemini 呼叫本身的 Token Usage / Latency 也沒有被單獨記錄下來。wrap_gemini() 目前 instrument 的主要是 models.generate_content() 這條舊路徑,還沒跟上 Interactions API。想拿到 Gemini Call 這層的 Telemetry,現階段得自己在 ask_llm() 裡手動記錄,或等 SDK 更新。
今天要完成的架構很小:
POST /ask
↓
FastAPI
↓
Build Prompt
↓
Call Gemini
↓
LangSmith Trace
↓
JSON Response
使用:
FastAPI
Google Gen AI SDK
Gemini API
LangSmith
uv
專案結構:
day01-ai-trace/
├── app/
│ ├── __init__.py
│ ├── config.py
│ ├── llm.py
│ ├── main.py
│ └── schemas.py
├── .env.example
├── .gitignore
├── pyproject.toml
└── uv.lock
Day 0 已經處理過 Python、uv、Gemini API Key 與 LangSmith API Key,Day 1 直接開始建立服務。
如果 Day 0 還沒裝完整,可以執行:
uv add \
fastapi \
"uvicorn[standard]" \
google-genai \
langsmith \
pydantic-settings
確認:
uv sync
.env:
GEMINI_API_KEY=your_gemini_api_key
LANGSMITH_TRACING=true
LANGSMITH_API_KEY=your_langsmith_api_key
LANGSMITH_PROJECT=learning-sre-ai-era-day01
MODEL_NAME=gemini-3.6-flash
其中:
GEMINI_API_KEY
負責:
Application → Gemini
而:
LANGSMITH_API_KEY
負責:
Application → LangSmith
這正好對應前面那兩條不同資料流。
LANGSMITH_PROJECT 填的是專案名稱,不是後台那個專案的識別碼。填錯不會報錯,只會默默開一個新專案收 Trace,讓你在原本以為的專案底下找不到任何 Run,誤判成 Tracing 沒生效。
建立:
app/config.py
from functools import lru_cache
from pydantic_settings import BaseSettings, SettingsConfigDict
class Settings(BaseSettings):
gemini_api_key: str
model_name: str = "gemini-3.6-flash"
model_config = SettingsConfigDict(
env_file=".env",
extra="ignore",
)
@lru_cache
def get_settings() -> Settings:
return Settings()
這裡只管理 Application 自己需要讀取的:
GEMINI_API_KEY
MODEL_NAME
LangSmith 則直接讀 Environment Variables。
app/schemas.py:
from pydantic import BaseModel, Field
class AskRequest(BaseModel):
question: str = Field(
min_length=1,
max_length=4000,
)
class AskResponse(BaseModel):
answer: str
model: str
我們的 API 很單純。
Request:
{
"question": "What is an SLO?"
}
Response:
{
"answer": "An SLO is ...",
"model": "gemini-3.6-flash"
}
這是故意的。
Day 1 要看的不是 API Architecture。
而是:
Request 裡面發生了什麼?
建立:
app/llm.py
先初始化 Gemini:
from google import genai
from langsmith import traceable, wrappers
from app.config import get_settings
settings = get_settings()
gemini_client = genai.Client(
api_key=settings.gemini_api_key,
)
再交給 LangSmith instrumentation:
client = wrappers.wrap_gemini(
gemini_client,
tracing_extra={
"tags": [
"day01",
"gemini",
],
"metadata": {
"provider": "google",
"sdk": "google-genai",
},
},
)
現在:
Application
↓
wrap_gemini
↓
Google Gen AI SDK
↓
Gemini
但記得:
wrap_gemini()不是 LLM Provider,也不是 Reverse Proxy。
接著定義一個最小 Prompt:
SYSTEM_PROMPT = """
You are a concise SRE tutor.
Answer the user's question accurately and briefly.
If you are unsure, clearly state what is uncertain
instead of inventing information.
"""
再建立 Prompt function:
@traceable(
name="build_prompt",
run_type="chain",
)
def build_prompt(
question: str,
) -> str:
return f"""
{SYSTEM_PROMPT}
User question:
{question}
""".strip()
但我們故意讓它:
Traceable
因為未來 Prompt Construction 可能開始包含:
System Prompt
User Context
Retrieved Documents
Policy
Prompt Version
Day 1 先把這個 Workflow Boundary 留出來。
接著:
@traceable(
name="ask_workflow",
run_type="chain",
)
async def ask_llm(
question: str,
) -> dict[str, str]:
prompt = build_prompt(question)
interaction = await client.aio.interactions.create(
model=settings.model_name,
input=prompt,
)
return {
"answer": interaction.output_text or "",
"model": settings.model_name,
}
完整的 app/llm.py:
from google import genai
from langsmith import traceable, wrappers
from app.config import get_settings
settings = get_settings()
gemini_client = genai.Client(
api_key=settings.gemini_api_key,
)
client = wrappers.wrap_gemini(
gemini_client,
tracing_extra={
"tags": [
"day01",
"gemini",
],
"metadata": {
"provider": "google",
"sdk": "google-genai",
},
},
)
SYSTEM_PROMPT = """
You are a concise SRE tutor.
Answer the user's question accurately and briefly.
If you are unsure, clearly state what is uncertain
instead of inventing information.
"""
@traceable(
name="build_prompt",
run_type="chain",
)
def build_prompt(
question: str,
) -> str:
return f"""
{SYSTEM_PROMPT}
User question:
{question}
""".strip()
@traceable(
name="ask_workflow",
run_type="chain",
)
async def ask_llm(
question: str,
) -> dict[str, str]:
prompt = build_prompt(question)
interaction = await client.aio.interactions.create(
model=settings.model_name,
input=prompt,
)
return {
"answer": interaction.output_text or "",
"model": settings.model_name,
}
現在我們已經得到:
ask_workflow
│
├── build_prompt
│
└── Gemini
ask_workflow 現在已經串起 build_prompt 與 Gemini Call。
建立:
app/main.py
from fastapi import FastAPI, HTTPException
from app.llm import ask_llm
from app.schemas import AskRequest, AskResponse
app = FastAPI(
title="Learning SRE for the AI Era — Day 01",
version="0.1.0",
)
@app.get("/healthz")
async def healthz() -> dict[str, str]:
return {
"status": "ok",
}
@app.post(
"/ask",
response_model=AskResponse,
)
async def ask(
request: AskRequest,
) -> AskResponse:
try:
result = await ask_llm(
request.question,
)
return AskResponse(**result)
except Exception as exc:
raise HTTPException(
status_code=502,
detail="LLM request failed",
) from exc
目前沒有:
ProviderAdapter
ModelRouter
LLMFactory
PromptRepository
WorkflowManager
因為我們現在只有:
FastAPI → Gemini
如果第一天就生出:
AbstractAIProviderFactoryManager
那不是 Architecture。
那是創傷。
執行:
uv run uvicorn app.main:app --reload
先測試:
curl http://localhost:8000/healthz
應該得到:
{
"status": "ok"
}
接著送出第一個 AI Request:
curl \
-X POST \
http://localhost:8000/ask \
-H "Content-Type: application/json" \
-d '{
"question": "What is an SLO?"
}'
可能得到:
{
"answer": "An SLO is a target level of reliability for a service.",
"model": "gemini-3.6-flash"
}
指令列測試成功;接下來要看的,是 LangSmith 裡的 Trace。
進入 LangSmith:
learning-sre-ai-era-day01
找到剛剛產生的 Trace。
理想上會看到:
ask_workflow
│
├── build_prompt
│
└── Gemini
今天只觀察幾個欄位:
| Trace 資訊 | 今天觀察什麼? | 未來 SRE 意義 |
|---|---|---|
| Trace / Run ID | 是否能識別單次執行 | Incident correlation |
| Workflow Latency | 整條 Request 多久 | End-to-end latency |
| Model Latency | Gemini 花多久 | Dependency latency |
| Prompt | Model 實際看到什麼 | Prompt debugging |
| Model | 實際使用哪個模型 | Change management |
| Input Tokens | Context 大小 | Capacity / Cost |
| Output Tokens | 生成量 | Cost / Throughput |
| Error | 哪一步失敗 | Failure localization |
| Output | 最後產生什麼 | Semantic investigation |
原本我們只有:
POST /ask
HTTP 200
現在變成:
ask_workflow 1.82s
│
├── build_prompt 1ms
│
└── Gemini 1.79s
├── Model
├── Prompt
├── Input Tokens
├── Output Tokens
└── Response
原本的 AI 黑盒子開始有輪廓了。
這次先主動製造一次故障:
不要等 Production 壞給你看。
自己先把它弄壞。
把:
MODEL_NAME=gemini-3.6-flash
改成:
MODEL_NAME=definitely-not-a-real-model
重新啟動 Application。
再呼叫:
curl \
-X POST \
http://localhost:8000/ask \
-H "Content-Type: application/json" \
-d '{
"question": "What is an SLO?"
}'
FastAPI 應該會回:
502 Bad Gateway
只有 HTTP 時:
POST /ask → 502
我們得到的資訊是:
壞了。
謝謝。
非常有幫助。
但 Trace 可能看到:
ask_workflow
│
├── build_prompt SUCCESS
│
└── Gemini ERROR
Failure Domain 馬上縮小:
FastAPI Endpoint?
至少有收到 Request。
Prompt Construction?
成功。
Gemini Call?
失敗。
這次故障顯示,Observability 能縮小 Failure Domain:
收集資料的目的,是降低未知數。
再來一個更接近 Production 的情境。
假設 Dashboard 告訴你:
P95 Latency = 15 seconds
問題可能出現在:
沒有 Trace:
¯\_(ツ)_/¯

大家輪流猜。
有 Trace:
Request 15.2s
├── build_prompt 2ms
└── Gemini 15.1s
至少知道:
Application Logic 大概不是主要瓶頸。
未來加入 RAG 後可能變成:
Request 15.2s
├── build_prompt 2ms
├── retrieval 11.8s
└── Gemini 3.1s
答案馬上變了。
Trace 不會讓 Failure 消失。
它做的是讓你從:
我覺得問題在這裡。
變成:
Evidence 顯示問題在這裡。
傳統 Service 通常會關心:
Availability
Latency
Errors
Traffic
CPU
Memory
Database
Network
AI Application 除了這些之外,又開始增加:
Prompt
Model
Tokens
Retrieval
Tools
Retries
Cost
Evaluation
未來完整 Workflow 可能長成:
Client
↓
API
↓
Prompt / Policy
↓
Retriever
├── Query
├── Vector DB
└── Document IDs
↓
Model Router
↓
Gemini / Other Provider
├── Model
├── Tokens
├── Latency
└── Cost
↓
Tool Executor
├── Tool
├── Input
├── Output
└── Latency
↓
Validator
↓
Response
Trace 裡也可能慢慢出現:
prompt_version
retrieval_query
document_ids
embedding_model
provider
model_version
tool_name
tool_latency
agent_step_count
retry_count
input_tokens
output_tokens
cost
evaluation_label
safety_decision
所以:
AI Observability 不是在 Prometheus 多加幾個 Gemini Metrics。
而是:
Reliability 的觀測邊界開始深入 AI Workflow。
現在回到文章最一開始。
假設 Trace 顯示:
API SUCCESS
Prompt SUCCESS
Gemini SUCCESS
Parser SUCCESS
LLM 最後回答:
員工一年有 30 天特休。
結果:
還是錯的。
Trace 能夠告訴我們:
系統怎麼產生這個答案。
但它不一定能告訴我們:
這個答案是否正確。
所以 AI Application 會出現三個不同層級:
Technical Success
≠
Workflow Success
≠
Task Success
也就是:
HTTP 200
≠
Workflow 正常
≠
使用者得到正確答案
這也是後續會正式討論:
的原因。
Observability ≠ Evaluation。
Observability 回答:
發生了什麼?
Evaluation 才開始回答:
結果夠不夠好?
2023 年紐約一起訴訟案更極端:律師用 ChatGPT 查案例,AI 順利產生了看起來格式完全正確的判例引用,整個流程「技術上」毫無異常。問題是,其中六個判例根本不存在。法官形容這些是「bogus judicial decisions with bogus quotes」。(BBC:ChatGPT — US lawyer admits using AI for case research)如果當時律師團隊只看 Trace 有沒有 Error,看到的會是一片綠燈;能抓出問題的,只有真正去驗證內容的 Evaluation 環節。
重要,因為 Metrics 適合觀察整體趨勢。
用了 LangSmith,不代表:
Prometheus
Logs
OpenTelemetry
突然全部可以丟掉。
假設 Production 一小時有:
100,000 Requests
你不會打開 100,000 條 Trace 開始手算:
Error Rate 是多少?
Metrics 更擅長回答:
整體趨勢
Error Rate
P95
P99
Traffic
Saturation
Trace 更擅長:
單一 Request
到底去哪裡慢
到底在哪裡失敗
Logs 則幫助我們理解:
具體發生什麼事件
Exception 是什麼
Application 寫了哪些狀態
未來整體關係會變成:
Prometheus
↓
發現 P95 Latency 異常
↓
Trace
↓
找到 Gemini Dependency 變慢
↓
Logs
↓
查看實際 Error / Retry 資訊
所以不是:
Metrics vs Logs vs Traces
而是:
Metrics + Logs + Traces
Day 21 我們會正式回來把三者串起來。
Gemini 本身也提供 OpenAI-compatible API。
但 Day 1 我們刻意使用:
google-genai
而不是:
OpenAI SDK
↓
Gemini OpenAI-compatible Endpoint
原因很簡單:
今天要回答的是:
一條 AI Workflow 到底怎麼執行?
而不是:
怎麼設計 Multi-provider Abstraction?
這兩件事情不要第一天混在一起。
未來進入:
時,我們會再把架構演進成:
Application
↓
Provider Abstraction
↓
┌───────────┬───────────┐
│ Gemini │ Provider B│
└───────────┴───────────┘
Day 1 保持簡單:
Application
↓
Gemini
不要太早抽象。
尤其當你現在只有一個 Provider。
今天沒有建立什麼巨大平台。
只有:
FastAPI
↓
Prompt
↓
Gemini
↓
Response
再加上一件事:
Trace
但就是這一條 Trace,把原本只有:
HTTP 200
的世界,擴展成:
Request
├── Prompt
├── Model
├── Latency
├── Tokens
├── Error
└── Output
傳統 Service Reliability 會問:
Request 有沒有成功完成?
AI Reliability 還必須繼續問:
它怎麼完成?
經過哪些步驟?
依賴哪些 External Dependencies?
哪一段最慢?
使用哪個 Model?
花了多少 Tokens?
發生 Retry 了嗎?
最後產生什麼結果?
甚至:
這個結果值得使用者相信嗎?
如果今天只能記住一件事。
不要記:
wrap_gemini()
也不要記:
LANGSMITH_TRACING=true
當 Application 從 deterministic request 變成 AI workflow,我們需要觀測的邊界,也必須跟著深入 Workflow。
LangSmith 今天只是讓我們快速看見這條 Workflow 的工具。
工具之後可以換。
未來即使變成:
OpenTelemetry
↓
OTLP
↓
Tempo / Jaeger
我們仍然要回答:
Instrument
↓
Propagate Context
↓
Record Execution
↓
Export Telemetry
Tracing 的概念不會因為工具改變。
Day 1 才剛把 Gemini 接起來。
Day 2 我們反而要先把 AI 放旁邊。
因為:
再漂亮的 LLM Trace,也不能取代 Reliability Engineering 的基本功。
下一篇我們會建立整個系列共用的 SRE Lab:
Client
↓
FastAPI
├── PostgreSQL
├── Redis
├── Prometheus
├── Loki
├── OpenTelemetry
└── Grafana
全部透過 Docker Compose 啟動。
然後正式開始:
Build
↓
Break
↓
Observe
↓
Explain
最後再一路把它演化回 AI Workflow:
Build
↓
Trace
↓
Break
↓
Measure
↓
Evaluate
↓
Recover
↓
Improve
這篇是 Learning SRE for the AI Era 系列的一部分。
我會從 SRE 的服務可靠性基礎開始,逐步探索當系統加入 LLM、RAG、Agent 與 GPU Infrastructure 後,如何讓 AI 系統不只可用,也能被觀測、評估、控制成本並安全演進。
Build → Trace → Break → Measure → Evaluate → Recover → Improve.