Equipos
En esta sección, aprenderás a crear un equipo multi-agente (o simplemente equipo) usando Saptiva-Agents. Un equipo es un grupo de agentes que trabajan juntos para lograr un objetivo común.
Primero, te mostraremos cómo crear y dirigir un equipo. Luego, te explicaremos cómo observar el comportamiento del equipo, lo cual es crucial para depurar y entender el rendimiento del equipo, y las operaciones comunes para controlar el comportamiento del Equipo.
Nota
¿Cuándo se debe utilizar un equipo?
Los equipos son para tareas complejas que requieren colaboración y experiencia diversa. Sin embargo, también exigen más estructura para dirigir en comparación con agentes individuales. Mientras que Saptiva-Agents simplifica el proceso de trabajar con equipos, comienza con un agente único para tareas más simples y cambia a un equipo de múltiples agentes cuando un solo agente resulta insuficiente. Asegúrate de haber optimizado tu agente único con las herramientas e instrucciones apropiadas antes de pasar a un enfoque basado en equipo.
Creando un Equipo
RoundRobinGroupChat
es una configuración de equipo simple pero efectiva donde todos los agentes comparten el mismo contexto y se turnan para responder de manera circular. Cada agente, durante su turno, transmite su respuesta a todos los demás agentes, asegurando que todo el equipo mantenga un contexto coherente.
Comenzaremos creando un equipo con dos AssistantAgent
y una condición de TextMentionTermination
que detiene al equipo cuando se detecta una palabra específica en la respuesta del agente.
El equipo de dos agentes implementa el patrón de reflexión, un patrón de diseño multiagente donde un agente crítico evalúa las respuestas de un agente principal.
import asyncio
from saptiva_agents import QWEN_MODEL
from saptiva_agents.agents import AssistantAgent, TaskResult
from saptiva_agents.conditions import ExternalTermination, TextMentionTermination
from saptiva_agents.teams import RoundRobinGroupChat
from saptiva_agents.ui import Console
from saptiva_agents.core import CancellationToken
from saptiva_agents.base import SaptivaAIChatCompletionClient
# Define el cliente de modelo de Saptiva.
model_client = SaptivaAIChatCompletionClient(
model=QWEN_MODEL,
api_key="TU_SAPTIVA_API_KEY",
)
# Crear el agente principal.
primary_agent = AssistantAgent(
"primary",
model_client=model_client,
system_message="You are a helpful AI assistant.",
)
# Crear al agente crítico.
critic_agent = AssistantAgent(
"critic",
model_client=model_client,
system_message="Provide constructive feedback. Respond with 'APPROVE' to when your feedbacks are addressed.",
)
# Definir una condición de terminación que detenga la tarea si el crítico la aprueba.
text_termination = TextMentionTermination("APPROVE")
# Crear un equipo con los agentes primario y crítico.
team = RoundRobinGroupChat([primary_agent, critic_agent], termination_condition=text_termination)
Dirigir un Equipo
Llamemos al método run()
para iniciar el equipo con una tarea.
# Utilice `asyncio.run(...)` cuando lo ejecute en un script
result = await team.run(task="Write a short poem about the fall season.")
print(result)
TaskResult(messages=[TextMessage(source='user', models_usage=None, content='Write a short poem about the fall season.', type='TextMessage'), TextMessage(source='primary', models_usage=RequestUsage(prompt_tokens=28, completion_tokens=109), content="Leaves of amber, gold, and rust, \nDance upon the gentle gust. \nCrisp air whispers tales of old, \nAs daylight wanes, the night grows bold. \n\nPumpkin patch and apple treats, \nLaughter in the street repeats. \nSweaters warm and fires aglow, \nIt's time for nature's vibrant show. \n\nThe harvest moon ascends the sky, \nWhile geese in formation start to fly. \nAutumn speaks in colors bright, \nA fleeting grace, a pure delight. ", type='TextMessage'), TextMessage(source='critic', models_usage=RequestUsage(prompt_tokens=154, completion_tokens=200), content='Your poem beautifully captures the essence of the fall season with vivid imagery and a rhythmic flow. The use of descriptive language like "amber, gold, and rust" effectively paints a visual picture of the changing leaves. Phrases such as "crisp air whispers tales of old" and "daylight wanes, the night grows bold" add a poetic touch by incorporating seasonal characteristics.\n\nHowever, you might consider exploring other sensory details to deepen the reader\'s immersion. For example, mentioning the sound of crunching leaves underfoot or the scent of cinnamon and spices in the air could enhance the sensory experience.\n\nAdditionally, while the mention of "pumpkin patch and apple treats" is evocative of fall, expanding on these elements or including more personal experiences or emotions associated with the season might make the poem more relatable and engaging.\n\nOverall, you\'ve crafted a lovely poem that celebrates the beauty and traditions of autumn with grace and warmth. A few tweaks to include multisensory details could elevate it even further.', type='TextMessage'), TextMessage(source='primary', models_usage=RequestUsage(prompt_tokens=347, completion_tokens=178), content="Thank you for the thoughtful feedback. Here's a revised version of the poem with additional sensory details:\n\nLeaves of amber, gold, and rust, \nDance upon the gentle gust. \nCrisp air whispers tales of old, \nAs daylight wanes, the night grows bold. \n\nCrunch beneath the wandering feet, \nA melody of autumn's beat. \nCinnamon and spices blend, \nIn every breeze, nostalgia sends. \n\nPumpkin patch and apple treats, \nLaughter in the street repeats. \nSweaters warm and fires aglow, \nIt's time for nature's vibrant show. \n\nThe harvest moon ascends the sky, \nWhile geese in formation start to fly. \nAutumn speaks in colors bright, \nA fleeting grace, a pure delight. \n\nI hope this version resonates even more with the spirit of fall. Thank you again for your suggestions!", type='TextMessage'), TextMessage(source='critic', models_usage=RequestUsage(prompt_tokens=542, completion_tokens=3), content='APPROVE', type='TextMessage')], stop_reason="Text 'APPROVE' mentioned")
El equipo ejecuta los agentes hasta que se cumple la condición de terminación. En este caso, el equipo ejecutó agentes siguiendo un orden de ronda hasta que se cumplió la condición de terminación cuando se detectó la palabra "APROBAR" en la respuesta del agente. Cuando el equipo se detiene, devuelve un objeto TaskResult
con todos los mensajes producidos por los agentes en el equipo.
Observando un Equipo
Similar al método on_messages_stream()
del agente, puedes transmitir los mensajes del equipo mientras se ejecuta llamando al método run_stream()
. Este método devuelve un generador que produce los mensajes generados por los agentes del equipo a medida que se generan, con el último elemento siendo el objeto TaskResult
.
# Al ejecutar dentro de un script, usa una función principal asincrónica y llámala con `asyncio.run(...)`.
await team.reset() # Reiniciar el equipo para una nueva tarea.
async for message in team.run_stream(task="Write a short poem about the fall season."): # type: ignore
if isinstance(message, TaskResult):
print("Stop Reason:", message.stop_reason)
else:
print(message)
source='user' models_usage=None content='Write a short poem about the fall season.' type='TextMessage'
source='primary' models_usage=RequestUsage(prompt_tokens=28, completion_tokens=105) content="Leaves descend in golden dance, \nWhispering secrets as they fall, \nCrisp air brings a gentle trance, \nHeralding Autumn's call. \n\nPumpkins glow with orange light, \nFields wear a cloak of amber hue, \nDays retreat to longer night, \nSkies shift to deeper blue. \n\nWinds carry scents of earth and pine, \nSweaters wrap us, warm and tight, \nNature's canvas, bold design, \nIn Fall's embrace, we find delight. " type='TextMessage'
source='critic' models_usage=RequestUsage(prompt_tokens=150, completion_tokens=226) content='Your poem beautifully captures the essence of fall with vivid imagery and a soothing rhythm. The imagery of leaves descending, pumpkins glowing, and fields cloaked in amber hues effectively paints a picture of the autumn season. The use of contrasting elements like "Days retreat to longer night" and "Sweaters wrap us, warm and tight" provides a nice balance between the cold and warmth associated with the season. Additionally, the personification of autumn through phrases like "Autumn\'s call" and "Nature\'s canvas, bold design" adds depth to the depiction of fall.\n\nTo enhance the poem further, you might consider focusing on the soundscape of fall, such as the rustling of leaves or the distant call of migrating birds, to engage readers\' auditory senses. Also, varying the line lengths slightly could add a dynamic flow to the reading experience.\n\nOverall, your poem is engaging and effectively encapsulates the beauty and transition of fall. With a few adjustments to explore other sensory details, it could become even more immersive. \n\nIf you incorporate some of these suggestions or find another way to expand the sensory experience, please share your update!' type='TextMessage'
source='primary' models_usage=RequestUsage(prompt_tokens=369, completion_tokens=143) content="Thank you for the thoughtful critique and suggestions. Here's a revised version of the poem with added attention to auditory senses and varied line lengths:\n\nLeaves descend in golden dance, \nWhisper secrets in their fall, \nBreezes hum a gentle trance, \nHeralding Autumn's call. \n\nPumpkins glow with orange light, \nAmber fields beneath wide skies, \nDays retreat to longer night, \nChill winds and distant cries. \n\nRustling whispers of the trees, \nSweaters wrap us, snug and tight, \nNature's canvas, bold and free, \nIn Fall's embrace, pure delight. \n\nI appreciate your feedback and hope this version better captures the sensory richness of the season!" type='TextMessage'
source='critic' models_usage=RequestUsage(prompt_tokens=529, completion_tokens=160) content='Your revised poem is a beautiful enhancement of the original. By incorporating auditory elements such as "Breezes hum" and "Rustling whispers of the trees," you\'ve added an engaging soundscape that draws the reader deeper into the experience of fall. The varied line lengths work well to create a more dynamic rhythm throughout the poem, adding interest and variety to each stanza.\n\nThe succinct, yet vivid, lines of "Chill winds and distant cries" wonderfully evoke the atmosphere of the season, adding a touch of mystery and depth. The final stanza wraps up the poem nicely, celebrating the complete sensory embrace of fall with lines like "Nature\'s canvas, bold and free."\n\nYou\'ve successfully infused more sensory richness into the poem, enhancing its overall emotional and atmospheric impact. Great job on the revisions!\n\nAPPROVE' type='TextMessage'
Stop Reason: Text 'APPROVE' mentioned
Como se demuestra en el ejemplo anterior, puedes determinar la razón por la que el equipo se detuvo comprobando el atributo stop_reason
.
El método Console()
proporciona una forma conveniente de imprimir mensajes en la consola con el formato adecuado.
await team.reset() # Reiniciar el equipo para una nueva tarea.
await Console(team.run_stream(task="Write a short poem about the fall season.")) # Transmitir los mensajes a la consola.
---------- user ----------
Write a short poem about the fall season.
---------- primary ----------
Golden leaves in crisp air dance,
Whispering tales as they prance.
Amber hues paint the ground,
Nature's symphony all around.
Sweaters hug with tender grace,
While pumpkins smile, a warm embrace.
Chill winds hum through towering trees,
A vibrant tapestry in the breeze.
Harvest moons in twilight glow,
Casting magic on fields below.
Fall's embrace, a gentle call,
To savor beauty before snowfalls.
[Prompt tokens: 28, Completion tokens: 99]
---------- critic ----------
Your poem beautifully captures the essence of the fall season, creating a vivid and cozy atmosphere. The imagery of golden leaves and amber hues paints a picturesque scene that many can easily relate to. I particularly appreciate the personification of pumpkins and the gentle embrace of sweaters, which adds warmth to your verses.
To enhance the poem further, you might consider adding more sensory details to make the reader feel even more immersed in the experience. For example, including specific sounds, scents, or textures could deepen the connection to autumn's ambiance. Additionally, you could explore the emotional transitions as the season prepares for winter to provide a reflective element to the piece.
Overall, it's a lovely and evocative depiction of fall, evoking feelings of comfort and appreciation for nature's changing beauty. Great work!
[Prompt tokens: 144, Completion tokens: 157]
---------- primary ----------
Thank you for your thoughtful feedback! I'm glad you enjoyed the imagery and warmth in the poem. To enhance the sensory experience and emotional depth, here's a revised version incorporating your suggestions:
---
Golden leaves in crisp air dance,
Whispering tales as they prance.
Amber hues paint the crunchy ground,
Nature's symphony all around.
Sweaters hug with tender grace,
While pumpkins grin, a warm embrace.
Chill winds hum through towering trees,
Crackling fires warm the breeze.
Apples in the orchard's glow,
Sweet cider scents that overflow.
Crunch of paths beneath our feet,
Cinnamon spice and toasty heat.
Harvest moons in twilight's glow,
Casting magic on fields below.
Fall's embrace, a gentle call,
Reflects on life's inevitable thaw.
---
I hope this version enhances the sensory and emotional elements of the season. Thank you again for your insights!
[Prompt tokens: 294, Completion tokens: 195]
---------- critic ----------
APPROVE
[Prompt tokens: 506, Completion tokens: 4]
---------- Summary ----------
Number of messages: 5
Finish reason: Text 'APPROVE' mentioned
Total prompt tokens: 972
Total completion tokens: 455
Duration: 11.78 seconds
TaskResult(messages=[TextMessage(source='user', models_usage=None, content='Write a short poem about the fall season.', type='TextMessage'), TextMessage(source='primary', models_usage=RequestUsage(prompt_tokens=28, completion_tokens=99), content="Golden leaves in crisp air dance, \nWhispering tales as they prance. \nAmber hues paint the ground, \nNature's symphony all around. \n\nSweaters hug with tender grace, \nWhile pumpkins smile, a warm embrace. \nChill winds hum through towering trees, \nA vibrant tapestry in the breeze. \n\nHarvest moons in twilight glow, \nCasting magic on fields below. \nFall's embrace, a gentle call, \nTo savor beauty before snowfalls. ", type='TextMessage'), TextMessage(source='critic', models_usage=RequestUsage(prompt_tokens=144, completion_tokens=157), content="Your poem beautifully captures the essence of the fall season, creating a vivid and cozy atmosphere. The imagery of golden leaves and amber hues paints a picturesque scene that many can easily relate to. I particularly appreciate the personification of pumpkins and the gentle embrace of sweaters, which adds warmth to your verses. \n\nTo enhance the poem further, you might consider adding more sensory details to make the reader feel even more immersed in the experience. For example, including specific sounds, scents, or textures could deepen the connection to autumn's ambiance. Additionally, you could explore the emotional transitions as the season prepares for winter to provide a reflective element to the piece.\n\nOverall, it's a lovely and evocative depiction of fall, evoking feelings of comfort and appreciation for nature's changing beauty. Great work!", type='TextMessage'), TextMessage(source='primary', models_usage=RequestUsage(prompt_tokens=294, completion_tokens=195), content="Thank you for your thoughtful feedback! I'm glad you enjoyed the imagery and warmth in the poem. To enhance the sensory experience and emotional depth, here's a revised version incorporating your suggestions:\n\n---\n\nGolden leaves in crisp air dance, \nWhispering tales as they prance. \nAmber hues paint the crunchy ground, \nNature's symphony all around. \n\nSweaters hug with tender grace, \nWhile pumpkins grin, a warm embrace. \nChill winds hum through towering trees, \nCrackling fires warm the breeze. \n\nApples in the orchard's glow, \nSweet cider scents that overflow. \nCrunch of paths beneath our feet, \nCinnamon spice and toasty heat. \n\nHarvest moons in twilight's glow, \nCasting magic on fields below. \nFall's embrace, a gentle call, \nReflects on life's inevitable thaw. \n\n--- \n\nI hope this version enhances the sensory and emotional elements of the season. Thank you again for your insights!", type='TextMessage'), TextMessage(source='critic', models_usage=RequestUsage(prompt_tokens=506, completion_tokens=4), content='APPROVE', type='TextMessage')], stop_reason="Text 'APPROVE' mentioned")
Reiniciar un Equipo
Puede restablecer el equipo llamando al método reset()
. Este método limpiará el estado del equipo, incluyendo todos los agentes. Llamará al método on_reset()
de cada agente para limpiar el estado del agente.
await team.reset() # Reiniciar el equipo para una próxima ejecución.
Por lo general, es una buena idea reiniciar el equipo si la siguiente tarea no está relacionada con la tarea anterior. Sin embargo, si la siguiente tarea está relacionada con la anterior, no es necesario reiniciar y se puede continuar con el equipo.
Detener un Equipo
Además de las condiciones de terminación automática, como TextMentionTermination
, que detienen el equipo según el estado interno del mismo, también puedes detener al equipo desde fuera utilizando el ExternalTermination
.
Al llamar a set()
en ExternalTermination
se detendrá el equipo cuando termine el turno del agente actual. Por lo tanto, el equipo puede no detenerse de inmediato. Esto permite que el agente actual finalice su turno y transmita el mensaje final al equipo antes de detenerse, manteniendo el estado del equipo consistente.
# Crear un nuevo equipo con una condición de terminación externa.
external_termination = ExternalTermination()
team = RoundRobinGroupChat(
[primary_agent, critic_agent],
termination_condition=external_termination | text_termination, # Usa el operador OR bit a bit para combinar condiciones.
)
# Ejecutar el equipo en una tarea en segundo plano.
run = asyncio.create_task(Console(team.run_stream(task="Write a short poem about the fall season.")))
# Espera cierto tiempo.
await asyncio.sleep(0.1)
# Detener el equipo.
external_termination.set()
# Espera a que el equipo termine.
await run
---------- user ----------
Write a short poem about the fall season.
---------- primary ----------
Leaves of amber, gold, and red,
Gently drifting from trees overhead.
Whispers of wind through the crisp, cool air,
Nature's canvas painted with care.
Harvest moons and evenings that chill,
Fields of plenty on every hill.
Sweaters wrapped tight as twilight nears,
Fall's charming embrace, as warm as it appears.
Pumpkins aglow with autumn's light,
Harvest feasts and stars so bright.
In every leaf and breeze that calls,
We find the magic of glorious fall.
[Prompt tokens: 28, Completion tokens: 114]
---------- Summary ----------
Number of messages: 2
Finish reason: External termination requested
Total prompt tokens: 28
Total completion tokens: 114
Duration: 1.71 seconds
TaskResult(messages=[TextMessage(source='user', models_usage=None, content='Write a short poem about the fall season.', type='TextMessage'), TextMessage(source='primary', models_usage=RequestUsage(prompt_tokens=28, completion_tokens=114), content="Leaves of amber, gold, and red, \nGently drifting from trees overhead. \nWhispers of wind through the crisp, cool air, \nNature's canvas painted with care. \n\nHarvest moons and evenings that chill, \nFields of plenty on every hill. \nSweaters wrapped tight as twilight nears, \nFall's charming embrace, as warm as it appears. \n\nPumpkins aglow with autumn's light, \nHarvest feasts and stars so bright. \nIn every leaf and breeze that calls, \nWe find the magic of glorious fall. ", type='TextMessage')], stop_reason='External termination requested')
Del resultado anterior, se puede ver que el equipo se detuvo porque se cumplió la condición de terminación externa, pero el agente de habla pudo terminar su turno antes de que el equipo se detuviera.
Reanudar un Equipo
Los equipos son con estado y mantienen el historial de la conversación y el contexto después de cada ejecución, a menos que restablezcas el equipo.
Puedes reanudar un equipo para continuar desde donde lo dejó llamando nuevamente al método run()
o run_stream()
sin una nueva tarea. RoundRobinGroupChat
continuará desde el siguiente agente en el orden round-robin.
await Console(team.run_stream()) # Reanudar el equipo para continuar con la siguiente tarea.
---------- critic ----------
This poem beautifully captures the essence of the fall season with vivid imagery and a soothing rhythm. The descriptions of the changing leaves, cool air, and various autumn traditions make it easy for readers to envision and feel the charm of fall. Here are a few suggestions to enhance its impact:
1. **Structure Variation**: Consider breaking some lines with a hyphen or ellipsis for dramatic effect or emphasis. For instance, “Sweaters wrapped tight as twilight nears— / Fall’s charming embrace, as warm as it appears."
2. **Sensory Details**: While the poem already evokes visual and tactile senses, incorporating other senses such as sound or smell could deepen the immersion. For example, include the scent of wood smoke or the crunch of leaves underfoot.
3. **Metaphorical Language**: Adding metaphors or similes can further enrich the imagery. For example, you might compare the leaves falling to a golden rain or the chill in the air to a gentle whisper.
Overall, it’s a lovely depiction of fall. These suggestions are minor tweaks that might elevate the reader's experience even further. Nice work!
Let me know if these feedbacks are addressed.
[Prompt tokens: 159, Completion tokens: 237]
---------- primary ----------
Thank you for the thoughtful feedback! Here’s a revised version, incorporating your suggestions:
Leaves of amber, gold—drifting like dreams,
A golden rain from trees’ canopies.
Whispers of wind—a gentle breath,
Nature’s scented tapestry embracing earth.
Harvest moons rise as evenings chill,
Fields of plenty paint every hill.
Sweaters wrapped tight as twilight nears—
Fall’s embrace, warm as whispered years.
Pumpkins aglow with autumn’s light,
Crackling leaves underfoot in flight.
In every leaf and breeze that calls,
We find the magic of glorious fall.
I hope these changes enhance the imagery and sensory experience. Thank you again for your feedback!
[Prompt tokens: 389, Completion tokens: 150]
---------- critic ----------
Your revisions have made the poem even more evocative and immersive. The use of sensory details, such as "whispers of wind" and "crackling leaves," beautifully enriches the poem, engaging multiple senses. The metaphorical language, like "a golden rain from trees’ canopies" and "Fall’s embrace, warm as whispered years," adds depth and enhances the emotional warmth of the poem. The structural variation with the inclusion of dashes effectively adds emphasis and flow.
Overall, these changes bring greater vibrancy and life to the poem, allowing readers to truly experience the wonders of fall. Excellent work on the revisions!
APPROVE
[Prompt tokens: 556, Completion tokens: 132]
---------- Summary ----------
Number of messages: 3
Finish reason: Text 'APPROVE' mentioned
Total prompt tokens: 1104
Total completion tokens: 519
Duration: 9.79 seconds
TaskResult(messages=[TextMessage(source='critic', models_usage=RequestUsage(prompt_tokens=159, completion_tokens=237), content='This poem beautifully captures the essence of the fall season with vivid imagery and a soothing rhythm. The descriptions of the changing leaves, cool air, and various autumn traditions make it easy for readers to envision and feel the charm of fall. Here are a few suggestions to enhance its impact:\n\n1. **Structure Variation**: Consider breaking some lines with a hyphen or ellipsis for dramatic effect or emphasis. For instance, “Sweaters wrapped tight as twilight nears— / Fall’s charming embrace, as warm as it appears."\n\n2. **Sensory Details**: While the poem already evokes visual and tactile senses, incorporating other senses such as sound or smell could deepen the immersion. For example, include the scent of wood smoke or the crunch of leaves underfoot.\n\n3. **Metaphorical Language**: Adding metaphors or similes can further enrich the imagery. For example, you might compare the leaves falling to a golden rain or the chill in the air to a gentle whisper.\n\nOverall, it’s a lovely depiction of fall. These suggestions are minor tweaks that might elevate the reader\'s experience even further. Nice work!\n\nLet me know if these feedbacks are addressed.', type='TextMessage'), TextMessage(source='primary', models_usage=RequestUsage(prompt_tokens=389, completion_tokens=150), content='Thank you for the thoughtful feedback! Here’s a revised version, incorporating your suggestions: \n\nLeaves of amber, gold—drifting like dreams, \nA golden rain from trees’ canopies. \nWhispers of wind—a gentle breath, \nNature’s scented tapestry embracing earth. \n\nHarvest moons rise as evenings chill, \nFields of plenty paint every hill. \nSweaters wrapped tight as twilight nears— \nFall’s embrace, warm as whispered years. \n\nPumpkins aglow with autumn’s light, \nCrackling leaves underfoot in flight. \nIn every leaf and breeze that calls, \nWe find the magic of glorious fall. \n\nI hope these changes enhance the imagery and sensory experience. Thank you again for your feedback!', type='TextMessage'), TextMessage(source='critic', models_usage=RequestUsage(prompt_tokens=556, completion_tokens=132), content='Your revisions have made the poem even more evocative and immersive. The use of sensory details, such as "whispers of wind" and "crackling leaves," beautifully enriches the poem, engaging multiple senses. The metaphorical language, like "a golden rain from trees’ canopies" and "Fall’s embrace, warm as whispered years," adds depth and enhances the emotional warmth of the poem. The structural variation with the inclusion of dashes effectively adds emphasis and flow. \n\nOverall, these changes bring greater vibrancy and life to the poem, allowing readers to truly experience the wonders of fall. Excellent work on the revisions!\n\nAPPROVE', type='TextMessage')], stop_reason="Text 'APPROVE' mentioned")
Puedes ver que el equipo retomó desde donde lo dejó en la salida anterior, y el primer mensaje es del siguiente agente después del último agente que habló antes de que el equipo se detuviera.
Reanudemos el equipo nuevamente con una nueva tarea mientras mantenemos el contexto sobre la tarea anterior.
# La nueva tarea es traducir el mismo poema al estilo de poesía china Tang.
await Console(team.run_stream(task="将这首诗用中文唐诗风格写一遍。"))
---------- user ----------
将这首诗用中文唐诗风格写一遍。
---------- primary ----------
朔风轻拂叶飘金,
枝上斜阳染秋林。
满山丰收人欢喜,
月明归途衣渐紧。
南瓜影映灯火中,
落叶沙沙伴归程。
片片秋意随风起,
秋韵悠悠心自明。
[Prompt tokens: 700, Completion tokens: 77]
---------- critic ----------
这首改编的唐诗风格诗作成功地保留了原诗的意境与情感,体现出秋季特有的氛围和美感。通过“朔风轻拂叶飘金”、“枝上斜阳染秋林”等意象,生动地描绘出了秋天的景色,与唐诗中的自然意境相呼应。且“月明归途衣渐紧”、“落叶沙沙伴归程”让人感受到秋天的安宁与温暖。
通过这些诗句,读者能够感受到秋天的惬意与宁静,勾起丰收与团圆的画面,是一次成功的翻译改编。
APPROVE
[Prompt tokens: 794, Completion tokens: 161]
---------- Summary ----------
Number of messages: 3
Finish reason: Text 'APPROVE' mentioned
Total prompt tokens: 1494
Total completion tokens: 238
Duration: 3.89 seconds
TaskResult(messages=[TextMessage(source='user', models_usage=None, content='将这首诗用中文唐诗风格写一遍。', type='TextMessage'), TextMessage(source='primary', models_usage=RequestUsage(prompt_tokens=700, completion_tokens=77), content='朔风轻拂叶飘金, \n枝上斜阳染秋林。 \n满山丰收人欢喜, \n月明归途衣渐紧。 \n\n南瓜影映灯火中, \n落叶沙沙伴归程。 \n片片秋意随风起, \n秋韵悠悠心自明。 ', type='TextMessage'), TextMessage(source='critic', models_usage=RequestUsage(prompt_tokens=794, completion_tokens=161), content='这首改编的唐诗风格诗作成功地保留了原诗的意境与情感,体现出秋季特有的氛围和美感。通过“朔风轻拂叶飘金”、“枝上斜阳染秋林”等意象,生动地描绘出了秋天的景色,与唐诗中的自然意境相呼应。且“月明归途衣渐紧”、“落叶沙沙伴归程”让人感受到秋天的安宁与温暖。\n\n通过这些诗句,读者能够感受到秋天的惬意与宁静,勾起丰收与团圆的画面,是一次成功的翻译改编。\n\nAPPROVE', type='TextMessage')], stop_reason="Text 'APPROVE' mentioned")
Abortar un Equipo
Puede abortar una llamada a run()
o run_stream()
durante la ejecución configurando un CancellationToken
pasado al parámetro cancellation_token
.
Distinto a detener un equipo, abortar un equipo detendrá inmediatamente el equipo y generará una excepción CancelledError
.
Nota
Quien llama recibirá una excepción CancelledError
cuando el equipo sea abortado.
# Crea un token de cancelación.
cancellation_token = CancellationToken()
# Usa otra corrutina para dirigir el equipo.
run = asyncio.create_task(
team.run(
task="Translate the poem to Spanish.",
cancellation_token=cancellation_token,
)
)
# Cancelar la ejecución.
cancellation_token.cancel()
try:
result = await run # Esto generará un CancelledError.
except asyncio.CancelledError:
print("Task was cancelled.")
Task was cancelled.
Equipo de Agente Único
A menudo, puede que desees ejecutar un solo agente en una configuración de equipo. Esto es útil para ejecutar el AssistantAgent
en un bucle hasta que se cumpla una condición.
Esto es diferente de ejecutar el AssistantAgent
usando su método run()
o run_stream()
, que solo ejecuta el agente por un paso y devuelve el resultado. Consulte AssistantAgent
para más detalles sobre un solo paso.
A continuación se presenta un ejemplo de ejecución de un solo agente en una configuración de equipo RoundRobinGroupChat
con una condición de terminación TextMessageTermination
. La tarea es incrementar un número hasta que alcance 10 usando una herramienta. El agente seguirá llamando a la herramienta hasta que el número llegue a 10, y luego devolverá un TextMessage
final que detendrá la ejecución.
from saptiva_agents import LLAMA_MODEL
from saptiva_agents.agents import AssistantAgent
from saptiva_agents.conditions import TextMessageTermination
from saptiva_agents.teams import RoundRobinGroupChat
from saptiva_agents.ui import Console
from saptiva_agents.base import SaptivaAIChatCompletionClient
model_client = SaptivaAIChatCompletionClient(
model=LLAMA_MODEL,
api_key="TU_SAPTIVA_API_KEY",
# Deshabilitar llamadas a herramientas paralelas para este ejemplo.
parallel_tool_calls=False, # type: ignore
)
# Crea una herramienta para incrementar un número.
def increment_number(number: int) -> int:
"""Increment a number by 1."""
return number + 1
# Cree un agente de herramientas que utilice la función increment_number.
looped_assistant = AssistantAgent(
"looped_assistant",
model_client=model_client,
tools=[increment_number], # Registra la herramienta.
system_message="You are a helpful AI assistant, use the tool to increment the number.",
)
# Condición de terminación que detiene la tarea si el agente responde con un mensaje de texto.
termination_condition = TextMessageTermination("looped_assistant")
# Crear un equipo con el agente asistente en bucle y la condición de terminación.
team = RoundRobinGroupChat(
[looped_assistant],
termination_condition=termination_condition,
)
# Ejecutar el equipo con una tarea e imprimir los mensajes en la consola.
async for message in team.run_stream(task="Increment the number 5 to 10."): # tipo: ignore
print(type(message).__name__, message)
TextMessage source='user' models_usage=None metadata={} content='Increment the number 5 to 10.' type='TextMessage'
ToolCallRequestEvent source='looped_assistant' models_usage=RequestUsage(prompt_tokens=75, completion_tokens=15) metadata={} content=[FunctionCall(id='call_qTDXSouN3MtGDqa8l0DM1ciD', arguments='{"number":5}', name='increment_number')] type='ToolCallRequestEvent'
ToolCallExecutionEvent source='looped_assistant' models_usage=None metadata={} content=[FunctionExecutionResult(content='6', name='increment_number', call_id='call_qTDXSouN3MtGDqa8l0DM1ciD', is_error=False)] type='ToolCallExecutionEvent'
ToolCallSummaryMessage source='looped_assistant' models_usage=None metadata={} content='6' type='ToolCallSummaryMessage'
ToolCallRequestEvent source='looped_assistant' models_usage=RequestUsage(prompt_tokens=103, completion_tokens=15) metadata={} content=[FunctionCall(id='call_VGZPlsFVVdyxutR63Yr087pt', arguments='{"number":6}', name='increment_number')] type='ToolCallRequestEvent'
ToolCallExecutionEvent source='looped_assistant' models_usage=None metadata={} content=[FunctionExecutionResult(content='7', name='increment_number', call_id='call_VGZPlsFVVdyxutR63Yr087pt', is_error=False)] type='ToolCallExecutionEvent'
ToolCallSummaryMessage source='looped_assistant' models_usage=None metadata={} content='7' type='ToolCallSummaryMessage'
ToolCallRequestEvent source='looped_assistant' models_usage=RequestUsage(prompt_tokens=131, completion_tokens=15) metadata={} content=[FunctionCall(id='call_VRKGPqPM9AHoef2g2kgsKwZe', arguments='{"number":7}', name='increment_number')] type='ToolCallRequestEvent'
ToolCallExecutionEvent source='looped_assistant' models_usage=None metadata={} content=[FunctionExecutionResult(content='8', name='increment_number', call_id='call_VRKGPqPM9AHoef2g2kgsKwZe', is_error=False)] type='ToolCallExecutionEvent'
ToolCallSummaryMessage source='looped_assistant' models_usage=None metadata={} content='8' type='ToolCallSummaryMessage'
ToolCallRequestEvent source='looped_assistant' models_usage=RequestUsage(prompt_tokens=159, completion_tokens=15) metadata={} content=[FunctionCall(id='call_TOUMjSCG2kVdFcw2CMeb5DYX', arguments='{"number":8}', name='increment_number')] type='ToolCallRequestEvent'
ToolCallExecutionEvent source='looped_assistant' models_usage=None metadata={} content=[FunctionExecutionResult(content='9', name='increment_number', call_id='call_TOUMjSCG2kVdFcw2CMeb5DYX', is_error=False)] type='ToolCallExecutionEvent'
ToolCallSummaryMessage source='looped_assistant' models_usage=None metadata={} content='9' type='ToolCallSummaryMessage'
ToolCallRequestEvent source='looped_assistant' models_usage=RequestUsage(prompt_tokens=187, completion_tokens=15) metadata={} content=[FunctionCall(id='call_wjq7OO9Kf5YYurWGc5lsqttJ', arguments='{"number":9}', name='increment_number')] type='ToolCallRequestEvent'
ToolCallExecutionEvent source='looped_assistant' models_usage=None metadata={} content=[FunctionExecutionResult(content='10', name='increment_number', call_id='call_wjq7OO9Kf5YYurWGc5lsqttJ', is_error=False)] type='ToolCallExecutionEvent'
ToolCallSummaryMessage source='looped_assistant' models_usage=None metadata={} content='10' type='ToolCallSummaryMessage'
TextMessage source='looped_assistant' models_usage=RequestUsage(prompt_tokens=215, completion_tokens=15) metadata={} content='The number 5 incremented to 10 is 10.' type='TextMessage'
TaskResult TaskResult(messages=[TextMessage(source='user', models_usage=None, metadata={}, content='Increment the number 5 to 10.', type='TextMessage'), ToolCallRequestEvent(source='looped_assistant', models_usage=RequestUsage(prompt_tokens=75, completion_tokens=15), metadata={}, content=[FunctionCall(id='call_qTDXSouN3MtGDqa8l0DM1ciD', arguments='{"number":5}', name='increment_number')], type='ToolCallRequestEvent'), ToolCallExecutionEvent(source='looped_assistant', models_usage=None, metadata={}, content=[FunctionExecutionResult(content='6', name='increment_number', call_id='call_qTDXSouN3MtGDqa8l0DM1ciD', is_error=False)], type='ToolCallExecutionEvent'), ToolCallSummaryMessage(source='looped_assistant', models_usage=None, metadata={}, content='6', type='ToolCallSummaryMessage'), ToolCallRequestEvent(source='looped_assistant', models_usage=RequestUsage(prompt_tokens=103, completion_tokens=15), metadata={}, content=[FunctionCall(id='call_VGZPlsFVVdyxutR63Yr087pt', arguments='{"number":6}', name='increment_number')], type='ToolCallRequestEvent'), ToolCallExecutionEvent(source='looped_assistant', models_usage=None, metadata={}, content=[FunctionExecutionResult(content='7', name='increment_number', call_id='call_VGZPlsFVVdyxutR63Yr087pt', is_error=False)], type='ToolCallExecutionEvent'), ToolCallSummaryMessage(source='looped_assistant', models_usage=None, metadata={}, content='7', type='ToolCallSummaryMessage'), ToolCallRequestEvent(source='looped_assistant', models_usage=RequestUsage(prompt_tokens=131, completion_tokens=15), metadata={}, content=[FunctionCall(id='call_VRKGPqPM9AHoef2g2kgsKwZe', arguments='{"number":7}', name='increment_number')], type='ToolCallRequestEvent'), ToolCallExecutionEvent(source='looped_assistant', models_usage=None, metadata={}, content=[FunctionExecutionResult(content='8', name='increment_number', call_id='call_VRKGPqPM9AHoef2g2kgsKwZe', is_error=False)], type='ToolCallExecutionEvent'), ToolCallSummaryMessage(source='looped_assistant', models_usage=None, metadata={}, content='8', type='ToolCallSummaryMessage'), ToolCallRequestEvent(source='looped_assistant', models_usage=RequestUsage(prompt_tokens=159, completion_tokens=15), metadata={}, content=[FunctionCall(id='call_TOUMjSCG2kVdFcw2CMeb5DYX', arguments='{"number":8}', name='increment_number')], type='ToolCallRequestEvent'), ToolCallExecutionEvent(source='looped_assistant', models_usage=None, metadata={}, content=[FunctionExecutionResult(content='9', name='increment_number', call_id='call_TOUMjSCG2kVdFcw2CMeb5DYX', is_error=False)], type='ToolCallExecutionEvent'), ToolCallSummaryMessage(source='looped_assistant', models_usage=None, metadata={}, content='9', type='ToolCallSummaryMessage'), ToolCallRequestEvent(source='looped_assistant', models_usage=RequestUsage(prompt_tokens=187, completion_tokens=15), metadata={}, content=[FunctionCall(id='call_wjq7OO9Kf5YYurWGc5lsqttJ', arguments='{"number":9}', name='increment_number')], type='ToolCallRequestEvent'), ToolCallExecutionEvent(source='looped_assistant', models_usage=None, metadata={}, content=[FunctionExecutionResult(content='10', name='increment_number', call_id='call_wjq7OO9Kf5YYurWGc5lsqttJ', is_error=False)], type='ToolCallExecutionEvent'), ToolCallSummaryMessage(source='looped_assistant', models_usage=None, metadata={}, content='10', type='ToolCallSummaryMessage'), TextMessage(source='looped_assistant', models_usage=RequestUsage(prompt_tokens=215, completion_tokens=15), metadata={}, content='The number 5 incremented to 10 is 10.', type='TextMessage')], stop_reason="Text message received from 'looped_assistant'")
La clave es centrarse en la condición de finalización. En este ejemplo, usamos una condición de TextMessageTermination
que detiene al equipo cuando el agente deja de producir ToolCallSummaryMessage
. El equipo seguirá funcionando hasta que el agente produzca un TextMessage
con el resultado final.
Última actualización