Installieren Sie die neueste Version mit:
pip install operagents
# or use poetry
poetry add operagents
# or use pdm
pdm add operagents
# or use uv
uv pip install operagentsEin Agent ist ein Mensch oder ein Sprachmodell, das als Zeichen fungieren und Requisiten in den Opernszenen verwenden kann. Der Agent kann mit anderen kommunizieren, indem er beobachtet und handelt. Jeder Agent verfügt über einen Backend (z. B. Benutzer, OpenAI-API), um die Antwort und den eigenen Speicher zu generieren, um die langfristigen / kurzfristigen Informationen zu speichern.
Eine Szene ist ein Teil der Oper, die eine Reihe von Zeichen enthält. Jede Szene hat einen Fluss und einen Regisseur, um den gesamten Sitzungsprozess zu kontrollieren. Die Szene kann auch einen Vorbereitungsbereich haben, um einige Initialisierungsarbeiten zu erledigen, bevor die Szene beginnt.
Ein Charakter ist eine Rolle in der Szene. Jeder Charakter hat einen Namen, eine Beschreibung und eine Liste von Requisiten. Wenn die Szene beginnt, wird ein Agent als Charakter fungieren und mit anderen kommunizieren.
Der Fluss wird verwendet, um die Reihenfolge der in der Szene wirkenden Zeichen der Zeichen zu steuern.
Der Regisseur wird verwendet, um zu entscheiden, ob er die aktuelle Szene beenden und welche Szene als nächstes spielen soll.
Eine Requisite ist ein Werkzeug, das von den Agenten verwendet werden kann, um ihre Handlung zu verbessern. Agenten können externe Informationen mithilfe von Requisiten erhalten.
Die Zeitleiste ist die Hauptkomponente der Laufzeit der Opera, um den Sitzungsprozess zu verwalten. Es führt die aktuelle Sitzung aus und wechselt zwischen den Sitzungen. Die Zeitleiste erfasst auch die globalen Informationen der Oper und kann von allen Agenten geteilt werden.
Eine Sitzung zeigt einen einzigen Lauf der Szene an. Es enthält eine eindeutige Kennung und seine entsprechende Szene.
Die übliche Möglichkeit, Operagents zu verwenden, besteht darin, eine Konfigurationsdatei zu schreiben und die Oper mit dem Befehlszeilen-Tool operagents auszuführen.
Erstellen Sie eine config.yaml -Datei mit folgenden grundlegenden Inhalten:
# yaml-language-server: $schema=https://operagents.yyydl.top/schemas/config.schema.json
agents :
opening_scene : " "
scenes : Die erste Zeile ist ein Kommentar, in dem der YAML -Sprachserver das Schema aus der angegebenen URL verwenden soll. Dies ermöglicht die Autoperation und Validierung in Ihrem Editor.
Das Schema bezieht sich auf die Version des von Ihnen verwendeten Operagents -Frameworks. Die URL befindet sich im Format https://operagents.yyydl.top/schemas/config-<version>.schema.json <version>.schema.json, wobei <version> die Version des Framework ist, z. B. 0.0.1 . Wenn keine Version angegeben ist, wird die neueste (Master-) Version verwendet.
Bevor wir die Agenten- und Szenenkonfigurationen schreiben, müssen wir die Vorlagenkonfiguration kennenlernen.
Operagenten verwenden Vorlagen, um die Kontexteingabe für das Sprachmodell zu generieren. Eine Vorlage ist eine Zeichenfolge im Jinja -Format. Sie können die Jinja2 -Syntax mit bereitgestellten Kontextvarieln verwenden, um die Eingabe in das Sprachmodell zu steuern.
Eine Vorlagenkonfiguration kann im folgenden Format sein:
Einfache Zeichenfolgevorlage
user_template : |-
{# some jinja template #}Vorlage mit benutzerdefinierten Funktionen
user_template :
content : |-
{# some jinja template #}
custom_functions :
function_name : module_name:function_name Wenn Sie in der Vorlage benutzerdefinierte Funktionen verwenden möchten, müssen Sie den Schlüssel custom_functions -Schlüssel für benutzerdefinierte Funktionsnamen und deren entsprechende Modulpfade im DOT -Notationsformat angeben.
Der Abschnitt agents ist ein Wörterbuch der Agenten, wobei der Schlüssel der Name des Agenten und der Wert der Konfiguration des Agenten ist.
Die Agenten müssen in den Szenen als Charakter fungieren und auf die Nachrichten anderer antworten. Der erste Teil der Agentenkonfiguration ist also die Backend -Konfiguration, mit der mit dem Sprachmodell oder Benutzer kommuniziert wird. Sie können den backend -Schlüssel verwenden, um den Backend -Typ und seine Konfiguration anzugeben.
agents :
Mike :
backend :
# user as the backend (a.k.a human-agent)
type : user
John :
backend :
# openai api as the backend
type : openai
model : gpt-3.5-turbo
temperature : 0.5
api_key :
base_url :
max_retries : 2
tool_choice :
type : auto
prop_validation_error_template : |-
{# some jinja template #} Sie können das Backend auch anpassen, indem Sie einen Objektpfad der benutzerdefinierten Backend -Klasse bereitstellen, der die Backend -Abstract -Klasse implementiert .:::
agents :
Mike :
backend :
type : custom
path : module_name:CustomBackend
custom_config : value # module_name.py
from typing import Self
from operagents . prop import Prop
from operagents . timeline import Timeline
from operagents . config import CustomBackendConfig
from operagents . backend import Backend , Message , GenerateResponse , GeneratePropUsage
class CustomBackend ( Backend ):
@ classmethod
def from_config ( cls , config : CustomBackendConfig ) -> Self :
return cls ()
@ overload
async def generate (
self ,
timeline : Timeline ,
messages : list [ Message ],
props : None = None ,
) -> AsyncGenerator [ GenerateResponse , None ]: ...
@ overload
async def generate (
self ,
timeline : Timeline ,
messages : list [ Message ],
props : list [ Prop ],
) -> AsyncGenerator [ GenerateResponse | GeneratePropUsage , None ]: ...
async def generate (
self , timeline : Timeline , messages : list [ Message ], props : list [ Prop ] | None = None
) -> AsyncGenerator [ GenerateResponse | GeneratePropUsage , None ]:
yield GenerateResponse ( content = "" ) Der nächste Teil der Agentenkonfiguration ist die System-/Benutzervorlage, mit der die Kontexteingabe für das Sprachmodell generiert wird. Sie können den Schlüssel -Taste system_template / user_template verwenden, um die System- / Benutzervorlage anzugeben. Hier ist ein Beispiel für die Vorlagenkonfiguration:
agents :
John :
system_template : |-
Your name is {{ agent.name }}.
Current scene is {{ timeline.current_scene.name }}.
{% if timeline.current_scene.description -%}
{{ timeline.current_scene.description }}
{%- endif -%}
You are acting as {{ timeline.current_character.name }}.
{% if timeline.current_character.description -%}
{{ timeline.current_character.description }}
{%- endif -%}
Please continue the conversation on behalf of {{ agent.name }}({{ timeline.current_character.name }}) based on your known information and make your answer appear as natural and coherent as possible.
Please answer directly what you want to say and keep your reply as concise as possible.
user_template : |-
{% for event in timeline.past_events(agent) -%}
{% if event.type_ == "session_act" -%}
{{ event.character.agent_name }}({{ event.character.name }}): {{ event.content }}
{%- endif %}
{%- endfor %} Ein weiterer Teil der Agent -Konfiguration ist die Session Summary System/Benutzervorlage, mit der die Zusammenfassung der Szenensitzung generiert wird. Sie können den Taste session_summary_system_template / session_summary_user_template verwenden, um die Session Summary System / Benutzervorlage anzugeben. Hier ist ein Beispiel für die Vorlagenkonfiguration:
agents :
John :
session_summary_system_template : |-
Your name is {{ agent.name }}.
Your task is to summarize the historical dialogue records according to the current scene, and summarize the most important information.
session_summary_user_template : |-
{% for event in agent.memory.get_memory_for_session(session_id) -%}
{% if event.type_ == "observe" -%}
{{ event.content }}
{%- elif event.type_ == "act" -%}
{{ agent.name }}({{ event.character.name }}): {{ event.content }}
{%- endif %}
{%- endfor %}
{% for event in timeline.session_past_events(agent, session_id) -%}
{% if event.type_ == "session_act" -%}
{{ event.character.agent_name }}({{ event.character.name }}): {{ event.content }}
{%- endif %}
{%- endfor %} Mit der Taste opening_scene werden die Startszene der Oper angegeben. Der Wert ist der Name der Eröffnungsszene.
opening_scene : " Introduction " Der Abschnitt scenes ist ein Wörterbuch von Szenen, in dem der Schlüssel der Name der Szene und der Wert der Szenekonfiguration ist.
Die Oper besteht aus mehreren Szenen und jede Szene hat eine Reihe von Zeichen. Sie müssen zuerst den Namen, die Beschreibung (optional) und die Zeichen der Szene definieren.
scenes :
talking :
description : " The scene is about two people talking. "
characters :
user :
agent_name : " Mike "
ai assistant :
agent_name : " John "
description : |-
You are a helpful assistant.
props : [] Die Zeichen in der Szene müssen den agent_name -Schlüssel definieren, der der Name des Agenten ist, der als Zeichen fungiert. Der description (optional) kann verwendet werden, um das Zeichen in der Agentenvorlage zu beschreiben. Der Taste props (optional) kann verwendet werden, um die Requisiten des Zeichens zu definieren. Weitere Informationen finden Sie in der Prop -Konfiguration.
Der Flow soll die Reihenfolge der Schauspielerei der Charaktere steuern. Sie können den Typ und die Parameter des Flow angeben.
order
Der order wird verwendet, um die Reihenfolge der Schauspielern der Zeichen vorzu definieren. Die Charaktere durchlaufen die Auftragsliste, bis die Szene endet.
scenes :
talking :
flow :
type : order
order :
- user
- ai assistant model
Der model wird verwendet, um das Modell zu spezifizieren, um das nächste Handeln vorherzusagen. Das Modell wird das nächste Zeichen basierend auf dem aktuellen Kontext voraussagen.
scenes :
talking :
flow :
type : model
backend :
type : openai
model : gpt-3.5-turbo
temperature : 0.5
system_template : " "
user_template : " "
allowed_characters : # optional, the characters allowed to act
- user
- ai assistant
begin_character : user # optional, the first character to act
fallback_character : ai assistant # optional, the fallback character when the model fails to predict user
Der user ermöglicht es dem Menschen, den nächsten Charakter zu wählen, um zu handeln.
scenes :
talking :
flow :
type : user custom Typ
Mit dem custom Typ können Sie eine benutzerdefinierte Flussklasse definieren, um die Reihenfolge der Schauspiele der Zeichen zu steuern.
scenes :
talking :
flow :
type : custom
path : module_name:CustomFlow
custom_config : value # module_name.py
from typing import Self
from operagents . flow import Flow
from operagents . timeline import Timeline
from operagents . character import Character
from operagents . config import CustomFlowConfig
class CustomFlow ( Flow ):
@ classmethod
def from_config ( cls , config : CustomFlowConfig ) -> Self :
return cls ()
async def begin ( self , timeline : Timeline ) -> Character :
return ""
async def next ( self , timeline : Timeline ) -> Character :
return "" Der Director der Szene wird verwendet, um die nächste Szene zu kontrollieren. Sie können den Typ und die Parameter des Direktors angeben.
model
Der model wird verwendet, um das Modell anzugeben, um die nächste Szene vorherzusagen. Wenn keine Figur gefunden oder kein Szenenname gefunden wurde, wird die kurente Szene weiter spielen.
scenes :
talking :
director :
type : model
backend :
type : openai
model : gpt-3.5-turbo
temperature : 0.5
system_template : " "
user_template : " "
allowed_scenes : # optional, the next scenes allowed to play
- walking
- running
finish_flag : " finish " # optional, the finish flag to end the opera user
Mit dem user kann Human die nächste Szene auswählen.
scenes :
talking :
director :
type : user Geben Sie never ein
Der never Director beendet die aktuelle Szene nie. Nützlich, wenn es eine einzelne Szene gibt und Sie die Oper mit einer Prop beenden möchten.
scenes :
talking :
director :
type : never custom Typ
Mit dem custom Typ können Sie eine benutzerdefinierte Director -Klasse definieren, um die nächste Szene zu steuern.
scenes :
talking :
director :
type : custom
path : module_name:CustomDirector
custom_config : value # module_name.py
from typing import Self
from operagents . scene import Scene
from operagents . director import Director
from operagents . timeline import Timeline
from operagents . config import CustomDirectorConfig
class CustomDirector ( Director ):
@ classmethod
def from_config ( cls , config : CustomDirectorConfig ) -> Self :
return cls ()
async def next_scene ( self , timeline : Timeline ) -> Scene | None :
return None Der Abschnitt prepare der Szene" wird verwendet, um die Vorbereitungsschritte vor Beginn der Szene zu definieren. Sie können hier einige Initialisierungsarbeiten durchführen.
preface Typ
Sie können den Charakter etwas sagen lassen, bevor die Szene beginnt.
scenes :
talking :
prepare :
- type : preface
character_name : ai assistant
content : |-
Hello, I am John, your AI assistant. How can I help you today? function
Der function ruft die benutzerdefinierte Funktion auf, bevor die Szene startet.
scenes :
talking :
prepare :
- type : function
function : module_name:function_name Die benutzerdefinierte Funktion empfängt einen Parameter von typen operagents.timeline.Timeline .
# module_name.py
from operagents . timeline import Timeline
async def function_name ( timeline : Timeline ) -> None :
pass custom Typ
Der custom Typ ruft die benutzerdefinierte Vorbereitungsklasse an, bevor die Szene beginnt.
scenes :
talking :
prepare :
- type : custom
path : module_name:CustomPrepare
custom_config : value # module_name.py
from typing import Self
from operagents . timeline import Timeline
from operagents . scene . prepare import ScenePrepare
from operagents . config import CustomScenePrepareConfig
class CustomScenePrepare ( ScenePrepare ):
@ classmethod
def from_config ( cls , config : CustomScenePrepareConfig ) -> Self :
return cls ()
async def prepare ( self , timeline : Timeline ) -> None :
pass Die Charaktere in der Szene können Requisiten verwenden, um dort die Schauspielerei zu verbessern. Der Abschnitt props ist eine Liste von Requisiten, wobei jede Requisite ein Wörterbuch mit dem Proptyp und der Prop -Konfiguration ist.
function
Die function ruft die benutzerdefinierte Funktion auf, wenn die Prop verwendet wird.
scenes :
talking :
characters :
ai assistant :
props :
- type : function
function : module_name:function_name
exception_template : |-
{# some jinja template #} Die benutzerdefinierte Funktion sollte keine Argumente oder ein Argument vom Typ pydantic.BaseModel haben.
from pydantic import Field , BaseModel
from datetime import datetime , timezone
async def current_time () -> str :
"""Get the current real world time."""
return datetime . now ( timezone . utc ). astimezone (). isoformat ()
class Args ( BaseModel ):
name : str = Field ( description = "The name" )
async def greet ( args : Args ) -> str :
"""Greet the name."""
return f"Hello, { args . name } !" Beachten Sie, dass der Name und der DocString der Funktion als Name und Beschreibung der Stütze verwendet werden. Sie können auch die Beschreibung der Argumente nach Pydantics Field angeben. Die Ausnahmevorlage wird verwendet, um die Reaktion zu rendern, wenn die Funktion einen Fehler aufwirft.
custom
Die custom Requisite ruft die benutzerdefinierte Prop -Klasse auf, wenn die Requisite verwendet wird.
scenes :
talking :
characters :
ai assistant :
props :
- type : custom
path : module_name:CustomProp
custom_config : value # module_name.py
from typing import Any , Self
from pydantic import BaseModel
from operagents . prop import Prop
from operagents . config import CustomPropConfig
class CustomProp ( Prop ):
"""The description of the prop"""
params : BaseModel | None
"""The parameters of the prop"""
@ classmethod
def from_config ( cls , config : CustomPropConfig ) -> Self :
return cls ()
async def call ( self , params : BaseModel | None ) -> Any :
return "" Mit Hooks können Sie benutzerdefinierten Code ausführen, wenn bestimmte Zeitleistenereignisse auftreten. Der Abschnitt hooks ist eine Liste von Haken, wobei jeder Haken ein Wörterbuch mit dem Hakentyp und der Hakenkonfiguration ist. Standardmäßig ermöglicht Operagenten den summary , es sei denn, Sie ändern den Abschnitt hooks .
summary
Der summary Hook ruft die Agenten an, um die Sitzung beim Ende der Sitzung zusammenzufassen. Sie können optional die zum Zusammenfassungen der Agenten festgelegten Agentennamen angeben.
hooks :
- type : summary
agent_names :
- Mike
- John custom Haken
Der custom Hook ruft die benutzerdefinierte Hook -Klasse auf, wenn bestimmte Timeline -Ereignisse begegnet sind.
hooks :
- type : custom
path : module_name:CustomHook
custom_config : value # module_name.py
from typing import Self
from operagents . hook import Hook
from operagents . timeline import Timeline
from operagents . config import CustomHookConfig
from operagents . timeline . event import (
TimelineEventEnd ,
TimelineEventStart ,
TimelineEventSessionAct ,
TimelineEventSessionEnd ,
TimelineEventSessionStart ,
)
class CustomHook ( Hook ):
@ classmethod
def from_config ( cls , config : CustomHookConfig ) -> Self :
return cls ()
async def on_timeline_start (
self , timeline : Timeline , event : TimelineEventStart
):
"""Called when the timeline is started."""
pass
async def on_timeline_end (
self , timeline : Timeline , event : TimelineEventEnd
):
"""Called when the timeline is ended."""
pass
async def on_timeline_session_start (
self , timeline : Timeline , event : TimelineEventSessionStart
):
"""Called when a session is started."""
pass
async def on_timeline_session_end (
self , timeline : Timeline , event : TimelineEventSessionEnd
):
"""Called when a session is ended."""
pass
async def on_timeline_session_act (
self , timeline : Timeline , event : TimelineEventSessionAct
):
"""Called when a character acts in a session."""
pass Die Hook -Klasse kann Methoden im Format von on_timeline_<event_type> enthält, wobei <event_type> der Typ des Timeline -Ereignisses ist.
Operagents bietet ein Befehlszeilen-Tool, um die Oper einfach auszuführen. Sie können die Oper mit dem folgenden Befehl ausführen:
operagents run config.yaml Wenn Sie die Debug-Protokolle sehen möchten, können Sie die Option --log-level festlegen:
operagents run --log-level DEBUG config.yaml Weitere Befehle und Optionen finden Sie durch Ausführen operagents --help .
Wenn Sie die Opera programmgesteuert ausführen möchten, können Sie die Funktion opera.run verwenden:
import asyncio
from pathlib import Path
import yaml
from operagents . opera import Opera
from operagents . log import setup_logging
from operagents . config import OperagentsConfig
async def main ():
# if you want to setup the default logging for operagents
setup_logging ( "INFO" )
# load the opera from config file
opera = Opera . from_config (
OperagentsConfig . model_validate (
yaml . safe_load ( Path ( "./config.yaml" ). read_text ( encoding = "utf-8" ))
)
)
finish_state = await opera . run ()
if __name__ == "__main__" :
asyncio . run ( main ()) cd examples/chatbot
env OPENAI_API_KEY=sk-xxx OPENAI_BASE_URL=https://api.openai.com/v1 operagents run --log-level DEBUG config.yamlOffen in den Codenspaces (Dev Container):
Oder installieren Sie die Entwicklungsumgebung lokal mit:
poetry install && poetry run pre-commit install