Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -502,17 +502,108 @@ def analyze_quality(text, sentences, words, morphemes):
|
|
| 502 |
# βββββββββββββββββββββββββββββββββββββββββββββββ
|
| 503 |
LLM_JUDGES = [("openai/gpt-oss-120b","GPT-OSS 120B"),("qwen/qwen3-32b","Qwen3 32B"),("moonshotai/kimi-k2-instruct-0905","Kimi-K2")]
|
| 504 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 505 |
def llm_cross_check(text):
|
| 506 |
if not GROQ_KEY: return {"score":-1,"detail":{}}
|
| 507 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 508 |
votes=[]; rpt={}
|
| 509 |
for mid,mn in LLM_JUDGES:
|
| 510 |
resp,err = call_groq(mid,prompt)
|
| 511 |
if resp:
|
| 512 |
-
|
| 513 |
-
if
|
| 514 |
-
|
| 515 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 516 |
if votes: return {"score":int(sum(votes)/len(votes)),"detail":rpt}
|
| 517 |
return {"score":-1,"detail":rpt}
|
| 518 |
|
|
|
|
| 502 |
# βββββββββββββββββββββββββββββββββββββββββββββββ
|
| 503 |
LLM_JUDGES = [("openai/gpt-oss-120b","GPT-OSS 120B"),("qwen/qwen3-32b","Qwen3 32B"),("moonshotai/kimi-k2-instruct-0905","Kimi-K2")]
|
| 504 |
|
| 505 |
+
def _parse_ai_probability(raw_resp):
|
| 506 |
+
"""LLM μλ΅μμ AI νλ₯ (0~100)μ μΆμΆ. νκ΅μ΄/μμ΄ λ€μν νμ λμ."""
|
| 507 |
+
if not raw_resp: return -1
|
| 508 |
+
# 1. <think> νκ·Έ λΆλ¦¬
|
| 509 |
+
think_content = ''
|
| 510 |
+
think_m = re.search(r'<think>(.*?)</think>', raw_resp, flags=re.S)
|
| 511 |
+
if think_m: think_content = think_m.group(1)
|
| 512 |
+
resp = re.sub(r'<think>.*?</think>', '', raw_resp, flags=re.S).strip()
|
| 513 |
+
if not resp or len(resp) < 5:
|
| 514 |
+
resp = raw_resp # thinkλ§ μμΌλ©΄ μλ³Έ ν¬ν¨
|
| 515 |
+
|
| 516 |
+
# 2. νΉμ ν€μλ ν¨ν΄ (λμ μ°μ μμ β 첫 λ§€μΉ)
|
| 517 |
+
specific_patterns = [
|
| 518 |
+
r'AI\s*νλ₯ \s*[:οΌ]\s*(?:μ½\s*)?(\d+)\s*%?',
|
| 519 |
+
r'AI\s*[Pp]robability\s*[:οΌ]\s*(?:about|approximately?\s*)?(\d+)\s*%?',
|
| 520 |
+
r'[Pp]robability\s*(?:of\s*)?(?:being\s*)?AI\s*[:οΌ\-]\s*(?:about|approximately?\s*)?(\d+)\s*%?',
|
| 521 |
+
r'AI\s*(?:μμ±|μμ±|νμ )?\s*νλ₯ \s*[:οΌ]?\s*(?:μ½\s*)?(\d+)',
|
| 522 |
+
r'(?:Score|Rating|Confidence)\s*[:οΌ]\s*(\d+)',
|
| 523 |
+
r'(\d+)\s*%\s*(?:μ\s*)?(?:νλ₯ |κ°λ₯μ±|probability|likely|chance|likelihood)',
|
| 524 |
+
r'(?:μ λ’°λ|νμ λ)\s*[:οΌ]?\s*(?:μ½\s*)?(\d+)\s*(?:%|νΌμΌνΈ)',
|
| 525 |
+
r'(?:μ½\s*)?(\d+)\s*(?:%|νΌμΌνΈ)\s*(?:μ λ|μμ€)',
|
| 526 |
+
]
|
| 527 |
+
for pat in specific_patterns:
|
| 528 |
+
m = re.search(pat, resp, re.I)
|
| 529 |
+
if m:
|
| 530 |
+
v = int(m.group(1))
|
| 531 |
+
if 0 <= v <= 100: return v
|
| 532 |
+
|
| 533 |
+
# 3. λ²μ© ν¨ν΄ β λ§μ§λ§ 5μ€μμλ§ κ²μ (ν΅κ³ μμΉ μ€ν λ°©μ§)
|
| 534 |
+
lines = [l.strip() for l in resp.strip().split('\n') if l.strip()]
|
| 535 |
+
for line in reversed(lines[-5:]):
|
| 536 |
+
# λΌμΈμ AI/νλ₯ /probability ν€μλκ° μμΌλ©΄ μ°μ
|
| 537 |
+
if re.search(r'AI|νλ₯ |[Pp]robab|μ λ’°|ν[μ λ¨]', line):
|
| 538 |
+
nums = re.findall(r'(\d+)\s*%', line)
|
| 539 |
+
if nums:
|
| 540 |
+
v = int(nums[-1])
|
| 541 |
+
if 0 <= v <= 100: return v
|
| 542 |
+
nums = re.findall(r'(\d+)\s*νΌμΌνΈ', line)
|
| 543 |
+
if nums:
|
| 544 |
+
v = int(nums[-1])
|
| 545 |
+
if 0 <= v <= 100: return v
|
| 546 |
+
|
| 547 |
+
# 4. μ 체 ν
μ€νΈμμ λ§μ§λ§ XX% (λ¨, AI/νλ₯ κ·Όμ²λ§)
|
| 548 |
+
all_pcts = list(re.finditer(r'(\d+)\s*(?:%|νΌμΌνΈ|percent)', resp, re.I))
|
| 549 |
+
for m in reversed(all_pcts):
|
| 550 |
+
v = int(m.group(1))
|
| 551 |
+
# μ£Όλ³ 50μ λ΄μ AI/νλ₯ ν€μλ μλμ§
|
| 552 |
+
ctx_start = max(0, m.start()-50)
|
| 553 |
+
ctx = resp[ctx_start:m.end()+20]
|
| 554 |
+
if re.search(r'AI|νλ₯ |[Pp]robab|μ λ’°|ν[μ λ¨]|κ°λ₯μ±|likelihood', ctx, re.I):
|
| 555 |
+
if 0 <= v <= 100: return v
|
| 556 |
+
|
| 557 |
+
# 5. μ΅ν μλ¨: μ 체μμ λ§μ§λ§ XX%
|
| 558 |
+
if all_pcts:
|
| 559 |
+
v = int(all_pcts[-1].group(1))
|
| 560 |
+
if 5 <= v <= 99: return v # 100% μ μΈ (ν΅κ³ μμΉ μ€ν λ°©μ§)
|
| 561 |
+
|
| 562 |
+
# 6. think λ΄λΆ ν΄λ°± (λ³Έλ¬Έ νμ± μ€ν¨ μ)
|
| 563 |
+
if think_content:
|
| 564 |
+
for pat in specific_patterns:
|
| 565 |
+
m = re.search(pat, think_content, re.I)
|
| 566 |
+
if m:
|
| 567 |
+
v = int(m.group(1))
|
| 568 |
+
if 0 <= v <= 100: return v
|
| 569 |
+
# think λ΄λΆ λ§μ§λ§ XX%
|
| 570 |
+
think_pcts = re.findall(r'(\d+)\s*%', think_content)
|
| 571 |
+
if think_pcts:
|
| 572 |
+
v = int(think_pcts[-1])
|
| 573 |
+
if 5 <= v <= 99: return v
|
| 574 |
+
|
| 575 |
+
return -1
|
| 576 |
+
|
| 577 |
def llm_cross_check(text):
|
| 578 |
if not GROQ_KEY: return {"score":-1,"detail":{}}
|
| 579 |
+
# νκ΅μ΄+μμ΄ λ³ν ν둬ννΈ (GPT-OSSλ μμ΄ λͺ¨λΈμ΄λ―λ‘)
|
| 580 |
+
prompt = f"""Analyze whether this text was written by AI.
|
| 581 |
+
|
| 582 |
+
[Instructions]
|
| 583 |
+
1. Determine AI vs Human with 3 brief reasons
|
| 584 |
+
2. IMPORTANT - Your LAST line MUST be exactly this format:
|
| 585 |
+
AIνλ₯ : XX%
|
| 586 |
+
(Replace XX with your estimated probability 0-100)
|
| 587 |
+
|
| 588 |
+
Example of correct last line:
|
| 589 |
+
AIνλ₯ : 75%
|
| 590 |
+
|
| 591 |
+
[Text to analyze]
|
| 592 |
+
{text[:2000]}"""
|
| 593 |
+
|
| 594 |
votes=[]; rpt={}
|
| 595 |
for mid,mn in LLM_JUDGES:
|
| 596 |
resp,err = call_groq(mid,prompt)
|
| 597 |
if resp:
|
| 598 |
+
p = _parse_ai_probability(resp)
|
| 599 |
+
if p >= 0:
|
| 600 |
+
votes.append(p); rpt[mn]=f"{p}%"
|
| 601 |
+
else:
|
| 602 |
+
# λλ²κ·Έ: think μ κ±° ν μλ΅ λλΆλΆ
|
| 603 |
+
cleaned = re.sub(r'<think>.*?</think>', '', resp, flags=re.S).strip()
|
| 604 |
+
tail = cleaned[-60:].replace('\n',' ') if len(cleaned) > 60 else cleaned.replace('\n',' ')
|
| 605 |
+
rpt[mn]=f"νμ±μ€ν¨({tail[:40]})"
|
| 606 |
+
else: rpt[mn]=f"ERR:{err[:30] if err else '?'}"
|
| 607 |
if votes: return {"score":int(sum(votes)/len(votes)),"detail":rpt}
|
| 608 |
return {"score":-1,"detail":rpt}
|
| 609 |
|