Zum Inhalt springen

Anleitungen

Simulierte Nutzer

Eine geskriptete Konversation testet Ihren Assistenten gegen einen Nutzer, der nie reagiert. Ein simulierter Nutzer reagiert: Ein Modell spielt eine Person, die jeder Fall beschreibt, schreibt jede nächste Nachricht aus dem, was Ihr Assistent gerade gesagt hat, und hört auf, wenn sein Ziel erreicht ist oder er aufgibt. Oloproof zeichnet auf, was zwischen beiden ausgetauscht wurde, misst es wie jede Konversation und lässt ein Gate erst dann darüber entscheiden, wenn Menschen den simulierten Nutzer realistisch gefunden haben. Das Tutorial führt durch einen Support-Desk, der mit simulierten Kunden spricht.

Personas

Der Input jedes Falls enthält eine Persona: wer der Nutzer ist, was er will und was er weiß.

{"id": "c25", "input": {"persona": {
  "description": "A retired teacher who ordered a cookbook last week. Writes short, polite messages.",
  "goal": "Have the order of a cookbook delivered to my new address.",
  "facts": {"order": "B-35", "postcode": "10275"}
}}}
  • description und goal sind Pflicht. Schreiben Sie ein Ziel, das ein Leser allein anhand der Konversation prüfen könnte: „den Shop eine Erstattung einleiten lassen“ lässt sich aus dem entscheiden, was der Assistent sagt, „eine Erstattung bekommen“ nicht, weil das Geld erst später ankommt.
  • facts ist das, was der Nutzer weiß und nur dann preisgibt, wenn die Konversation es braucht, etwa eine Bestellnummer. Ihr Assistent sieht die Persona nie.
  • opening ist die erste Nachricht des Nutzers, Wort für Wort, wenn jedes System auf dieselbe Weise begrüßt werden soll.
  • max_turns begrenzt die Nachrichten dieses Nutzers und überschreibt den Wert des Projekts.

Eine Persona ist Inhalt des Datensatzes: Sie wird vom Digest der Suite abgedeckt und ist für jedes System, das an ihr gemessen wird, dieselbe.

Den simulierten Nutzer deklarieren

Das Modell, das jede Persona spielt, wird am System deklariert, wie ein Judge:

system:
  name: support-desk
  callable: desk:talk
  simulated_user:
    provider: openai_compatible
    base_url: http://localhost:11434/v1
    model: qwen2.5vl
    max_turns: 6

Jedes Feld steht in der Konfigurationsreferenz. Ein lokales Modell kostet nichts; ein gehostetes rechnet jede Nachricht ab, die es schreibt, und seine Tokens werden neben der Konversation festgehalten und nie als Kosten Ihres Systems gezählt.

Ihr System behält seine Schleife

Oloproof steuert die Konversation nicht. Ihr System fragt nach der ersten Nachricht des Nutzers, beantwortet sie so, wie es Nutzern eben antwortet, und gibt jede Antwort für die nächste Nachricht zurück:

from oloproof import current_case

def talk(case):
    user = current_case().simulated_user()
    message = user.opening()
    while message is not None:
        message = user.reply(my_assistant.answer(message))
    return {}

reply gibt None zurück, sobald der Nutzer aufhört. Ihr System kann die Konversation selbst mit user.end(answer) beenden, so wie es eine Übergabe an eine Person täte; ein async def-System wartet auf aopening(), areply(answer) und aend(answer). Oloproof zeichnet auf, was durch das Handle gegangen ist, als conversation/v1, und wie die Konversation endete, als simulated_user/v1, und lehnt beides ab, wenn es von Ihrem System kommt (SDK-Referenz).

Wie eine Konversation endet

Nach jeder Antwort Ihres Systems wird das Modell des simulierten Nutzers gefragt, als eigene Frage bei Temperatur 0 und ohne das Rollenspiel drumherum, ob diese Antwort das Ziel erreicht hat. Wenn ja, endet die Konversation mit goal_reached. Andernfalls schreibt der Nutzer seine nächste Nachricht oder geht (user_left), bis er max_turns Nachrichten gesendet hat (turn_limit). Ein System, das aufhört, ohne die letzte Nachricht zu beantworten, hinterlässt die Konversation unanswered und abgeschnitten.

Die getrennte Frage ist es, die ein kleines lokales Modell brauchbar macht: Eine Persona spielen und entscheiden, ob ein Ziel erreicht wurde, sind verschiedene Aufgaben, und ein Modell, das beides in einer Antwort tun soll, neigt dazu, weiterzuplaudern, nachdem sein Ziel erreicht wurde, oder zu sagen, es gehe, wenn es zufrieden ist.

Die Konversationen messen

Die Konversation ist die Einheit: Jeder Evaluator gibt ein Urteil pro Konversation, sodass jedes Intervall, jeder Vergleich und jedes Gate unverändert gilt.

TypBesteht, wenn
conversation_completedIhr System jede Nachricht beantwortet hat
goal_reacheddie Zielprüfung das Ziel als erreicht befunden hat
turns_to_goaldas innerhalb von max_turns der Nachrichten des Nutzers geschah
every_turnjede Antwort deklarierte Bedingungen erfüllt: Wörter, die sie enthalten muss oder nicht enthalten darf, ein Muster, eine Länge
conversation_judgeein Modell-Judge des ganzen Transkripts sie bestehen lässt, sobald er an menschlichen Labels validiert ist

Replikate (replicates:) treffen auf unterschiedlich geseedete Nutzer, sodass eine Persona mehrere Konversationen ergibt. Die Version des simulierten Nutzers (sein Modell, sein Prompt, seine Temperatur und sein Budget) ist Teil des Cache-Schlüssels jeder Ausführung, sodass ein anderer simulierter Nutzer Ihr System erneut misst.

Den simulierten Nutzer validieren

Ein Ergebnis über simulierte Nutzer reicht nur so weit an echte Nutzer heran, wie der simulierte Nutzer ihnen ähnelt. Daher ist jede Regel über einem Lauf, dessen Nutzer simuliert waren, INSUFFICIENT_EVIDENCE mit simulated_user_not_validated, bis Menschen seine Konversationen realistisch gefunden haben:

oloproof labels export RUN_ID --criterion simulated_user_realistic --sample 30 --local --out realism.csv
oloproof labels import realism.csv
oloproof simulated-users RUN_ID

Die Tabelle zeigt jede gezogene Konversation mit der Persona und wie sie endete. Eine Person markiert passed mit ja, wenn ein echter Kunde die Seite des Nutzers geschrieben und die Konversation genau dort, auf diese Weise, beendet haben könnte; das deckt auch die Zielprüfung ab: Eine Konversation, die mit goal_reached endete, obwohl das Ziel nicht erreicht war, ist nicht realistisch. Der simulierte Nutzer ist auf der Suite validiert, wenn die exakte untere Schranke des realistischen Anteils minimum_simulated_user_realism in release.yaml erreicht. Eine gezogene Konversation, die ohne Label bleibt, zählt als unrealistisch, und eine Konversation ist nur dann realistisch, wenn alle, die sie gelabelt haben, das sagen.

Eine Validierung gilt für die Version eines simulierten Nutzers auf einer Suite, gleich mit welchem System er gesprochen hat, sodass ein Kandidat, der an denselben Personas gemessen wird, anhand der Labels der Baseline entschieden wird. Ein neues Modell, eine neue Prompt-Einstellung oder ein neuer Satz von Personas braucht neue Labels. Wer require_validated_evaluators: false setzt, entscheidet ohne sie über simulierte Nutzer, und zwar bewusst.

Simuliert neben echt

oloproof simulated-users RUN_ID --real REAL_RUN_ID stellt die Form der simulierten Konversationen neben einen Lauf mit echten (aufgezeichnete Chats, als conversation/v1 abgespielt): wie viele Nachrichten der Nutzer gesendet hat, wie lang sie waren, wie lang die Antworten waren, wie oft eine Konversation abgebrochen wurde und wie die simulierten endeten. Das ist beschreibend und entscheidet nie: Zwei ungepaarte Stichproben zu vergleichen braucht eine Methode, die Oloproof nicht zugelassen hat. Lesen Sie es für das, was Labels zur Realitätsnähe übersehen, etwa simulierte Nutzer, die in einem ordentlichen Satz schreiben, was echte auf drei verteilen.

Nicht unterstützt

  • Über simulierte Nutzer in einem gehosteten Workspace entscheiden: Seine Entscheidungen bleiben zurückgehalten, bis seine Review-Warteschlange Labels zur Realitätsnähe selbst ziehen und versiegeln kann.
  • Ein Gate darauf, wie sich simulierte Konversationen im Vergleich zu echten verhalten.
  • Raten auf Turn-Ebene innerhalb einer Konversation und das erneute Abspielen einer Konversation ab einem Turn.
  • Simulierte Nutzer für ein HTTP-System: Der eigene Code Ihres Systems führt die Schleife aus, es muss also ein Callable sein.