Agentes Personalizados
Puedes tener agentes con comportamientos que no encajan en una configuración predefinida. En esos casos, puedes construir agentes personalizados.
Todos los agentes en AgentChat heredan de la clase BaseChatAgent e implementan los siguientes métodos y atributos abstractos:
on_messages(): El método abstracto que define el comportamiento del agente en respuesta a los mensajes. Este método se llama cuando se le pide al agente que proporcione una respuesta medianterun(). Devuelve un objetoResponse.on_reset(): El método abstracto que reinicia el agente a su estado inicial. Este método se llama cuando se solicita al agente que se reinicie.produced_message_types: La lista de tipos de mensajesBaseChatMessageque el agente puede producir en su respuesta.
Opcionalmente, puedes implementar el método on_messages_stream() para transmitir mensajes a medida que son generados por el agente. Este método es llamado por run_stream() para transmitir mensajes en forma de flujo (streaming). Si este método no está implementado, el agente utiliza la implementación predeterminada de on_messages_stream() que llama a on_messages() y emite todos los mensajes en la respuesta.
Agente de Cuenta Regresiva
En este ejemplo, creamos un agente simple que cuenta regresivamente desde un número dado hasta cero, y produce un flujo de mensajes con el conteo actual.
from typing import AsyncGenerator, List, Sequence
from saptiva_agents.agents import BaseChatAgent
from saptiva_agents.base import Response
from saptiva_agents.messages import BaseAgentEvent, BaseChatMessage, TextMessage
from saptiva_agents.core import CancellationToken
class CountDownAgent(BaseChatAgent):
def __init__(self, name: str, count: int = 3):
super().__init__(name, "A simple agent that counts down.")
self._count = count
@property
def produced_message_types(self) -> Sequence[type[BaseChatMessage]]:
return (TextMessage,)
async def on_messages(self, messages: Sequence[BaseChatMessage], cancellation_token: CancellationToken) -> Response:
# Llama a on_messages_stream.
response: Response | None = None
async for message in self.on_messages_stream(messages, cancellation_token):
if isinstance(message, Response):
response = message
assert response is not None
return response
async def on_messages_stream(
self, messages: Sequence[BaseChatMessage], cancellation_token: CancellationToken
) -> AsyncGenerator[BaseAgentEvent | BaseChatMessage | Response, None]:
inner_messages: List[BaseAgentEvent | BaseChatMessage] = []
for i in range(self._count, 0, -1):
msg = TextMessage(content=f"{i}...", source=self.name)
inner_messages.append(msg)
yield msg
# La respuesta se devuelve al final del stream.
# Contiene el mensaje final y todos los mensajes internos.
yield Response(chat_message=TextMessage(content="Done!", source=self.name), inner_messages=inner_messages)
async def on_reset(self, cancellation_token: CancellationToken) -> None:
pass
async def run_countdown_agent() -> None:
# Crear un agente de cuenta regresiva.
countdown_agent = CountDownAgent("countdown")
# Ejecutar el agente con una tarea dada y transmitir la respuesta.
async for message in countdown_agent.on_messages_stream([], CancellationToken()):
if isinstance(message, Response):
print(message.chat_message.content)
else:
print(message.content)
# Usar asyncio.run(run_countdown_agent()) al ejecutar en un script.
await run_countdown_agent()Agente Aritmético
En este ejemplo, creamos una clase de agente capaz de realizar operaciones aritméticas simples sobre un número entero dado. Luego, utilizaremos distintas instancias de esta clase de agente dentro de un SelectorGroupChat para transformar un número entero en otro mediante la aplicación de una secuencia de operaciones aritméticas.
La clase ArithmeticAgent recibe una función llamada operator_func, la cual toma un número entero y devuelve otro número entero tras aplicarle una operación aritmética. En su método on_messages, aplica la función operator_func al número recibido en el mensaje de entrada y devuelve una respuesta con el resultado.
Ahora podemos crear un SelectorGroupChat con 5 instancias del ArithmeticAgent:
Una que suma 1 al número entero recibido.
Una que resta 1 al número entero recibido.
Una que multiplica por 2 al número entero recibido.
Una que divide entre 2 al número entero recibido y redondea hacia abajo al entero más cercano.
Una que retorna el número entero recibido sin cambios.
Luego, creamos un SelectorGroupChat con estos agentes y configuramos adecuadamente el selector:
Permitimos seleccionar consecutivamente el mismo agente, para posibilitar operaciones repetidas.
Personalizamos el mensaje del selector (
selector_prompt) para adaptar la respuesta del modelo a la tarea específica.
Del resultado, podemos ver que los agentes han transformado con éxito el número entero de entrada de 10 a 25 eligiendo los agentes apropiados que aplican las operaciones aritméticas en secuencia.
Uso de Clientes de Modelos Personalizados en Agentes Personalizados
Una de las características clave del agente predefinido AssistantAgent en AgentChat es que acepta un argumento model_client y puede utilizarlo para responder a los mensajes. Sin embargo, en algunos casos podrías necesitar que tu agente utilice un cliente de modelo personalizado.
Puedes lograr esto mediante la creación de un agente personalizado que implemente tu propio cliente de modelo.
En el ejemplo anterior, hemos optado por proporcionar model, api_key y system_message como argumentos. Sin embargo, tú puedes elegir proporcionar cualquier otro argumento que sea requerido por el cliente de modelo que estés utilizando o que encaje con el diseño de tu aplicación.
Ahora exploremos cómo utilizar este agente personalizado como parte de un equipo en Saptiva-Agents.
En la sección anterior mostramos varios conceptos muy importantes:
Hemos desarrollado un agente personalizado que utiliza 2 modelos para responder mensajes.
Demostramos que este agente personalizado puede utilizarse dentro del ecosistema general de Saptiva-Agents, en este caso como participante en un
RoundRobinGroupChat, siempre que herede de la claseBaseChatAgent.
Última actualización