| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- """Creation gates used before and during deep decode."""
- from __future__ import annotations
- import json
- from typing import Any, Callable
- from core.llm import chat_json as default_chat_json
- from core.prompts import load_prompt
- from decode_content.models import GateResult
- GATE_ADMIT = load_prompt("gate_admit")
- GATE_REFUTE = load_prompt("gate_refute")
- GATE_TIEBREAK = load_prompt("gate_tiebreak")
- GATE_HOW_ADMIT = load_prompt("gate_how_admit")
- GATE_HOW_REFUTE = load_prompt("gate_how_refute")
- GATE_HOW_TIEBREAK = load_prompt("gate_how_tiebreak")
- GATE_WHY_REFUTE = load_prompt("gate_why_refute")
- ChatJsonFn = Callable[..., dict[str, Any]]
- def vote_bool(
- system: str,
- user: str,
- key: str,
- *,
- on_fail: bool,
- chat_json_fn: ChatJsonFn = default_chat_json,
- timeout: int = 90,
- ) -> bool:
- try:
- return bool(chat_json_fn(system, user, timeout=timeout).get(key))
- except Exception:
- return on_fail
- def creation_gate(read_text: str, *, chat_json_fn: ChatJsonFn = default_chat_json) -> GateResult:
- """Decide whether the read content is reusable creation knowledge."""
- v_admit = vote_bool(GATE_ADMIT, read_text, "in_scope", on_fail=True, chat_json_fn=chat_json_fn)
- v_refute = not vote_bool(GATE_REFUTE, read_text, "out_of_scope", on_fail=False, chat_json_fn=chat_json_fn)
- if v_admit == v_refute:
- return GateResult(
- passed=v_admit,
- reason=f"admit={v_admit}/refute={v_refute} 一致",
- details={"admit": v_admit, "refute": v_refute},
- )
- v_tie = vote_bool(GATE_TIEBREAK, read_text, "in_scope", on_fail=False, chat_json_fn=chat_json_fn)
- return GateResult(
- passed=v_tie,
- reason=f"admit={v_admit}/refute={v_refute} 分歧→裁决={v_tie}",
- details={"admit": v_admit, "refute": v_refute, "tiebreak": v_tie},
- )
- def chain_signals(steps: list[dict[str, Any]]) -> list[str]:
- sigs: list[str] = []
- outs = [(s.get("output") or "") for s in steps]
- independent_count = 0
- for idx, step in enumerate(steps):
- if idx == 0:
- continue
- step_input = step.get("input") or ""
- if not (("←" in step_input) or any(o and o[:4] in step_input for o in outs[:idx])):
- independent_count += 1
- if independent_count >= 2:
- sigs.append(f"{independent_count} 个后步的 input 未指向前步产出(各自起头)")
- for i in range(len(outs)):
- for j in range(i + 1, len(outs)):
- left, right = outs[i], outs[j]
- if left and right and (left in right or right in left):
- sigs.append(f"步骤{i + 1}与{j + 1}产出近义({left} / {right})")
- break
- return sigs
- def how_gate(knowledge: dict[str, Any], *, chat_json_fn: ChatJsonFn = default_chat_json) -> GateResult:
- payload = json.dumps(
- {
- "purpose": knowledge.get("purpose"),
- "steps": [
- {
- "input": step.get("input"),
- "方法": (step.get("directive") or "")[:300],
- "产出": step.get("output"),
- }
- for step in knowledge.get("steps", [])
- ],
- "代码信号": chain_signals(knowledge.get("steps", [])),
- },
- ensure_ascii=False,
- )
- v_admit = vote_bool(GATE_HOW_ADMIT, payload, "is_real_how", on_fail=True, chat_json_fn=chat_json_fn)
- v_refute = not vote_bool(GATE_HOW_REFUTE, payload, "is_fake", on_fail=False, chat_json_fn=chat_json_fn)
- if v_admit == v_refute:
- return GateResult(
- passed=v_admit,
- reason=f"admit={v_admit}/refute={v_refute} 一致",
- details={"admit": v_admit, "refute": v_refute},
- )
- v_tie = vote_bool(GATE_HOW_TIEBREAK, payload, "is_real_how", on_fail=False, chat_json_fn=chat_json_fn)
- return GateResult(
- passed=v_tie,
- reason=f"admit={v_admit}/refute={v_refute} 分歧→裁决={v_tie}",
- details={"admit": v_admit, "refute": v_refute, "tiebreak": v_tie},
- )
- def why_refute_gate(knowledge: dict[str, Any], *, chat_json_fn: ChatJsonFn = default_chat_json) -> GateResult:
- payload = json.dumps({"阐述": knowledge.get("阐述")}, ensure_ascii=False)
- try:
- result = chat_json_fn(GATE_WHY_REFUTE, payload, timeout=90)
- except Exception:
- return GateResult(passed=True, reason="API错误→保留", details={"not_why": False})
- not_why = bool(result.get("not_why"))
- verdict = str(result.get("verdict") or "")
- reason = str(result.get("reason") or "")
- return GateResult(
- passed=not not_why,
- reason=reason,
- details={"not_why": not_why, "verdict": verdict},
- )
|