圖 1: AI 分析概念圖。決策邏輯樹圖,展示規則裁判無法判定時,路徑如何導向 AI 仲裁節點進行最終決策。
LLM 模組為 PowerBarcoder 提供智慧序列分析與決策輔助,核心定位:
- QC 模組整合:作為統一仲裁流程中 rule as judge 無結論 (INCONCLUSIVE) 時的仲裁層
- 序列差異解釋:對既有候選(DADA2 merged 與 Merger 最終結果)進行品質與差異描述
- 品質佐證:彙總 BLAST identity、ambiguity、lowercase、abundance/proportion 等指標於 prompt
簡化原則:不生成新序列、不進行多序列 consensus、不引入 IUPAC 擴張,只在固定候選集合中做來源選擇與理由生成。
避免對品質不佳或無足夠候選序列的樣本進行昂貴的 LLM API 調用,透過量化品質閾值進行預先篩選。
觸發時機:前端啟用規則時的所有樣本(Rule 1-6),統一進入 RuleAsJudge 品質預篩選
篩選步驟:
- 品質檢查:對 DADA2 和 Merger 序列應用閾值(abundance / proportion / ambiguity / lowercase / identity)
- 決策判斷:
- 0 通過 → 全拒 (manual_review) (
confidence: 0.1) → 不進 LLM - 僅一方通過 → 直接推薦該來源 (
confidence: 0.8/ 若低豐度或 warning -> 0.6) - 兩方均通過 → 標記 INCONCLUSIVE;若
llm_analysis_enabled=True→ LLM 仲裁;否則 Fallback(比較 DADA2 與 Merger 最高絕對豐度;confidence: 0.30)
- 0 通過 → 全拒 (manual_review) (
基於 src/qc/rule_as_judge.py 的 SequenceQualityThresholds 類別:
class SequenceQualityThresholds:
# ASV 基本要求
MIN_ABUNDANCE_THRESHOLD = 30 # abundance > 30
MIN_PROPORTION_THRESHOLD = 0.4 # proportion > 0.4
# Merger 品質要求
MAX_AMBIGUOUS_SITES = 10 # ambiguous sites < 10
MAX_LOWERCASE_SITES = 10 # lowercase sites < 10
# BLAST 品質要求
MIN_BLAST_IDENTITY = 0.9 # BLAST identity > 90%引入 RuleAsJudge 後的 LLM 使用情況追蹤:
rule_as_judge_count:品質過濾成功處理的數量rule_2_quality_filter_rejected_count:Rule 2 品質過濾拒絕的樣本數rule_3_quality_filter_rejected_count:Rule 3 品質過濾拒絕的樣本數llm_available_count:實際調用 LLM 的樣本數llm_fallback_count:LLM 失敗使用後備邏輯的樣本數
有合格序列,送交 LLM:
"Rule 2: Quality filtering applied - 2 sequences passed filtering (1 DADA2, 1 Merger) - LLM arbitration with top2 candidates"
無合格序列,直接放棄:
"Rule 3: Quality filtering applied - No sequences passed filtering - DADA2: low abundance/proportion (abundance=25, proportion=0.30), Merger: high ambiguity (18 sites)"
| 層級 | 模組/來源 | 角色 | 輸出 | 可否跳過 |
|---|---|---|---|---|
| 資料收集 | QCDataManager / path | 提供序列 + QC 欄位 | dict | 否 |
| 規則分類 | recommendation_engine | 決定 rule_type (1..6) | rule_type | 否 |
| 品質預篩 | RuleAsJudge | 過濾並計算合法 ASVs 數量 | decision / confidence / reasoning | 否 (統一流程) |
| LLM 仲裁 | LLMAnalysisPipeline + MergeAnalyzer | 解釋 & 選擇來源 | JSON / fallback | 可 (flag 或前端未勾選) |
| Fallback | 比較 DADA2 與 Merger 最高絕對豐度 | 失敗或停用時退回 | recommendation | 自動 |
| 報告生成 | ReportGenerator | Markdown | 檔案 | 可 (無 LLM 不生成) |
若 RuleAsJudge 已輸出唯一合法 ASV,LLM 層不執行。
- 檔案位置:
src/llm/analyzer.py - 主要功能: 取得兩來源(DADA2 merged, Merger final)差異點與品質特徵,建構 prompt,解析回應,不產生新“合併”序列;支援多數決投票以提升穩定性。
- 輸入驗證: 依
_validate_analysis_data()的實作,送入 LLM 必須同時滿足:- 具備
merger_merged與dada2_merged任一合併結果的序列(兩者皆需存在) - 具備
merger_r1ref與merger_r2ref之參考序列(第二條序列為 ref) 若不滿足,該樣本會被標記為 failed 並跳過 LLM。
- 具備
- 關鍵方法:
analyze_sample(): (序列提取→差異摘要→品質整合→prompt→LLM→解析→報告)_build_analysis_prompt(): XML/文字格式 prompt 建構_prepare_analysis_data(): 分析資料預處理_parse_analysis_result():單次回應解析(向下相容)_parse_analysis_result_with_majority_vote():多數決回應解析_execute_llm_analysis_with_majority_vote(): 多輪請求與逐輪 log_apply_majority_vote(): 投票統計、平均信心度與共識摘要_write_majority_vote_summary(): 多數決摘要 JSON 輸出_write_prompt_log_with_run_index(): 每輪 prompt/response JSON 紀錄
- 檔案位置:
src/llm/llm_client.py - 功能: OpenAI 相容 API 封裝,支援多種 LLM 模型
- 支援: 同步與異步 streaming 調用,錯誤處理與重試機制
- 檔案位置:
src/llm/data_loader.py - 功能: 從結果資料中提取序列和 QC 資料,支援多種序列來源
- 檔案位置:
src/llm/report_generator.py - 功能: 統一的 Markdown 報告生成,包含分析結果與推薦理由
- 檔案位置:
src/llm/llm_pipeline.py - 功能: LLM 分析管道簡化協調器,主要負責協調和批量處理操作
- 關鍵方法:
run_single_locus_analysis(): 單個 locus 的完整分析流程analyze_sample_streaming(): 前端 streaming 分析介面
推薦決策: SequenceRecommendationEngine → RuleAsJudge (過濾與計數) → (可選) LLMAnalysisPipeline → MergeAnalyzer → Report
# src/qc/recommendation_engine.py 中的實現
def _process_unified_arbitration(self, sample_id: str, sample_data: Dict[str, Any], rule: int) -> Dict[str, Any]:
"""
統一仲裁流程:先進行 rule-as-judge 品質過濾,
若篩出複數 ASVs 且前端勾選規則,則進入 LLM 仲裁。
"""
# 1. Rule-as-judge 品質過濾
rule_result = self.rule_judge.evaluate_sample(sample_data, sample_id)
# 2. 智慧化決策分流
if rule_result.decision != RuleDecision.INCONCLUSIVE:
# 唯一合法 ASV,直接推薦(不呼叫 LLM)
return self._create_direct_recommendation(rule_result)
# 3. 複數 ASVs → LLM 仲裁
if not self.config.llm_analysis_enabled:
# LLM 未啟用,使用 fallback
return self._select_highest_abundance_fallback(sample_id, sample_data, rule)
# 4. 進入 LLM 仲裁 (Top2 ASVs)
llm_pipeline = LLMAnalysisPipeline(self.config)
top_candidates = self._extract_top2_asvs_from_sample_data(sample_data)
result = llm_pipeline.run_single_sample_analysis(self.locus, sample_id)
return self._process_llm_result(sample_id, result, rule)特點:
- 統一流程:所有樣本都經過相同的
RuleAsJudge品質過濾。 - 規則驅動:當前端勾選了除了 rule3 以外的任何規則時,啟用統一仲裁流程。
- 智慧節省:
RuleAsJudge篩選出唯一結果時,避免不必要的 LLM API 調用。 - 品質保證:僅對通過基本品質標準的序列進行深度分析。
- 統計透明:詳細記錄每階段的處理數量與決策原因。
調用路徑: app.py → MergeAnalyzer → streaming LLM
# app.py 中的實現
@app.route('/llm_analysis', methods=['POST'])
def llm_analysis():
# 建立分析器
analyzer = MergeAnalyzer(llm_client=llm_client, log_dir=temp_dir)
# 準備分析資料
analysis_data = analyzer._prepare_analysis_data(sample_id, sequences, qc_data)
prompt = analyzer._build_analysis_prompt(analysis_data)
# 執行 streaming 分析
def generate():
for chunk in llm_client.stream_chat(prompt):
yield chunk
return Response(generate(), mimetype='text/plain')特點:
| 項目 | 現況 | 與自動仲裁差異 |
|---|---|---|
| 模式 | SSE streaming | 自動仲裁為函式呼叫 |
| 寫入 | 實時字串 | 自動仲裁只記錄最終結果 |
| 報告 | 可即時產出 | 自動仲裁 parse 後一次生成 |
| 用途 | 手動診斷 / demo | 生產決策鏈節點 |
| 狀態 | 條件 | 報告 | 推薦來源 | confidence 基準 |
|---|---|---|---|---|
| completed | JSON 解析成功 | 是 | JSON 指定來源 | JSON 或 0.7 預設 |
| completed_with_parsing_error | 有文字無法解析 JSON | 是 (含警告) | Fallback(比較最高絕對豐度) | 0.30 |
| error | HTTP / 連線 / API 內部 | 否 | Fallback(比較最高絕對豐度) | 0.30 |
| skipped_llm_disabled | flag False | 否 | Fallback(比較最高絕對豐度) | 0.30 |
| skipped_rule_judge_direct | rule as judge 直接決策 | 否 | judge 來源 | 0.8 / 0.6 |
| skipped_no_candidates | 0 passed sequences | 否 | manual_review | 0.1 |
completed_with_parsing_error與error都計入llm_fallback_count。
graph TB
subgraph "QC 模組 (Rule 3)"
QC[SequenceRecommendationEngine] --> LLMP[LLMAnalysisPipeline]
LLMP --> MA1[MergeAnalyzer]
MA1 --> QCResult[同步分析結果]
end
subgraph "前端 Streaming"
Frontend[前端請求] --> App[app.py]
App --> MA2[MergeAnalyzer]
MA2 --> StreamResult[異步流式回應]
end
subgraph "共用核心元件"
DataLoader[DataLoader<br/>資料載入器]
LLMClient[LLMClientWrapper<br/>LLM 客戶端]
ReportGen[ReportGenerator<br/>報告生成器]
end
MA1 --> DataLoader
MA1 --> LLMClient
MA1 --> ReportGen
MA2 --> DataLoader
MA2 --> LLMClient
MA2 --> ReportGen
sequenceDiagram
participant Caller as 調用者 (Rule3/Frontend)
participant DL as DataLoader
participant MA as MergeAnalyzer
participant LLM as LLMClientWrapper
participant RG as ReportGenerator
Caller->>DL: 載入樣本資料
DL-->>Caller: sequences + qc_data
Caller->>MA: analyze_sample(sample_id, sequences, qc_data)
MA->>MA: _prepare_analysis_data()
Note over MA: 提取序列資料<br/>(r1, r2, ref, merger, dada2)
MA->>MA: _build_analysis_prompt()
Note over MA: 建構 XML 格式 prompt<br/>包含 5 步驟分析任務
MA->>LLM: 發送 prompt (同步/異步)
LLM-->>MA: LLM 回應 (JSON 格式)
MA->>MA: _parse_analysis_result()
Note over MA: 解析 LLM JSON 回應<br/>構建分析結果物件
MA->>RG: 生成 Markdown 報告
RG-->>MA: 報告路徑
MA-->>Caller: 完整分析結果
| 層級 | 條件 | 行為 | 統計 | reasoning 註記 |
|---|---|---|---|---|
| Rule as judge | 0 passed | manual_review | quality_filter_rejected_count | "No sequences passed filtering" |
| Rule as judge | 1 passed | 直接推薦該來源 | direct_recommendation_count | "Exactly one ... passed filtering" |
| Rule as judge | 2+ passed & 前端未勾選 | Fallback(選豐度最高;conf=0.30) | fallback_no_llm_trigger_count | "Fallback: selected highest abundance ASV" |
| LLM pipeline | 2+ passed & 前端已勾選 | 進入 LLM 仲裁 | llm_available_count | "... sequences passed, sent to LLM" |
| LLM pipeline | llm disabled | Fallback(選豐度最高;conf=0.30) | llm_fallback_count | "LLM disabled fallback" |
| LLM pipeline | network / HTTP error | 同上 Fallback | llm_fallback_count | 簡述錯誤碼 |
| LLM pipeline | parsing error | 同上 Fallback + report | llm_fallback_count | "parsing error" |
| LLM pipeline | schema 缺失 | 同上 Fallback | llm_fallback_count | "invalid schema" |
| 場景 | Confidence |
|---|---|
| Rule-as-judge 篩選出單一來源 | 0.8 / 0.6 (依品質) |
| LLM 仲裁成功 (JSON) | JSON (clamp 0.3–0.9, default 0.7) |
| 所有 Fallback (LLM 失敗/未觸發) | 0.30 |
| manual_review | 0.1 |
clamp:若 LLM 提供 <0.3 → 0.3;>0.9 → 0.9。
{
"recommendation_source": "merger | dada2",
"confidence": 0.72,
"reasoning": "Merger higher blast identity, fewer ambiguous sites.",
"differential_observations": [
{"metric": "blast_identity", "merger": 0.985, "dada2": 0.962},
{"metric": "ambiguous_sites", "merger": 2, "dada2": 7}
],
"warnings": ["low_abundance_dada2"]
}解析守則:缺 recommendation_source → fallback;缺/非法 confidence → 0.7;來源不在 {merger,dada2} → fallback;differential_observations 可選。
flowchart LR
subgraph "輸入資料"
S1[R1 序列]
S2[R2 序列]
REF[參考序列]
MERGER[Merger 合併結果]
DADA2[DADA2 合併結果]
QC[QC 統計資料]
end
subgraph "MergeAnalyzer 處理"
subgraph "LLM 分析"
DIFF[序列差異分析]
QUAL[品質評估]
MERGE[智慧合併]
REC[結果推薦]
end
PREP[_prepare_analysis_data<br/>資料預處理]
PROMPT[_build_analysis_prompt<br/>XML 格式 prompt]
PARSE[_parse_analysis_result<br/>結果解析]
end
subgraph "輸出"
JSON[結構化分析結果]
MD[Markdown 報告]
LOG[Prompt 日誌]
end
S1 & S2 & REF & MERGER & DADA2 & QC --> PREP
PREP --> PROMPT
PROMPT --> DIFF & QUAL & MERGE & REC
DIFF & QUAL & MERGE & REC --> PARSE
PARSE --> JSON & MD & LOG
src/llm/analyzer.py- 核心分析引擎 (MergeAnalyzer,可重用於多種場景)src/llm/llm_pipeline.py- LLM 分析協調器 (LLMAnalysisPipeline)src/qc/recommendation_engine.py- QC 模組集成點 (Rule 3 調用)app.py- 前端 streaming 介面 (即時分析)
src/llm/data_loader.py- 資料載入與序列提取src/llm/llm_client.py- LLM 客戶端封裝src/llm/report_generator.py- 報告生成src/llm/llm_analysis_result.py- 分析結果物件定義
src/config/config_model.py- LLM 相關設定定義
LLM 模組相關設定在 PowerBarcoderConfig 中:
llm_analysis_enabled: bool = True
llm_model: str = "gpt-4"
llm_base_url: str = "https://api.openai.com/v1"
llm_api_key: str = "(env or user)"
llm_temperature: float = 0.3
llm_max_tokens: int = 4000在配置中新增或調整下列參數(對應 src/config/config_model.py 的 PowerBarcoderConfig):
# LLM 多數決投票設定
llm_majority_vote_count: 5 # 目標成功投票次數 (允許值: 1, 3, 5, 10)
llm_enable_json_log: true # 啟用詳細日誌記錄| 參數名稱 | 類型 | 預設值 | 說明 |
|---|---|---|---|
llm_majority_vote_count |
int | 1 | 目標成功次數。僅允許 {1, 3, 5, 10},否則會丟出 ValueError。系統會固定蒐集此數量份「有內容的回應」才開始多數決;若持續無法獲得有效回應,總嘗試次數不超過此數值的 3 倍(安全上限)。詳見 9.1 投票與正規化規則 說明。 |
llm_enable_json_log |
bool | true | 是否啟用 per-run 與摘要 JSON 日誌輸出。啟用後會在 log_dir 生成 {sample_id}_prompt_log_run*.json 與 {sample_id}_majority_vote_summary.json。 |
| 場景 | llm_majority_vote_count | llm_enable_json_log | 說明 |
|---|---|---|---|
| 快速/低成本模式 | 1 | false |
生產環境預設,追求速度與成本效益。 |
| 提升準確性 | 3 或 5 | true |
開發或對關鍵樣本進行複核時使用,平衡成本與穩定性。 |
| 研究分析模式 | 5 或 10 | true |
需要完整可解釋性與最高穩定性時使用,成本較高。 |
from src.qc.recommendation_engine import SequenceRecommendationEngine
# 建立推薦引擎(會自動初始化 LLM 分析管道)
engine = SequenceRecommendationEngine(
locus="COI_1",
result_data_path="/path/to/result",
config=config,
# 此處的 filter 僅用於分類,不影響仲裁流程
qc_rules_filter={'rule1': True, 'rule2': True, 'rule3': True}
)
# 執行推薦流程
# LLM 是否啟用取決於 config.llm_analysis_enabled_by_frontend
results = engine.run_recommendation_pipeline()# app.py 中的 /llm_analysis 端點會自動處理 streaming 調用
# 前端透過 POST 請求觸發,並接收 streaming 回應
# 範例請求:
# POST /llm_analysis
# Content-Type: application/json
#
# {
# "sample_id": "sample001",
# "locus": "COI_1",
# "result_data_path": "/path/to/result"
# }from src.llm.analyzer import MergeAnalyzer
from src.llm.llm_client import LLMClientWrapper
# 建立 LLM 客戶端
llm_client = LLMClientWrapper(
model="mistralai/mistral-small-2509",
base_url="https://api.mistral.ai/v1",
api_key="your-api-key"
)
# 建立分析器(使用多數決投票)
analyzer = MergeAnalyzer(
llm_client=llm_client,
log_dir="/tmp/llm_logs",
majority_vote_count=5, # 目標成功次數(允許值: 1, 3, 5, 10)
enable_json_log=True # 啟用詳細日誌
)
# 執行分析(會自動進行 5 次 LLM 運行並投票)
result = analyzer.analyze_sample(
sample_id="sample001",
sequences=sequences_dict,
qc_data=qc_data_dict
)
# 檢查結果
if result['status'] == 'completed':
majority_votes = result['majority_vote_details']['winning_votes']
total_votes = result['majority_vote_details']['valid_votes']
print(f"推薦來源: {result['llm_analysis']['selected_sequence_id']}")
print(f"信心度: {result['llm_analysis']['confidence']:.3f}")
print(f"投票結果: {majority_votes}/{total_votes}")
print(f"推薦理由: {result['llm_analysis']['reasoning']}")
else:
print(f"分析失敗: {result['error']}")症狀: LLMClientWrapper 建立失敗 解決方案: 檢查 API key、base_url 可達性及模型名稱。
症狀: _parse_analysis_result 解析失敗 解決方案: 檢查 LLM 回應格式、查看 prompt 日誌、驗證 JSON 格式。
症狀: QC 流程中 LLM 分析失敗 解決方案: 確認 config.llm_analysis_enabled_by_frontend 設定、檢查序列資料完整性、驗證 LLM 服務可用性。
症狀: 程式啟動時報錯 ValueError: llm_majority_vote_count 必須為 [1, 3, 5, 10] 其中之一 解決方案: 請將 llm_majority_vote_count 調整為允許值之一。
症狀: 未生成 prompt_log 或 majority_vote_summary JSON 檔案 解決方案: 確認 log_dir 路徑存在且程式有寫入權限,並檢查磁碟空間。
透過對同一個樣本重複執行多次 LLM 分析,以投票方式選出最一致的推薦來源,並計算該來源的平均信心度,提升穩定性與可解釋性。
核心設計原則:
- 「有效投票」明確定義:一個 LLM 回應被視為有效投票當且僅當:
- HTTP 請求成功(收到回應內容)
- JSON 解析成功
selected_sequence_id為有效值(dada2_top1,dada2_top2,merger_top1,merger_top2等,不含逗號或其他異常格式)
- 收集足夠有效投票後立即停止:當收集到
majority_vote_count個有效投票後,執行提前停止 - 安全上限:最大嘗試次數為
majority_vote_count * 2,避免無限重試
執行步驟:
- 執行 LLM 呼叫 -
_execute_llm_analysis_with_majority_vote()- 目標:收集
majority_vote_count個有效投票 - 每次呼叫後立即驗證是否為有效投票(
_is_valid_vote()) - 有效投票計入
valid_votes;無效回應不計入但會記錄於日誌
- 目標:收集
- 提前停止檢查 - 每次呼叫後檢查
- 若
valid_votes >= majority_vote_count→ 停止執行 - 否則繼續嘗試,直到達最大嘗試次數
- 若
- 多數決投票 -
_apply_majority_vote()- 只處理標記為有效投票的回應
- 統計各選項得票數
- 選擇得票最多者,計算平均信心度
| 指標 | 說明 | 舉例 |
|---|---|---|
target_votes |
目標有效投票數(配置值) | 5 |
total_attempts |
實際嘗試次數 | 6 |
valid_votes |
有效投票數 | 5 |
invalid_attempts |
無效嘗試數(total_attempts - valid_votes) |
1 |
設計哲學:在完全內部可控的系統中,簡化錯誤處理。只區分「有效」與「無效」兩種狀態,無需更細的錯誤分類。
- 若達最大嘗試次數仍無法收集足夠有效投票 → 使用已有的有效投票進行多數決(若 >= 1)
- 若完全沒有有效投票 → LLM 分析狀態為
failed,回退至 Fallback(最高豐度)
graph TD
Start["開始分析<br/>(analyze_sample)"] --> PrepData["_prepare_analysis_data<br/>準備分析資料"]
PrepData --> ValidData{"資料驗證"}
ValidData -->|失敗| ErrResult["返回 error 結果"]
ValidData -->|成功| BuildPrompt["_build_analysis_prompt<br/>建構 XML prompt"]
BuildPrompt --> ExecuteVote["_execute_llm_analysis_with_majority_vote<br/>目標:收集 N 個有效投票"]
ExecuteVote --> RunLoop["FOR 每個 attempt (0 to max_attempts-1)"]
RunLoop --> CallLLM["_execute_llm_analysis<br/>調用 LLM API"]
CallLLM --> CheckResp{"回應接收?"}
CheckResp -->|否| MarkInvalid["is_valid_vote = false<br/>記錄 API 失敗"]
CheckResp -->|是| ValidateVote["_is_valid_vote<br/>驗證有效投票<br/>(JSON解析 + selected_id 有效)"]
ValidateVote --> CheckValid{"有效投票?"}
CheckValid -->|否| MarkInvalid
CheckValid -->|是| MarkValid["is_valid_vote = true<br/>valid_votes += 1"]
MarkInvalid --> WriteLog["_write_prompt_log_with_run_index<br/>記錄 prompt/response 日誌"]
MarkValid --> WriteLog
WriteLog --> CheckEarlyStop{"valid_votes >= target?"}
CheckEarlyStop -->|是| CollectResults["收集所有回應<br/>(提前停止)"]
CheckEarlyStop -->|否| CheckMaxAttempts{"達最大嘗試次數?"}
CheckMaxAttempts -->|否| RunLoop
CheckMaxAttempts -->|是| CollectResults
CollectResults --> CheckSuccess{"有有效投票?"}
CheckSuccess -->|否| AllFailed["返回 failed<br/>(所有嘗試無效)"]
CheckSuccess -->|是| ApplyVote["_apply_majority_vote<br/>計算多數決<br/>- 統計有效投票的選擇分布<br/>- 選擇得票最多者<br/>- 計算平均信心度"]
ApplyVote --> WriteSummary["_write_majority_vote_summary<br/>寫入 majority_vote_summary.json"]
WriteSummary --> ReturnResult["返回完整分析結果"]
ReturnResult --> End["結束"]
ErrResult --> End
AllFailed --> End
啟用 llm_enable_json_log: true 且 MergeAnalyzer(log_dir=...) 提供路徑後,會寫入兩類 JSON:
- Per-run 檔名:
{sample_id}_prompt_log_run{N}.json- 欄位:
sample_id、run_index、target_votes、timestamp、prompt_content、response_content、is_valid_vote、error等。
- 欄位:
- 摘要檔名:
{sample_id}_majority_vote_summary.json-
核心結構:
{ "sample_id": "...", "timestamp": "YYYY-MM-DD HH:mm:ss", "target_votes": 5, // 目標有效投票數 "total_attempts": 6, // 實際嘗試次數 "valid_votes": 5, // 有效投票數 "invalid_attempts": 1, // 無效嘗試數 "all_runs": [ { "run_number": 1, "is_valid_vote": true, "selected_sequence_id": "merger_top1", "confidence": 0.88, "sequence_scores": {"dada2_top1": 0.8, "merger_top1": 0.9, ...}, "quality_assessment": {"dada2_strengths": [...], "merger_strengths": [...], ...}, "detailed_analysis": "...", "reasoning": "...", "raw_response_length": 2048 }, { "run_number": 2, "is_valid_vote": true, "selected_sequence_id": "merger_top1", "confidence": 0.85, "..." } ], "majority_result": { "selected_sequence_id": "merger_top1", "confidence": 0.877, # 獲勝選項的平均信心度 "vote_distribution": {"merger": 3, "dada2": 2}, # 各選項的得票分布 "winning_votes": 3, # 獲勝選項的得票數 "consensus_strengths": { # 多數決共識優勢(多個 runs 中共現的優勢) "dada2_strengths": ["...", "..."], "merger_strengths": ["...", "..."] }, "quality_assessment": { # 彙整的品質評估(多個 runs 的結合) "dada2_strengths": ["...", "..."], "merger_strengths": ["...", "..."], "abundance_factors": ["...", "..."] }, "reasoning": "... (多數決: 3/5 票,來自 runs: 1, 2, 4)" } } -
欄位說明:
majority_vote_count與total_runs用於理解執行計畫與實際情況successful_runs用於診斷有多少 runs 成功產生結果(只有這些參與投票)all_runs中每個運行的完整分析細節都被保留,供事後審查majority_result.consensus_strengths與quality_assessment是多個 runs 的共識彙整,增強了結果的可信度
-
| 主題 | 本文件 | 其他文件 |
|---|---|---|
| Rule 分類 | 僅用於最終標記,與仲裁流程脫鉤 | qc.md, locus_qc.md |
| Confidence | LLM / fallback 來源 | qc.md 總表 |
| RuleAsJudge | 品質過濾器與計數器 | locus_qc.md |
| 報告生成 | 詳細 | qc.md 簡述 |
| 路徑 | 入/出檔案 | path.md |
- QC 整合: 參考
docs/qc.md/docs/locus_qc.md - 前端 API: 參考
docs/frontend.md的 LLM 分析部分 - 配置管理: 參考
docs/config_flow.md