KennyOry commited on
Commit
5ae1040
·
verified ·
1 Parent(s): b5f0354

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +78 -24
app.py CHANGED
@@ -249,8 +249,8 @@ def web_search(query: str) -> tuple:
249
  content = snippet # Fallback на сниппет
250
 
251
  # Форматирование контента
252
- relevant_content = extract_relevant_solution(content, norm_data)
253
- combined_content += f"[[Источник {i+1}]] {title}\n{relevant_content}\n\n"
254
 
255
  # Сохранение источника
256
  source_data = {
@@ -303,6 +303,51 @@ def clean_response(response: str, sources: list) -> str:
303
 
304
  return response.strip()
305
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
306
 
307
  def process_query(prompt: str):
308
  try:
@@ -314,21 +359,28 @@ def process_query(prompt: str):
314
  message_queue.put(('log', f"⏏️ Извлечено: {json.dumps(norm_data, ensure_ascii=False)}"))
315
 
316
  search_query = norm_data['search_query']
317
- message_queue.put(('log', f"🔍 Провожу поиск по запросу: {search_query}"))
318
-
319
- # Получаем полный контент источников
320
- _, sources = web_search(search_query)
321
-
322
- # Формируем контент ТОЛЬКО из полных страниц, без сниппетов
323
- full_content = ""
324
- for i, source in enumerate(sources):
325
- full_content += f"[[Источник {i+1}]] {source['title']}\n{source['content']}\n\n"
326
-
327
- message_queue.put(('log', f"📚 Собрано: {len(full_content)} символов из {len(sources)} источников"))
328
 
329
- # Генерируем ответ сразу на основе полного контента
330
- message_queue.put(('log', "🧠 Генерирую ответ на основе полного контента источников..."))
331
- message_queue.put(('response_start', ""))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
332
 
333
  messages = [
334
  {"role": "system", "content": SYSTEM_PROMPT + f"""
@@ -336,17 +388,16 @@ def process_query(prompt: str):
336
  Бренд: {norm_data['brand']}
337
  Модель: {norm_data['model']}
338
  Ошибка: {norm_data['error_code']}
339
- Суть проблемы: {norm_data['problem_description']}
340
-
341
- ВАЖНО: Генерируй ответ ТОЛЬКО на основе предоставленных источников ниже.
342
- Не выдумывай информацию, которой нет в источниках.
343
-
344
- Источники:
345
- {full_content}
346
  """},
347
  {"role": "user", "content": f"Проблема: {prompt}"}
348
  ]
349
 
 
 
 
350
  full_response = ""
351
  for chunk in mistral_client.chat.stream(
352
  model=MISTRAL_MODEL,
@@ -359,8 +410,11 @@ def process_query(prompt: str):
359
  full_response += chunk_text
360
  message_queue.put(('response_chunk', chunk_text))
361
 
 
 
 
362
  # Очистка и форматирование ответа
363
- final_response = clean_response(full_response, sources)
364
 
365
  message_queue.put(('response_end', final_response))
366
  message_queue.put(('sources', json.dumps(sources)))
 
249
  content = snippet # Fallback на сниппет
250
 
251
  # Форматирование контента
252
+ cleaned_content = re.sub(r'\s+', ' ', content).strip()
253
+ combined_content += f"[[Источник {i+1}]] {title}\n{cleaned_content}\n\n"
254
 
255
  # Сохранение источника
256
  source_data = {
 
303
 
304
  return response.strip()
305
 
306
+ def verify_with_sources(response: str, sources: list) -> str:
307
+ """Проверяет соответствие ответа источникам с помощью LLM"""
308
+ try:
309
+ message_queue.put(('log', "🔍 Проверяю соответствие ответа источникам..."))
310
+
311
+ sources_text = "\n\n".join([
312
+ f"Источник {i+1} ({source['title']}):\n{source['content'][:1500]}"
313
+ for i, source in enumerate(sources)
314
+ ])
315
+
316
+ verification_prompt = f"""
317
+ Проверь соответствие решения источникам:
318
+
319
+ ### Ответ бота:
320
+ {response}
321
+
322
+ ### Источники:
323
+ {sources_text}
324
+
325
+ Правила проверки:
326
+ 1. Все шаги решения должны иметь подтверждение в источниках
327
+ 2. Детали замены должны точно соответствовать артикулам из источников
328
+ 3. Если в ответе есть шаги не из источников - удали их
329
+ 4. Если есть противоречия между источниками - укажи это в решении
330
+ 5. Если ошибки в кодах ошибок - исправь
331
+ 6. Сохрани оригинальную структуру ответа
332
+
333
+ Верни исправленный ответ.
334
+ """
335
+
336
+ verification = mistral_client.chat.complete(
337
+ model=MISTRAL_MODEL,
338
+ messages=[{"role": "user", "content": verification_prompt}],
339
+ max_tokens=2048,
340
+ temperature=0.1
341
+ )
342
+
343
+ verified_response = verification.choices[0].message.content
344
+ return verified_response.strip()
345
+
346
+ except Exception as e:
347
+ error_msg = f"❌ Ошибка верификации: {str(e)}"
348
+ message_queue.put(('log', error_msg))
349
+ return response
350
+
351
 
352
  def process_query(prompt: str):
353
  try:
 
359
  message_queue.put(('log', f"⏏️ Извлечено: {json.dumps(norm_data, ensure_ascii=False)}"))
360
 
361
  search_query = norm_data['search_query']
362
+ search_data, sources = web_search(search_query)
 
 
 
 
 
 
 
 
 
 
363
 
364
+ message_queue.put(('log', f"📚 Собрано: {len(search_data)} символов в {len(sources)} источнике(-ах)"))
365
+
366
+ message_queue.put(('log', f"⚙️ Определяю проблему"))
367
+ problem_response = mistral_client.chat.complete(
368
+ model=MISTRAL_MODEL,
369
+ messages=[
370
+ {"role": "system", "content": "Опиши СУТЬ проблемы в одном предложении. Только диагноз, без решений. Не более 12 слов. На русском."},
371
+ {"role": "user", "content": f"Запрос пользователя: {prompt}\nПоисковые данные:\n{search_data}"}
372
+ ],
373
+ max_tokens=150,
374
+ temperature=0.2
375
+ )
376
+ extracted_problem = problem_response.choices[0].message.content.strip()
377
+
378
+ if not extracted_problem or len(extracted_problem) < 5:
379
+ extracted_problem = f"Неисправность {norm_data['brand']} {norm_data['model']}"
380
+
381
+ message_queue.put(('log', f"🧩 Определённая проблема: {extracted_problem}"))
382
+
383
+ sources_text = "\n".join([f"[{i+1}] {s['title']} - {s['url']}" for i, s in enumerate(sources)])
384
 
385
  messages = [
386
  {"role": "system", "content": SYSTEM_PROMPT + f"""
 
388
  Бренд: {norm_data['brand']}
389
  Модель: {norm_data['model']}
390
  Ошибка: {norm_data['error_code']}
391
+ Суть проблемы (на основе поиска): {extracted_problem}
392
+ Данные поиска:
393
+ {search_data}
 
 
 
 
394
  """},
395
  {"role": "user", "content": f"Проблема: {prompt}"}
396
  ]
397
 
398
+ message_queue.put(('log', "🧠 На основе полученных данных генерирую ответ..."))
399
+ message_queue.put(('response_start', ""))
400
+
401
  full_response = ""
402
  for chunk in mistral_client.chat.stream(
403
  model=MISTRAL_MODEL,
 
410
  full_response += chunk_text
411
  message_queue.put(('response_chunk', chunk_text))
412
 
413
+ # Проверка соответствия источникам
414
+ verified_response = verify_with_sources(full_response, sources)
415
+
416
  # Очистка и форматирование ответа
417
+ final_response = clean_response(verified_response, sources)
418
 
419
  message_queue.put(('response_end', final_response))
420
  message_queue.put(('sources', json.dumps(sources)))