File size: 6,079 Bytes
5539560 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
import pandas as pd
from datetime import datetime
import json
from typing import List, Dict
from langchain_core.messages import HumanMessage, AIMessage
from langchain_core.tracers import BaseTracer
from dataclasses import dataclass, asdict
import plotly.express as px
import streamlit as st
@dataclass
class ChatAnalysis:
timestamp: str
user_input: str
bot_response: str
context: str
kb_version: str
response_time: float
tokens_used: int
context_relevance_score: float
class ChatAnalyzer(BaseTracer):
def __init__(self):
super().__init__()
self.analyses: List[ChatAnalysis] = []
def load_logs(self, log_file_path: str) -> List[Dict]:
"""Загрузка и парсинг логов чата из JSON файла"""
logs = []
with open(log_file_path, 'r', encoding='utf-8') as f:
for line in f:
try:
logs.append(json.loads(line.strip()))
except json.JSONDecodeError:
continue
return logs
def analyze_interaction(self, log_entry: Dict) -> ChatAnalysis:
"""Анализ одного взаимодействия в чате"""
# Расчет базовых метрик
timestamp = datetime.fromisoformat(log_entry["timestamp"])
# Расчет времени ответа (можно заменить на реальную логику измерения)
response_time = len(log_entry["bot_response"]) * 0.01 # Простая аппроксимация
# Подсчет использованных токенов (заменить на реальный подсчет)
tokens_used = len(log_entry["bot_response"].split()) + len(log_entry["user_input"].split())
# Расчет релевантности контекста
context_relevance = self._calculate_context_relevance(
log_entry["user_input"],
log_entry["context"],
log_entry["bot_response"]
)
return ChatAnalysis(
timestamp=timestamp.isoformat(),
user_input=log_entry["user_input"],
bot_response=log_entry["bot_response"],
context=log_entry["context"],
kb_version=log_entry["kb_version"],
response_time=response_time,
tokens_used=tokens_used,
context_relevance_score=context_relevance
)
def _calculate_context_relevance(self, query: str, context: str, response: str) -> float:
"""Расчет оценки релевантности между запросом и предоставленным контекстом"""
# Простая реализация - можно заменить на более сложную систему оценки
query_terms = set(query.lower().split())
context_terms = set(context.lower().split())
response_terms = set(response.lower().split())
query_context_overlap = len(query_terms & context_terms)
context_response_overlap = len(context_terms & response_terms)
if not query_terms or not context_terms:
return 0.0
return (query_context_overlap + context_response_overlap) / (len(query_terms) + len(context_terms))
def create_analysis_dashboard(self):
"""Создание дашборда анализа чата в Streamlit"""
st.title("Панель анализа чата")
# Преобразование анализа в DataFrame
df = pd.DataFrame([asdict(a) for a in self.analyses])
# Базовая статистика
st.header("Обзор")
col1, col2, col3, col4 = st.columns(4)
with col1:
st.metric("Всего взаимодействий", len(df))
with col2:
st.metric("Среднее время ответа", f"{df['response_time'].mean():.2f}с")
with col3:
st.metric("Средняя релевантность контекста", f"{df['context_relevance_score'].mean():.2%}")
with col4:
st.metric("Всего использовано токенов", df['tokens_used'].sum())
# Анализ временных рядов
st.header("Тренды взаимодействий")
df['timestamp'] = pd.to_datetime(df['timestamp'])
fig = px.line(df, x='timestamp', y='response_time', title='Время ответа с течением времени')
st.plotly_chart(fig)
# Распределение релевантности контекста
fig = px.histogram(df, x='context_relevance_score',
title='Распределение оценок релевантности контекста',
nbins=20)
st.plotly_chart(fig)
# Детальные логи
st.header("Детальные логи взаимодействий")
st.dataframe(df)
def setup_chat_analysis():
"""Инициализация и настройка системы анализа чата"""
analyzer = ChatAnalyzer()
# Добавление к существующему логированию
def enhanced_log_interaction(user_input: str, bot_response: str, context: str):
# Ваш существующий код логирования
log_interaction(user_input, bot_response, context)
# Добавление анализа
log_entry = {
"timestamp": datetime.now().isoformat(),
"user_input": user_input,
"bot_response": bot_response,
"context": context,
"kb_version": st.session_state.kb_info['version']
}
analysis = analyzer.analyze_interaction(log_entry)
analyzer.analyses.append(analysis)
return analyzer, enhanced_log_interaction |