filter_uncertain.py 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. import json, time, requests
  2. from pathlib import Path
  3. from concurrent.futures import ThreadPoolExecutor, as_completed
  4. BASE = Path("/opt/3cx-middleware/3cx-telefonie-middleware")
  5. SRC = BASE / "data/transcripts"
  6. SCREEN = BASE / "data/transcript_screening.jsonl"
  7. OUT = BASE / "data/transcript_relevance_final.jsonl"
  8. URL = "http://192.168.1.101:11434/api/chat"
  9. MODEL = "llama3.2:3b"
  10. WORKERS = 1
  11. SYSTEM = """Du klassifizierst ein Telefontranskript ausschließlich nach Relevanz.
  12. RELEVANT:
  13. Ein echter Dialog mit Kunde, Interessent, Lieferant oder Geschäftspartner.
  14. IRRELEVANT:
  15. reine Telefonansage, Mailbox, Warteschleife, Fehlanruf ohne Gespräch,
  16. Werbung oder praktisch kein Gespräch.
  17. UNCERTAIN:
  18. nicht eindeutig.
  19. Antworte ausschließlich mit JSON:
  20. {"relevance":"RELEVANT","confidence":0.0}
  21. oder
  22. {"relevance":"IRRELEVANT","confidence":0.0}
  23. oder
  24. {"relevance":"UNCERTAIN","confidence":0.0}
  25. """
  26. items = []
  27. for line in SCREEN.read_text(encoding="utf-8").splitlines():
  28. r = json.loads(line)
  29. if r["relevance"] == "UNCERTAIN":
  30. items.append(r["file"])
  31. print(f"UNCERTAIN: {len(items)}")
  32. def run(filename):
  33. text = (SRC / filename).read_text(
  34. encoding="utf-8", errors="replace"
  35. ).strip()
  36. payload = {
  37. "model": MODEL,
  38. "messages": [
  39. {"role": "system", "content": SYSTEM},
  40. {"role": "user", "content": text[:5000]}
  41. ],
  42. "stream": False,
  43. "think": False,
  44. "format": "json",
  45. "options": {"temperature": 0}
  46. }
  47. start = time.time()
  48. r = requests.post(URL, json=payload, timeout=120)
  49. r.raise_for_status()
  50. result = json.loads(r.json()["message"]["content"])
  51. return {
  52. "file": filename,
  53. "relevance": result.get("relevance", "UNCERTAIN"),
  54. "confidence": result.get("confidence", 0),
  55. "seconds": round(time.time() - start, 1)
  56. }
  57. with OUT.open("w", encoding="utf-8") as f:
  58. with ThreadPoolExecutor(max_workers=WORKERS) as pool:
  59. futures = [pool.submit(run, x) for x in items]
  60. for i, future in enumerate(as_completed(futures), 1):
  61. try:
  62. r = future.result()
  63. f.write(json.dumps(r, ensure_ascii=False) + "\n")
  64. f.flush()
  65. print(
  66. f"[{i}/{len(items)}] {r['file']} "
  67. f"{r['seconds']}s → {r['relevance']} "
  68. f"{r['confidence']}",
  69. flush=True
  70. )
  71. except Exception as e:
  72. print("ERROR:", e, flush=True)
  73. print("\nFertig:", OUT)