ติดตั้งเวอร์ชันล่าสุดด้วย:
pip install operagents
# or use poetry
poetry add operagents
# or use pdm
pdm add operagents
# or use uv
uv pip install operagentsตัวแทนเป็นรูปแบบมนุษย์หรือภาษาที่สามารถทำหน้าที่เป็นตัวละครและใช้อุปกรณ์ประกอบฉากในฉากโอเปร่า ตัวแทนสามารถสื่อสารกับผู้อื่นได้โดยการสังเกตและแสดง ตัวแทนทุกคนมีแบ็กเอนด์ (เช่นผู้ใช้ OpenAI API) เพื่อสร้างการตอบสนองและหน่วยความจำของตัวเองเพื่อจัดเก็บข้อมูลระยะยาว / ระยะสั้น
ฉากเป็นส่วนหนึ่งของโอเปร่าที่มีอักขระจำนวนมาก ทุกฉากมีการไหลและผู้อำนวยการเพื่อควบคุมกระบวนการเซสชันทั้งหมด ฉากยังสามารถมีส่วนเตรียมการสำหรับการเริ่มต้นบางอย่างก่อนที่ฉากจะเริ่ม
ตัวละครเป็นบทบาทในฉาก ตัวละครทุกตัวมีชื่อคำอธิบายและรายการอุปกรณ์ประกอบฉาก เมื่อฉากเริ่มต้นตัวแทนจะทำหน้าที่เป็นตัวละครและสื่อสารกับผู้อื่น
โฟลว์ถูกใช้เพื่อควบคุมลำดับของการแสดงของตัวละครในฉาก
ผู้กำกับจะใช้ในการตัดสินใจว่าจะจบฉากปัจจุบันและฉากใดที่จะเล่นต่อไป
เสาเป็นเครื่องมือที่ตัวแทนสามารถใช้เพื่อปรับปรุงการแสดงของพวกเขา ตัวแทนสามารถรับข้อมูลภายนอกโดยใช้อุปกรณ์ประกอบฉาก
ไทม์ไลน์เป็นองค์ประกอบรันไทม์หลักของโอเปร่าเพื่อจัดการกระบวนการเซสชัน มันเรียกใช้เซสชันปัจจุบันและสวิตช์ระหว่างเซสชัน ไทม์ไลน์ยังบันทึกข้อมูลทั่วโลกของโอเปร่าและสามารถแบ่งปันโดยตัวแทนทั้งหมด
เซสชันหมายถึงการวิ่งครั้งเดียวของฉาก มันมีตัวระบุที่ไม่ซ้ำกันและฉากที่สอดคล้องกัน
วิธีทั่วไปในการใช้งาน Operagents คือการเขียนไฟล์กำหนดค่าและเรียกใช้ Opera ด้วยเครื่องมือบรรทัดคำสั่ง 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 หากไม่มีการระบุเวอร์ชันเวอร์ชันล่าสุด (มาสเตอร์) จะถูกใช้
ก่อนที่จะเขียน Agent และ Scene Configs เราต้องเรียนรู้เกี่ยวกับการกำหนดค่าเทมเพลต
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 (ไม่บังคับ) สามารถใช้เพื่อกำหนดอุปกรณ์ประกอบฉากของอักขระดูการกำหนดค่า Prop สำหรับรายละเอียดเพิ่มเติม
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 ใช้เพื่อระบุแบบจำลองเพื่อทำนายฉากต่อไปที่จะเล่น หากไม่พบธงเสร็จสิ้นหรือไม่พบชื่อฉากฉากการรักษาจะเล่นต่อไป
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 ฟังก์ชั่นที่กำหนดเองจะได้รับหนึ่งพารามิเตอร์ของประเภท operagents.timeline.Timeline
# module_name.py
from operagents . timeline import Timeline
async def function_name ( timeline : Timeline ) -> None :
pass ประเภท 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 } !" โปรดทราบว่าชื่อและเอกสารของฟังก์ชั่นจะถูกใช้เป็นชื่อและคำอธิบายของเสา นอกจากนี้คุณยังสามารถให้คำอธิบายของ Args โดย Field ของ Pydantic เทมเพลตข้อยกเว้นจะถูกใช้เพื่อแสดงผลเมื่อฟังก์ชั่นทำให้เกิดข้อผิดพลาด
Prop custom
Prop custom จะเรียกคลาส Prop ที่กำหนดเองเมื่อใช้เสา
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 จะเรียกใช้คลาส Hook ที่กำหนดเองเมื่อพบเหตุการณ์ไทม์ไลน์เฉพาะ
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 คลาส Hook อาจมีวิธีการในรูปแบบของ 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เปิดใน codespaces (dev container):
หรือติดตั้งสภาพแวดล้อมการพัฒนาในพื้นที่ด้วย:
poetry install && poetry run pre-commit install