trandangduc0's picture
Upload app.py
fa928ca verified
import gradio as gr
import json
import os
import re
from collections import Counter
# ── CONFIG ───────────────────────────────────────────────────────────────────
KB_PATH = "knowledge_base_v4.json"
# Load knowledge base
with open(KB_PATH, "r", encoding="utf-8") as f:
KB = json.load(f)
PATTERNS = KB.get("by_pattern", {})
FAILURE_KEYS = KB.get("by_failure_key", {})
LOOKUP = KB.get("lookup", {})
# ── FUZZY SEARCH ───────────────────────────────────────────────────────────────
def find_best_pattern(query):
"""Tìm pattern phù hợp nhất với query của user"""
query = query.upper()
# 1. Exact match
for pattern in PATTERNS:
if pattern.upper() == query:
return pattern, 1.0
# 2. Substring match
for pattern in PATTERNS:
if pattern.upper() in query or query in pattern.upper():
return pattern, 0.9
# 3. Keyword matching
query_words = set(re.findall(r'\b[A-Z]{2,}\b', query))
best_match = None
best_score = 0
for pattern in PATTERNS:
pattern_words = set(re.findall(r'\b[A-Z]{2,}\b', pattern.upper()))
if not pattern_words:
continue
common = query_words & pattern_words
score = len(common) / max(len(query_words), len(pattern_words))
if score > best_score:
best_score = score
best_match = pattern
if best_score >= 0.3:
return best_match, best_score
# 4. Failure key matching
for fk in FAILURE_KEYS:
if fk.upper() in query:
return fk, 0.5 # Return failure key for broad matching
return None, 0
# ── RESPONSE BUILDER ─────────────────────────────────────────────────────────
def build_response(query):
"""Xây dựng phản hồi từ knowledge base"""
pattern, score = find_best_pattern(query)
if not pattern:
return "Không tìm thấy thông tin phù hợp. Vui lòng mô tả lỗi chi tiết hơn (ví dụ: 'lỗi channel 53', 'TRIP PE TEM', 'DDR failed')."
# Get entry
if pattern in PATTERNS:
entry = PATTERNS[pattern]
elif pattern in FAILURE_KEYS:
entry = FAILURE_KEYS[pattern]
else:
return "Lỗi: Không tìm thấy dữ liệu."
# Build response
lines = []
lines.append(f"## Phân tích lỗi: {pattern}")
lines.append(f"")
lines.append(f"- **Tổng cases:** {entry['total_cases']}")
lines.append(f"- **Pass rate:** {entry['pass_rate']}%")
lines.append(f"- **Pass:** {entry['pass_count']} | **Fail:** {entry['fail_count']}")
lines.append(f"- **Board types:** {', '.join(entry.get('board_types', []))}")
lines.append(f"")
# BKM Procedure
bkm_procs = entry.get('bkm_procedures', [])
if bkm_procs:
lines.append(f"## Quy trình BKM")
for proc in bkm_procs[:3]:
lines.append(f"- {proc}")
lines.append(f"")
# BKM Components
bkm_comps = entry.get('bkm_components', [])
if bkm_comps:
lines.append(f"## Linh kiện theo BKM")
lines.append(f"- {', '.join(bkm_comps[:10])}")
lines.append(f"")
# Priority Replace
priority = entry.get('priority_replace', [])
if priority:
lines.append(f"## Thống kê - Linh kiện thay nhiều nhất")
lines.append(f"| Rank | Linh kiện | Pass Rate | Số lần thay | Pass | Fail |")
lines.append(f"|------|-----------|-----------|-------------|------|------|")
for i, p in enumerate(priority[:10], 1):
lines.append(f"| {i} | {p['component']} | {p['pass_rate']}% | {p['count']} | {p['pass']} | {p['fail']} |")
lines.append(f"")
# Best Actions
best_actions = entry.get('best_actions', [])
if best_actions:
lines.append(f"## Hành động hiệu quả nhất")
lines.append(f"| Rank | Hành động | Linh kiện | Pass Rate | Số lần | Pass | Fail |")
lines.append(f"|------|-----------|-----------|-----------|--------|------|------|")
for i, a in enumerate(best_actions[:10], 1):
lines.append(f"| {i} | {a['action']} | {a['component']} | {a['pass_rate']}% | {a['count']} | {a['pass']} | {a['fail']} |")
lines.append(f"")
# Top Technicians
techs = entry.get('top_technicians', [])
if techs:
lines.append(f"## Kỹ thuật viên tốt nhất")
lines.append(f"| Rank | Tên | Pass Rate | Tổng cases | Pass |")
lines.append(f"|------|-----|-----------|------------|------|")
for i, t in enumerate(techs[:5], 1):
lines.append(f"| {i} | {t['name']} | {t['pass_rate']}% | {t['total']} | {t['pass']} |")
lines.append(f"")
# Sample descriptions
samples = entry.get('sample_original_descriptions', [])
if samples:
lines.append(f"## Ví dụ mô tả lỗi tương tự")
for s in samples:
lines.append(f"- {s}")
lines.append(f"")
lines.append(f"---")
lines.append(f"*Độ chính xác tìm kiếm: {int(score*100)}%*")
return "\n".join(lines)
# ── GRADIO UI ────────────────────────────────────────────────────────────────
def chat(message, history):
"""Chat function for Gradio"""
response = build_response(message)
return response
# Create interface
demo = gr.ChatInterface(
fn=chat,
title="HDMT Debug Assistant v4",
description="Chatbot hỗ trợ debug HDMT boards. Mô tả lỗi để nhận phân tích và hướng dẫn.",
examples=[
"lỗi channel 53",
"TRIP PE TEM",
"DDR failed",
"blue screen",
"ADATE error",
"FPGA calibration",
"MISSING J18",
],
)
if __name__ == "__main__":
demo.launch()