全部產品
Search
文件中心

Cloud Monitor:OT-LLM品質分析

更新時間:May 01, 2026

從 OT-Trace 資料中提取每次 LLM 調用的完整快照,經去重採樣後自動完成 Prompt 與響應的品質評估及 Token 統計分析。

業務情境

AI Agent 應用中 LLM 調用是核心組件。本模板聚焦單次 LLM 調用(Span-LLM)粒度,支援以下分析情境:

  • 發現 Prompt 設計缺陷,例如 System Prompt 缺失、輸入訊息冗餘等。

  • 識別異常響應,例如幻覺輸出、格式錯誤、工具調用異常。

  • 分析 Token 使用效率和推理效能,例如輸入輸出 Token 比、每秒產生速率。

Pipeline 流程

本模板的 Pipeline 分為以下 4 個階段,從原始 Trace 資料到 AI 品質評估依次處理。

階段

節點

說明

Phase 1:資料群組裝

extend(extract)

從 OT-Trace Span 原始欄位中提取 LLM 調用相關屬性,包括 session_idrequest_modelinput_tokensoutput_tokens 等。

make-instance

spanid 彙總,將同一次 LLM 調用的多條 Span 記錄合并為一行寬表。

extend(derive)

派生計算指標,包括 duration_ms(調用耗時)、tokens_per_sec(產生速率)、input_output_ratio(輸入輸出比)等。

where(filter)

過濾無效記錄,僅保留模型名稱非空且輸入 Token 大於 0 的調用。

Phase 2:資料清洗

dedup-exact

full_text 欄位精確去重,消除完全重複的 LLM 調用記錄。

Phase 3:特徵計算

doc-stats

full_text 進行文本統計,計算字元數、詞數和行數。

Phase 4:採樣 + AI 處理

sample

隨機採樣 50 條記錄,控制後續 AI 評估的調用量。

llm-call(quality_eval)

調用 AI 模型對每條 LLM 調用進行品質評估,輸出結構化評估結果。

調用品質評估Prompt模板

你是一位專業的 LLM 調用品質分析專家,擅長評估單次 LLM 調用的 Prompt 設計品質、響應效果和資源效率。

請根據以下評估維度,對這次 LLM 調用進行全面評估:

評估維度:

Prompt 品質: System Prompt 是否清晰定義了角色、約束和輸出格式?使用者輸入是否提供了足夠的上下文?(0-5分)
響應品質: LLM 輸出是否準確、完整、切題?是否有幻覺或跑題?(0-5分)
Token 效率: 輸入/輸出 token 比例是否合理?是否存在冗餘輸入或過長輸出?(0-5分)
延遲合理性: 根據 token 吞吐率(tok/s),推理效能是否在合理範圍?(0-5分)
工具調用: 若涉及 tool_call,工具選擇是否合理、參數是否正確?無工具調用則標記為 N/A。(0-5分或N/A)
評估參考:

Token 效率基準:input/output ratio 在 2:1 ~ 10:1 為合理範圍
延遲基準:tokens_per_sec > 30 為優秀,15-30 為良好,< 15 需關注
若 has_tool_call=true,重點評估工具選擇準確性
現在請評估以下 LLM 調用:

模型:{{request_model}} Token 使用:輸入 {{input_tokens}} / 輸出 {{output_tokens}} 效能指標:{{tokens_per_sec}} tok/s,耗時 {{duration_ms}} ms 工具調用:{{has_tool_call}} 調用詳情: {{full_text}}

請輸出JSON格式: { “prompt_quality”: {“score”: 分數, “reason”: “簡短理由”}, “response_quality”: {“score”: 分數, “reason”: “簡短理由”}, “token_efficiency”: {“score”: 分數, “reason”: “簡短理由”}, “latency_rating”: {“score”: 分數, “reason”: “簡短理由”}, “tool_usage”: {“score”: “分數或N/A”, “reason”: “簡短理由”}, “overall_score”: 綜合分數, “risk_flags”: [“風險標記1”, “風險標記2”], “optimization_suggestion”: “一句話最佳化建議” }

【重要】只輸出純JSON,不要添加任何markdown標記(如json或)。

完整配置

本模板提供 JSON 配置格式。關於 Pipeline 配置的基本概念和使用方式,請參見資料處理(Pipeline)

以下為完整的 Pipeline JSON 配置,可直接通過 API 建立。

{
  "name": "ot_llm_quality_analysis",
  "description": "OT-Trace Span-LLM 粒度:LLM 調用品質分析 — 從 Trace 資料提取所有 LLM 調用快照,去重採樣後進行 Prompt/響應品質評估與文本統計",
  "source": {
    "type": "logstore",
    "logstore": {
      "project": "ali-pub-cn-hangzhou-staging-sls-admin",
      "logstore": "logstore-tracing",
      "query": "\"attributes.gen_ai.span.kind\": LLM"
    }
  },
  "pipeline": {
    "nodes": [
      {
        "id": "extract",
        "type": "extend",
        "parameters": {
          "session_id":       "\"attributes.gen_ai.session.id\"",
          "user_id":          "\"attributes.gen_ai.user.id\"",
          "framework":        "\"attributes.gen_ai.framework\"",
          "operation_name":   "\"attributes.gen_ai.operation.name\"",
          "provider":         "\"attributes.gen_ai.provider.name\"",
          "request_model":    "CASE WHEN \"attributes.gen_ai.request.model\" IS NOT NULL AND \"attributes.gen_ai.request.model\" != '' THEN \"attributes.gen_ai.request.model\" WHEN substr(spanname, 1, 4) = 'llm:' THEN substr(spanname, 5) WHEN substr(spanname, 1, 14) = 'llm_streaming_' THEN substr(spanname, 15) WHEN substr(spanname, 1, 9) = 'llm_call_' THEN substr(spanname, 10) WHEN substr(spanname, 1, 5) = 'chat ' THEN substr(spanname, 6) WHEN strpos(spanname, '.invoke') > 0 THEN substr(spanname, 1, strpos(spanname, '.invoke') - 1) ELSE spanname END",
          "system_prompt":    "\"attributes.gen_ai.system_instructions\"",
          "input_messages":   "\"attributes.gen_ai.input.messages\"",
          "output_messages":  "\"attributes.gen_ai.output.messages\"",
          "input_tokens":     "CAST(\"attributes.gen_ai.usage.input_tokens\" AS BIGINT)",
          "output_tokens":    "CAST(\"attributes.gen_ai.usage.output_tokens\" AS BIGINT)",
          "finish_reasons":   "\"attributes.gen_ai.response.finish_reasons\""
        }
      },
      {
        "id": "assemble",
        "type": "make-instance",
        "parameters": {
          "by": "spanid",
          "trace_id":         "any(traceid)",
          "service_name":     "any(servicename)",
          "span_name":        "any(spanname)",
          "duration_ns":      "max(duration)",
          "status_code":      "max(statuscode)",
          "span_time":        "first(__time__)",
          "session_id":       "any(session_id)",
          "user_id":          "any(user_id)",
          "framework":        "any(framework)",
          "operation_name":   "any(operation_name)",
          "provider":         "any(provider)",
          "request_model":    "any(request_model)",
          "system_prompt":    "first(system_prompt)",
          "input_messages":   "first(input_messages)",
          "output_messages":  "last(output_messages)",
          "input_tokens":     "sum(input_tokens)",
          "output_tokens":    "sum(output_tokens)",
          "finish_reasons":   "any(finish_reasons)"
        }
      },
      {
        "id": "derive",
        "type": "extend",
        "parameters": {
          "duration_ms":       "CAST(duration_ns AS DOUBLE) / 1000000.0",
          "tokens_per_sec":    "CASE WHEN CAST(duration_ns AS DOUBLE) > 0 THEN CAST(output_tokens AS DOUBLE) / (CAST(duration_ns AS DOUBLE) / 1000000000.0) ELSE 0.0 END",
          "input_output_ratio":"CASE WHEN CAST(output_tokens AS DOUBLE) > 0 THEN CAST(input_tokens AS DOUBLE) / CAST(output_tokens AS DOUBLE) ELSE 0.0 END",
          "has_tool_call":     "CASE WHEN finish_reasons LIKE '%tool_calls%' THEN 'true' ELSE 'false' END",
          "has_system_prompt": "CASE WHEN system_prompt IS NOT NULL AND system_prompt != '' THEN 'true' ELSE 'false' END",
          "full_text":         "concat('[', coalesce(request_model, '?'), '] ', coalesce(operation_name, 'chat'), chr(10), 'Tokens: ', coalesce(CAST(input_tokens AS VARCHAR), '?'), '→', coalesce(CAST(output_tokens AS VARCHAR), '?'), chr(10), 'Input: ', substr(coalesce(input_messages, ''), 1, 500), chr(10), 'Output: ', substr(coalesce(output_messages, ''), 1, 500))"
        }
      },
      {
        "id": "filter_valid",
        "type": "where",
        "parameters": {
          "filter": "(request_model IS NOT NULL AND request_model != '') AND (input_tokens IS NOT NULL AND input_tokens > 0)"
        }
      },
      {
        "id": "exact_dedup",
        "type": "dedup-exact",
        "parameters": {
          "field": "full_text"
        }
      },
      {
        "id": "text_stats",
        "type": "doc-stats",
        "parameters": {
          "field": "full_text"
        }
      },
      {
        "id": "downsample",
        "type": "sample",
        "parameters": {
          "n": 50
        }
      },
      {
        "id": "quality_eval",
        "type": "llm-call",
        "parameters": {
          "prompt": "@eval/llm-call-eval.md",
          "fields": "request_model,input_tokens,output_tokens,tokens_per_sec,duration_ms,has_tool_call,full_text",
          "format": "json",
          "as": "eval"
        }
      }
    ]
  },
  "sink": {
    "type": "dataset",
    "dataset": {
      "workspace": "inner-playground",
      "dataset": "ot_llm_quality_analysis"
    }
  },
  "executePolicy": {
    "mode": "run_once",
    "run_once": { "fromTime": 0, "toTime": 0 }
  }
}

欄位說明

下表列出本模板涉及的主要欄位及其來源。

extract 節點提取欄位

欄位名

原始屬性

說明

session_id

attributes.gen_ai.session.id

會話 ID。

user_id

attributes.gen_ai.user.id

使用者識別碼。

framework

attributes.gen_ai.framework

AI 架構名稱(如 LangChain、Semantic Kernel 等)。

operation_name

attributes.gen_ai.operation.name

操作類型(如 chat、completion 等)。

provider

attributes.gen_ai.provider.name

模型供應商名稱。

request_model

attributes.gen_ai.request.model

請求的模型名稱。支援從 Span 名稱中自動提取(當屬性欄位為空白時)。

system_prompt

attributes.gen_ai.system_instructions

系統指令(System Prompt)。

input_messages

attributes.gen_ai.input.messages

輸入訊息內容。

output_messages

attributes.gen_ai.output.messages

輸出訊息內容。

input_tokens

attributes.gen_ai.usage.input_tokens

輸入 Token 數量。

output_tokens

attributes.gen_ai.usage.output_tokens

輸出 Token 數量。

finish_reasons

attributes.gen_ai.response.finish_reasons

模型響應的結束原因。

derive 節點派生欄位

欄位名

類型

說明

duration_ms

DOUBLE

LLM 調用耗時(毫秒)。由 duration_ns 納秒轉換。

tokens_per_sec

DOUBLE

每秒產生 Token 數。計算公式:output_tokens / (duration_ns / 1e9)

input_output_ratio

DOUBLE

輸入/輸出 Token 比值。比值過高可能表示輸入訊息冗餘。

has_tool_call

VARCHAR

是否包含工具調用。當 finish_reasons 包含 tool_calls 時為 true

has_system_prompt

VARCHAR

是否包含 System Prompt。

full_text

VARCHAR

拼接的完整文本摘要,用於去重和文本統計。格式為 [模型名] 操作類型\nTokens: 輸入→輸出\nInput: ...\nOutput: ...

定製建議

可以基於本模板進行以下定製調整。

定製項

修改方式

說明

資料來源

修改 source.logstore 中的 projectlogstore

替換為實際的 OT-Trace 資料來源。

採樣數量

修改 sample.n 的值

控制 AI 評估的樣本量。增大採樣數會增加 AI 調用成本。

評估維度

自訂 prompts/llm-call-eval.md 中的評估提示詞

調整 AI 品質評估的評分標準和評估維度。

去重策略

dedup-exact 後追加 dedup-fuzzy 節點

在精確去重基礎上增加近似去重,進一步減少重複資料。

輸出目標

修改 sink.dataset 中的 workspacedataset

替換為實際的資料集輸出目標。