تثبيت أحدث إصدار مع:
pip install operagents
# or use poetry
poetry add operagents
# or use pdm
pdm add operagents
# or use uv
uv pip install operagentsالعامل هو نموذج إنسان أو لغة يمكن أن يعمل كحرف ويستخدم الدعائم في مشاهد الأوبرا. يمكن للوكيل التواصل مع الآخرين من خلال مراقبة والتمثيل. كل وكيل لديه الواجهة الخلفية (EG ، Openai API) لإنشاء الاستجابة والذاكرة الخاصة لتخزين المعلومات طويلة الأجل / قصيرة الأجل.
المشهد هو جزء من الأوبرا التي تحتوي على عدد من الشخصيات. كل مشهد له تدفق ومخرج للتحكم في عملية الجلسة بأكملها. يمكن أن يكون للمشهد أيضًا قسم إعداد للقيام ببعض أعمال التهيئة قبل بدء المشهد.
الشخصية هي دور في المشهد. كل حرف له اسم ووصف وقائمة من الدعائم. عندما يبدأ المشهد ، سيعمل الوكيل كحرف ويتواصل مع الآخرين.
يتم استخدام التدفق للتحكم في ترتيب تصرف الشخصيات في المشهد.
يتم استخدام المخرج لتقرير ما إذا كان سيتم إنهاء المشهد الحالي وأي مشهد يلعب بعد ذلك.
الدعامة هي أداة يمكن أن تستخدمها الوكلاء لتحسين التمثيل. يمكن للوكلاء الحصول على معلومات خارجية باستخدام الدعائم.
الجدول الزمني هو مكون وقت التشغيل الرئيسي في الأوبرا لإدارة عملية الجلسة. يدير الجلسة الحالية والتبديل بين الجلسات. يسجل الجدول الزمني أيضًا المعلومات العالمية للأوبرا ، ويمكن مشاركتها من قبل جميع الوكلاء.
تشير الجلسة إلى تشغيل واحد للمشهد. أنه يحتوي على معرف فريد ومشهده المقابل.
تتمثل الطريقة الشائعة لاستخدام Operagents في كتابة ملف التكوين وتشغيل الأوبرا باستخدام أداة سطر أوامر operagents .
قم بإنشاء ملف config.yaml مع المحتوى الأساسي التالي:
# yaml-language-server: $schema=https://operagents.yyydl.top/schemas/config.schema.json
agents :
opening_scene : " "
scenes : السطر الأول هو تعليق يخبر خادم لغة YAML باستخدام المخطط من عنوان URL المحدد. سيمكن هذا الإكمال التلقائي والتحقق من الصحة في المحرر الخاص بك.
يرتبط المخطط بإصدار إطار Operagents الذي تستخدمه. يكون عنوان URL في التنسيق https://operagents.yyydl.top/schemas/config-<version>.schema.json <version> 0.0.1 إذا لم يتم تحديد أي إصدار ، فسيتم استخدام أحدث إصدار (رئيسي).
قبل كتابة تكوينات الوكيل والمشهد ، نحتاج إلى معرفة تكوين القالب.
يستخدم Operagents قوالب لإنشاء إدخال السياق لنموذج اللغة. القالب عبارة عن سلسلة بتنسيق Jinja. يمكنك استخدام بناء جملة Jinja2 مع سياق سياق متوفر للتحكم في الإدخال في نموذج اللغة.
يمكن أن يكون تكوين القالب بالتنسيق التالي:
قالب سلسلة بسيط
user_template : |-
{# some jinja template #}قالب مع وظائف مخصصة
user_template :
content : |-
{# some jinja template #}
custom_functions :
function_name : module_name:function_name إذا كنت ترغب في استخدام وظائف مخصصة في القالب ، فأنت بحاجة إلى توفير مفتاح custom_functions ، وهو قاموس لأسماء الوظائف المخصصة ومسارات الوحدة النمطية المقابلة في تنسيق ترميز DOT.
قسم agents هو قاموس الوكلاء ، حيث يكون المفتاح هو اسم الوكيل والقيمة هي تكوين الوكيل.
يحتاج الوكلاء إلى العمل كشخصية في الكواليس والرد على رسائل الآخرين. لذلك ، فإن الجزء الأول من تكوين الوكيل هو تكوين الواجهة الخلفية ، والذي يتم استخدامه للتواصل مع نموذج اللغة أو المستخدم. يمكنك استخدام مفتاح backend لتحديد نوع الواجهة الخلفية وتكوينه.
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 #} يمكنك أيضًا تخصيص الواجهة الخلفية من خلال توفير مسار كائن لفئة الواجهة الخلفية المخصصة التي تنفذ الفئة الملخص Backend :
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 = "" ) الجزء التالي من تكوين الوكيل هو قالب النظام/المستخدم المستخدم لإنشاء إدخال السياق لنموذج اللغة. يمكنك استخدام مفتاح system_template / user_template لتحديد قالب النظام / المستخدم. فيما يلي مثال على تكوين القالب:
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 %} جزء آخر من تكوين الوكيل هو قالب نظام ملخص الجلسة/قالب المستخدم ، والذي يتم استخدامه لإنشاء ملخص جلسة المشهد. يمكنك استخدام مفتاح session_summary_system_template / session_summary_user_template لتحديد قالب نظام ملخص الجلسة / قالب المستخدم. فيما يلي مثال على تكوين القالب:
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 %} يتم استخدام مفتاح opening_scene لتحديد مشهد البدء للأوبرا. القيمة هي اسم المشهد الافتتاحي.
opening_scene : " Introduction " قسم scenes هو قاموس المشاهد ، حيث يكون المفتاح هو اسم المشهد والقيمة هي تكوين المشهد.
تتكون الأوبرا من مشاهد متعددة ، وكل مشهد يحتوي على عدد من الشخصيات. تحتاج أولاً إلى تحديد الاسم والوصف (اختياري) وشخصيات المشهد.
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 : [] يجب أن تحدد الشخصيات في المشهد مفتاح agent_name ، وهو اسم الوكيل الذي يعمل كحرف. يمكن استخدام مفتاح description (اختياري) لوصف الحرف في قالب الوكيل. يمكن استخدام مفتاح props (اختياري) لتحديد الدعائم الشخصية ، راجع تكوين الدعامة لمزيد من التفاصيل.
تم تصميم Flow المشهد للتحكم في ترتيب تمثيل الشخصيات. يمكنك تحديد نوع ومعلمات Flow .
نوع order
يتم استخدام نوع order لتحديد ترتيب التمثيل للأحرف. سوف تدور الأحرف من خلال قائمة الطلبات حتى ينتهي المشهد.
scenes :
talking :
flow :
type : order
order :
- user
- ai assistant نوع model
يتم استخدام نوع model لتحديد النموذج للتنبؤ بالحرف التالي للعمل. سوف يتنبأ النموذج بالحرف التالي بناءً على السياق الحالي.
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
يسمح نوع user للبشر باختيار الحرف التالي للعمل.
scenes :
talking :
flow :
type : user نوع custom
يتيح لك النوع custom تحديد فئة التدفق المخصصة للتحكم في ترتيب التمثيل للأحرف.
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 "" يستخدم Director المشهد للتحكم في المشهد التالي للعب. يمكنك تحديد نوع ومعلمات المخرج.
نوع model
يتم استخدام نوع model لتحديد النموذج للتنبؤ بالمشهد التالي للعب. إذا لم يتم العثور على علم الانتهاء أو لم يتم العثور على اسم مشهد ، فسيستمر مشهد Curent في اللعب.
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
يتيح نوع user للبشر اختيار المشهد التالي للعب.
scenes :
talking :
director :
type : user لا تكتب never
لم ينهي never أبدًا المشهد الحالي. مفيد عندما يكون هناك مشهد واحد وتريد إنهاء الأوبرا بواسطة Prop .
scenes :
talking :
director :
type : never نوع custom
يتيح لك النوع custom تحديد فئة المخرج المخصصة للتحكم في المشهد التالي للعب.
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 يتم استخدام قسم prepare المشهد لتحديد خطوات التحضير قبل بدء المشهد. يمكنك القيام ببعض أعمال التهيئة هنا.
نوع preface
يمكنك جعل الشخصية تقول شيئًا قبل أن يبدأ المشهد.
scenes :
talking :
prepare :
- type : preface
character_name : ai assistant
content : |-
Hello, I am John, your AI assistant. How can I help you today? نوع function
سيقوم نوع function بالاتصال بالوظيفة المخصصة قبل بدء المشهد.
scenes :
talking :
prepare :
- type : function
function : module_name:function_name ستتلقى الوظيفة المخصصة معلمة واحدة من type operagents.timeline.Timeline .
# module_name.py
from operagents . timeline import Timeline
async def function_name ( timeline : Timeline ) -> None :
pass نوع custom
سيتصل النوع custom بفئة إعداد Custom قبل بدء المشهد.
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 يمكن للشخصيات في المشهد استخدام الدعائم لتحسين التمثيل. قسم props هو قائمة من الدعائم ، حيث يكون كل دعامة من قاموس مع نوع الدعامة وتكوين الدعامة.
function الدعامة
ستدعو الدالة function إلى الوظيفة المخصصة عند استخدام الدعامة.
scenes :
talking :
characters :
ai assistant :
props :
- type : function
function : module_name:function_name
exception_template : |-
{# some jinja template #} لا ينبغي أن تحتوي الوظيفة المخصصة على وسيط أو وسيطة واحدة من نوع pydantic.BaseModel .
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 } !" لاحظ أنه سيتم استخدام اسم الوظيفة و docstring كاسم ووصف الدعامة. يمكنك أيضًا تقديم وصف لـ ARGS بواسطة Field Pydantic. سيتم استخدام قالب الاستثناء لتقديم الاستجابة عندما ترفع الوظيفة خطأ.
دعامة custom
سيقوم الدعامة custom باستدعاء فئة الدعامة المخصصة عند استخدام الدعامة.
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 "" تمكنك Hooks من تشغيل رمز مخصص عند حدوث أحداث محددة من الجدول الزمني. قسم hooks هو قائمة من السنانير ، حيث يكون كل خطاف قاموسًا بنوع الخطاف وتكوين الخطاف. بشكل افتراضي ، يتيح Operagents الخطاف summary ما لم تقم بتغيير قسم hooks .
خطاف summary
سوف يتصل الخطاف summary بالوكلاء لتلخيص الجلسة عندما تنتهي الجلسة. يمكنك اختياريا تحديد أسماء الوكيل لتلخيصها.
hooks :
- type : summary
agent_names :
- Mike
- John خطاف custom
سوف يستدعي الخطاف custom فئة الخطاف المخصصة عند مواجهات حدث محدد.
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 قد تحتوي فئة الخطاف على طرق بتنسيق on_timeline_<event_type> ، حيث <event_type> هو نوع الحدث الزمني.
يوفر Operagents أداة سطر الأوامر لتشغيل الأوبرا بسهولة. يمكنك تشغيل الأوبرا مع الأمر التالي:
operagents run config.yaml إذا كنت ترغب في رؤية سجلات التصحيح ، فيمكنك تعيين خيار --log-level :
operagents run --log-level DEBUG config.yaml يمكن العثور على المزيد من الأوامر والخيارات عن طريق تشغيل operagents --help .
إذا كنت ترغب في تشغيل الأوبرا برمجيًا ، فيمكنك استخدام وظيفة opera.run :
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.yamlافتح في مساحات الترميز (حاوية DEV):
أو تثبيت بيئة التطوير محليا مع:
poetry install && poetry run pre-commit install