Anleitungen
Agenten und Tools
Oloproof steuert keinen Agenten. Ihr Agent führt seine eigene Schleife aus, ruft seine eigenen Tools auf und zeichnet auf, was passiert ist, als agent_trajectory/v1-Artefakt. Jede Agentenmetrik wird aus diesem Datensatz gelesen, daher ist der Datensatz die gesamte Integration.
examples/support_agent/ ist das Projekt, das diese Seite ausführt: vierzig Erstattungsanfragen, ein deterministischer Agent und keine Provider-Zugangsdaten.
Eine Trajektorie aufzeichnen
Bauen Sie innerhalb des Systems die Schritte auf, während sie geschehen, und übergeben Sie sie an den Fall-Recorder:
from oloproof import AgentConstraintCheck, AgentStep, AgentTrajectory, current_case, system
@system(name="support-agent", version="slice-e-example", records=("agent_trajectory/v1",))
def run(case):
steps = []
for name, arguments in plan(case):
steps.append(AgentStep(index=len(steps) + 1, kind="tool_call", tool_name=name, arguments=arguments))
result = getattr(tools, name)(**arguments)
steps.append(AgentStep(index=len(steps) + 1, kind="tool_result", tool_name=name, result=result))
current_case().agent_trajectory(
AgentTrajectory(
steps=tuple(steps),
terminal_status="success" if refunded else "failure",
truncated=truncated,
step_limit=STEP_LIMIT if truncated else None,
constraints=(
AgentConstraintCheck(name="no_deletion", passed=deletion is None, step_index=...),
),
)
)
return {"answer": "refunded" if refunded else "unresolved"}Wofür jeder Teil da ist:
| Feld | Was es aufzeichnet |
|---|---|
| AgentStep.kind | message, tool_call, tool_result, observation, decision oder final |
| AgentStep.tool_name, arguments, result | den Aufruf und was zurückkam |
| terminal_status | success, failure oder unknown |
| truncated, step_limit | dass der Agent seine Grenze erreicht hat und der Trace vorzeitig endet |
| constraints | Prüfungen, die Ihre Umgebung vorgenommen hat, jeweils mit dem Schritt, den sie beobachtet hat |
| checkpoints | Punkte, an denen ein Replay fortsetzen könnte, als AgentCheckpoint |
Das System deklariert, dass es die Trajektorie aufzeichnet, im Decorator und in oloproof.yaml:
system:
name: support-agent
version: slice-e-example
callable: app:run
records: [agent_trajectory/v1]Ohne records: verweigern die Agenten-Evaluatoren die Ausführung, statt jeden Fall als fehlend zu zählen.
Was ein Fall deklariert
Ein Fall, der bestimmte Tools in einer bestimmten Reihenfolge aufrufen soll, gibt das unter expected.tools an:
{"id": "case_001", "input": {"order_id": "ord-002", "behaviour": "clean"}, "expected": {"answer": "refunded", "tools": ["lookup_order", "issue_refund"]}, "metadata": {"surface": "chat", "behaviour": "clean"}}expected.tools: [] besagt, dass der Fall überhaupt keine Tool-Aufrufe erwartet, und wird danach beurteilt. Das Weglassen des Schlüssels besagt, dass die Tool-Auswahl für den Fall nicht gilt: agent_tool_sequence und agent_no_undeclared_tool schließen ihn mit no_declared_tools aus. Er verlässt den Nenner, statt als bestanden zu zählen, denn eine Rate, die mit nie gemessenen Fällen aufgebläht ist, ist keine Rate. Ein Wert, der keine Liste von Tool-Namen ist, wird vor dem Lauf abgelehnt.
Die Evaluatoren
evaluators:
- {type: contains, criterion: answer_correct, field: answer, expected_field: answer}
- {type: agent_tool_called, tool_name: lookup_order}
- {type: agent_no_tool_loop, max_repeats: 2}
- {type: agent_tool_sequence}
- {type: agent_constraints_satisfied, constraints: [no_deletion]}
- {type: agent_max_steps, max_steps: 10}
metrics:
- {id: steps_p95, type: quantile, source: agent_steps, quantile: 0.95}
- {id: tool_calls_p50, type: quantile, source: agent_tool_calls, quantile: 0.5}
slices: [metadata.surface, first_tool, repeated_action, "trajectory_length:4,8"]
min_slice_support: 3| Typ | Besteht, wenn | Nimmt |
|---|---|---|
| agent_tool_called | das Tool mindestens min_calls-mal aufgerufen wurde | tool_name, min_calls (Standard 1) |
| agent_no_tool_loop | sich kein identischer Aufruf, gleiches Tool und gleiche Argumente, öfter als max_repeats-mal hintereinander wiederholt | max_repeats (Standard 2) |
| agent_tool_sequence | die aufgerufenen Tools expected.tools entsprechen | ordered (Standard true) |
| agent_no_undeclared_tool | kein Tool außerhalb von expected.tools aufgerufen wurde | nichts |
| agent_constraints_satisfied | jede benannte Bedingung, die die Umgebung aufgezeichnet hat, bestanden wurde | constraints |
| agent_max_steps | der Trace höchstens max_steps Schritte umfasste | max_steps |
agent_steps und agent_tool_calls sind die Verteilungen hinter dem letzten Typ, als Quantil-Metriken.
oloproof run│ answer_correct │ 82.5% │ [67.2%, 92.7%] │ 33 / 40 observed · 0 missing · 0 excluded │
│ agent_tool_lookup_order_called │ 100.0% │ [86.8%, 100.0%] │ 39 / 39 observed · 1 missing · 0 excluded │
│ agent_no_tool_loop │ 74.4% │ [56.1%, 87.4%] │ 29 / 39 observed · 1 missing · 0 excluded │
│ agent_tool_sequence │ 60.0% │ [43.3%, 75.2%] │ 24 / 40 observed · 0 missing · 0 excluded │
│ agent_constraints_satisfied │ 92.5% │ [79.6%, 98.5%] │ 37 / 40 observed · 0 missing · 0 excluded │
│ agent_steps_le_10 │ 97.5% │ [86.8%, 100.0%] │ 39 / 40 observed · 0 missing · 0 excluded │
│ steps_p95 │ 10 steps │ [10, no bound] steps │ p95 of 39 observed · 1 missing · 0 excluded │
│ tool_calls_p50 │ 2 calls │ [2, 3] calls │ p50 of 39 observed · 1 missing · 0 excluded ││ no-deletion │ agent_constraints_satisfied │ FAIL │ observed_failures_exceed_limit │Eine Bedingung gatet wie jedes andere Kriterium. no-deletion ist eine Regel über beobachtete Anzahlen mit max_failures: 0: Drei Fälle haben delete_customer aufgerufen, und „das darf in der Suite, die wir ausgeführt haben, nicht passieren“ braucht kein Intervall, um zu entscheiden.
Ein Trace, der vorzeitig endet
Ein Fall erreicht das Schrittlimit des Agenten, daher wird sein Trace als truncated aufgezeichnet. Jede Zählung über einen abgeschnittenen Trace ist eine untere Schranke, und eine untere Schranke klärt manche Fragen und andere nicht:
| Kriterium | Der abgeschnittene Fall | Warum |
|---|---|---|
| agent_steps_le_10 | scheitert | die aufgezeichneten Schritte belegen bereits, dass ein Limit von zehn überschritten wurde |
| agent_tool_lookup_order_called | fehlend | der Aufruf kann in dem Teil liegen, der nicht aufgezeichnet wurde |
| agent_no_tool_loop | fehlend | eine Wiederholung, die das Ende des Traces erreicht, kann darüber hinaus weitergehen |
| steps_p95, tool_calls_p50 | fehlend | ein Quantil über untere Schranken ist kein Quantil |
Fehlend statt ausgeschlossen: Der Fall bleibt unbeobachtet im Nenner, und das Intervall lässt zu, dass er in beide Richtungen ausgegangen sein könnte. Deshalb lautet agent_tool_lookup_order_called [86.8%, 100.0%] über 39 beobachtete Fälle statt des engeren Intervalls, das 39 Fälle allein ergeben würden.
Slices über Trajektorien
first_tool gruppiert Fälle nach dem Tool, zu dem der Agent zuerst gegriffen hat, welche Tools der Lauf auch immer aufgerufen hat. repeated_action trennt Fälle, die einen identischen Aufruf wiederholt haben, von denen, die das nicht getan haben. trajectory_length:4,8 gruppiert Fälle bei 1-4, 5-8 und 9 oder mehr Schritten, an Grenzen, die Sie deklarieren, weil eine Gruppengrenze verändert, was ein Slice aussagt.
│ first_tool=search │ agent_no_tool_loop │ 0.0% │ [0.0%, 57.9%] │ 0 / 6 observed · 1 missing · 0 excluded · │
│ first_tool=search │ agent_tool_sequence │ 0.0% │ [0.0%, 41.0%] │ 0 / 7 observed · 0 missing · 0 excluded · │
│ repeated_action=false │ answer_correct │ 93.1% │ [77.2%, 99.2%] │ 27 / 29 observed · 0 missing · 0 excluded · │
│ repeated_action=true │ answer_correct │ 60.0% │ [26.2%, 87.9%] │ 6 / 10 observed · 0 missing · 0 excluded · │Eine Schleife ist ein Signal, keine Erklärung. Nichts in der Ausgabe besagt, dass ein wiederholter Aufruf der Grund ist, warum ein Fall gescheitert ist; das könnte nur ein Replay zeigen, das ihn entfernt.
Mehrere Agenten
examples/triage_agents/ führt ein Team aus drei Agenten aus: triage übergibt jede Anfrage an billing oder tech, und eine Erstattung, die billing nicht ausstellen darf, wird an eine Person übergeben. In einem System aus mehreren Agenten benennt jeder Schritt den Agenten, der ihn ausgeführt hat, und eine Übergabe der Kontrolle ist ein handoff-Schritt:
steps.append(AgentStep(index=1, kind="message", agent="triage", arguments={"request": request}))
steps.append(AgentStep(index=2, kind="handoff", agent="triage", to_agent="billing"))
steps.append(AgentStep(index=3, kind="tool_call", agent="billing", tool_name="lookup_order"))Eine Trajektorie benennt den Agenten jedes Schritts oder keines Schritts. Eine Aufzeichnung, die nur einige benennt, wird abgelehnt, und eine, die keinen benennt, ist für jedes der folgenden Kriterien fehlend, statt es zu bestehen. Ein Übergabeschritt ist optional, da die Kontrolle auch dann wechselt, wenn der nächste Schritt von einem anderen Agenten ausgeführt wird. Mit ihm zeichnet ein Trace eine Übergabe an einen Agenten auf, der keinen Schritt ausführt, etwa eine Person.
Ein Fall deklariert unter expected.route die Agenten, die er durchlaufen soll:
{"id": "case_012", "input": {"topic": "billing", "request": "I was charged twice for order ord-012", "order_id": "ord-012", "behaviour": "escalated"}, "expected": {"answer": "escalated", "route": ["triage", "billing", "person"]}, "metadata": {"topic": "billing", "behaviour": "escalated"}}evaluators:
- {type: contains, criterion: answer_correct, field: answer, expected_field: answer}
- {type: agent_route}
- type: agent_tool_permissions
permissions:
triage: []
billing: [lookup_order, issue_refund]
tech: [search_kb]
- {type: agent_max_handoffs, max_handoffs: 2}
slices: [route]| Typ | Besteht, wenn | Nimmt |
|---|---|---|
| agent_route | die Agenten, die die Kontrolle hatten, Wiederholungen zusammengefasst, der expected.route des Falls entsprechen | nichts |
| agent_tool_permissions | jeder Tool-Aufruf von einem Agenten stammt, dem die Zuordnung den Aufruf dieses Tools erlaubt | permissions |
| agent_max_handoffs | die Kontrolle höchstens max_handoffs-mal gewechselt hat | max_handoffs |
Die Route schließt den Empfänger einer Übergabe ein, sodass ein Trace, der mit einer Eskalation an eine Person endet, zu der Person führt. Ein Fall ohne expected.route wird von agent_route nicht gezählt. Die Berechtigungszuordnung ist abgeschlossen: Ein Agent, den sie nicht aufführt, darf kein Tool aufrufen.
│ answer_correct │ 96.7% │ [82.7%, 100.0%] │ 29 / 30 observed · 0 missing · 0 excluded │
│ agent_route │ 86.7% │ [69.2%, 96.3%] │ 26 / 30 observed · 0 missing · 0 excluded │
│ agent_tool_permissions │ 93.1% │ [73.4%, 99.2%] │ 27 / 29 observed · 1 missing · 0 excluded │
│ agent_handoffs_le_2 │ 86.7% │ [69.2%, 96.3%] │ 26 / 30 observed · 0 missing · 0 excluded │In zwei Anfragen hat tech eine Erstattung ausgestellt. Beide bestehen answer_correct und scheitern an agent_tool_permissions: Der Kunde hat die richtige Antwort von einem System erhalten, das seine eigenen Berechtigungen verletzt hat. Eine Anfrage wird zwischen billing und tech hin- und hergereicht, bis die Grenze der Schleife erreicht ist. Ihr Trace ist abgeschnitten, daher scheitert sie an der Route und an der Übergabegrenze, die ihr Präfix bereits klärt, und ist bei den Berechtigungen fehlend, die es nicht klärt.
route gruppiert Fälle nach der Route, die ihre Agenten genommen haben, geschrieben als triage>billing. Ein abgeschnittener Trace tritt keiner Routengruppe bei, weil seine Route ein Präfix dessen ist, wohin seine Agenten als Nächstes gegangen sind.
Nichts in der Ausgabe sagt, welcher Agent schuld ist. Eine Routenabweichung sagt, wo sich zwei Routen trennen. Dass ein Agent einen Fehlschlag verursacht hat, ist eine Aussage darüber, was geschehen wäre, hätte er anders gehandelt, was nur ein Replay zeigen könnte, das diesen Agenten ersetzt, und Oloproof führt keines aus.
Wie es weitergeht
- Festhalten, was ein System getan hat behandelt die anderen typisierten Artefakte.
- Slices behandelt den Slice-Support und warum Slices niemals gaten.