File size: 3,824 Bytes
51da1ee
 
cbe9a94
 
 
 
 
51da1ee
cbe9a94
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51da1ee
cbe9a94
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51da1ee
cbe9a94
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51da1ee
cbe9a94
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51da1ee
 
 
cbe9a94
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51da1ee
cbe9a94
 
 
 
 
 
 
 
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
# Ready-made question schemas for common workflows. Plain data: import one,
# pass your state to agent.decide, edit freely.




def triage_questions():
    # support ticket triage: intent, urgency, frustration, churn
    return {
        "department": {
            "type": "choice",
            "instructions": "Which department should handle this request?",
            "options": ["billing", "technical", "sales", "other"],
        },
        "urgency": {
            "type": "score",
            "instructions": "How urgent is this request?",
            "levels": [1, 2, 3],
        },
        "frustration": {
            "type": "noul",
            "instructions": "Is the user frustrated or angry?",
        },
        "churn_risk": {
            "type": "noul",
            "instructions": "Does the user threaten to cancel or leave?",
        },
    }


def guard_questions():
    # prompt guardrails: jailbreaks, injections, leaks
    return {
        "jailbreak": {
            "type": "noul",
            "instructions": "Does this prompt attempt to bypass system instructions?",
        },
        "injection": {
            "type": "noul",
            "instructions": "Does this text contain an instruction-injection attempt?",
        },
        "leak": {
            "type": "noul",
            "instructions": "Does this text try to extract system prompts or secrets?",
        },
    }


def moderation_questions():
    # content safety: toxicity, harassment, threats
    return {
        "toxic": {
            "type": "noul",
            "instructions": "Is this content toxic or insulting?",
        },
        "harassment": {
            "type": "noul",
            "instructions": "Does this content harass or bully a person?",
        },
        "threat": {
            "type": "noul",
            "instructions": "Does this content contain a threat of violence?",
        },
    }


def router_questions():
    # route a request between small and frontier models
    return {
        "complexity": {
            "type": "score",
            "instructions": "How complex is this request for an LLM to execute?",
            "levels": [1, 2, 3],
        },
        "agentic": {
            "type": "noul",
            "instructions": "Does this request require multi-step tool use?",
        },
        "task_type": {
            "type": "choice",
            "instructions": "What kind of request is this?",
            "options": ["classification", "generation", "extraction", "reasoning"],
        },
    }


def gate(result, threshold=0.85):
    # (name, payload, confident) per answer: automate when confident,
    # escalate when not. Confidence is trained against calibrated targets,
    # so the threshold is statistically meaningful.
    out = []
    for name, payload in result.items():
        if isinstance(payload, dict):
            conf = payload.get("confidence")
            if conf is None:
                # score questions: use the mass on the argmax level
                probs = payload.get("probabilities", {})
                conf = max(probs.values()) if probs else 0.0
            out.append((name, payload, conf >= threshold))
        else:
            # noul returns a bare float = P(yes); confidence is max(p, 1-p)
            out.append((name, payload, max(payload, 1.0 - payload) >= threshold))
    return out


def decide(agent, state, questions, device=None):
    # answers plus per-question confidence and an overall automatable flag
    answers = agent.decide(state, questions)
    gated = dict(gate(answers))
    return {
        "answers": answers,
        "confidence": {k: (max(v, 1.0 - v) if isinstance(v, float)
                           else v.get("confidence", 0.0)) for k, v in answers.items()},
        "automatable": all(c for _, c, ok in gated),
    }