AutoGen:终止条件和管理状态(Termination & Managing State)

  • 👉👉👉本人承接各类AI相关应用开发项目(包括但不限于大模型微调、RAG、AI智能体、NLP、机器学习算法、运筹优化算法、数据分析EDA等) !!!
  • 👉👉👉 有意愿请私信!!!

终止 (Termination)

在我的上一篇博客中,我们探索了如何定义智能体,并将它们组织成可以解决任务的团队。 然而,程序执行可能会无限期地进行下去,在许多情况下,我们需要知道何时停止它们。 这就是终止条件的作用。

AgentChat 通过提供一个基础的 TerminationCondition 类和几个继承自该类的实现来支持多种终止条件。

终止条件是一个可调用对象,它接收一个自上次调用条件以来的一系列  AgentEvent或  ChatMessage 对象,如果对话应该终止,则返回一个  StopMessage,否则返回 None。 一旦达到终止条件,必须通过调用  reset()来重置它,然后才能再次使用。

关于终止条件的一些重要注意事项:

  • 它们是有状态的,但在每次运行(run() 或  run_stream())结束后会自动重置。

  • 它们可以使用 AND 和 OR 运算符进行组合。

注意: 对于群聊团队(即 RoundRobinGroupChatSelectorGroupChat 和 Swarm),终止条件在每个智能体响应后调用。 虽然响应可能包含多个内部消息,但团队仅对来自单个响应的所有消息调用一次其终止条件。 因此,条件使用自上次调用以来的“增量序列”消息调用。

内置终止条件:

  1. MaxMessageTermination:在生成指定数量的消息(包括智能体和任务消息)后停止。

  2. TextMentionTermination:当在消息中提及特定文本或字符串时停止(例如,“TERMINATE”)。

  3. TokenUsageTermination:当达到某个数量的提示或完成令牌时停止。 这需要智能体在其消息中报告令牌使用情况。

  4. TimeoutTermination:在经过指定持续时间(以秒为单位)后停止。

  5. HandoffTermination:当请求切换到特定目标时停止。 切换消息可用于构建诸如  Swarm 之类的模式。 当你希望暂停运行并允许应用程序或用户在智能体切换到他们时提供输入时,这非常有用。

  6. SourceMatchTermination:在特定智能体响应后停止。

  7. ExternalTermination:允许从运行外部以编程方式控制终止。 这对于 UI 集成非常有用(例如,聊天界面中的“停止”按钮)。

  8. StopMessageTermination:当智能体生成  StopMessage 时停止。

为了演示终止条件的特性,我们还是沿用前一篇文章的成语接龙的例子:我们创建2个智能体,用户开始时说一个字,然后由这两个智能体交替进行成语接龙。只不过我们在这里设置了最大消息数为5,这样在消息总数达到5时程序就会自动停止。

from autogen_agentchat.agents import AssistantAgent
from autogen_agentchat.conditions import MaxMessageTermination, TextMentionTermination
from autogen_agentchat.teams import RoundRobinGroupChat
from autogen_agentchat.ui import Console
from autogen_ext.models.openai import OpenAIChatCompletionClient

#创建grok 模型客户端
model_client = OpenAIChatCompletionClient(
    model="grok-2-latest",
    base_url="https://api.x.ai/v1",
    api_key="xai-XXXXXXX",
    model_info={
        "vision": True,
        "function_calling": True,
        "json_output": True,
        "family": "unknown",
    },
    )


agent1 = AssistantAgent(
    name="agent1",
    model_client=model_client,  # 使用模型客户端
    system_message="""你是一个成语接龙高手。 你会接收一个成语。
    你需要以前一个成语的最后一个字为开头,回复一个成语。回复时只需要包含成语本身,
    不要有多余的文字。如果找不出来,请发送“过”。""",
)

agent2 = AssistantAgent(
    name="agent2",
    model_client=model_client,  # 使用模型客户端
    system_message="""你是一个成语接龙高手。 你会接收一个成语。
    你需要以前一个成语的最后一个字为开头,回复一个成语。
    回复时只需要包含成语本身,不要有多余的文字。如果找不出来,请发送“过”。""",
)

让我们探索一下终止条件如何在每次 run 或 run_stream 调用后自动重置,从而允许团队从上次停止的地方恢复对话。

max_msg_termination = MaxMessageTermination(max_messages=5)
round_robin_team = RoundRobinGroupChat([agent1, agent2], 
                                       termination_condition=max_msg_termination)

# 如果你将此脚本作为独立脚本运行,请使用 asyncio.run(...)。
await Console(round_robin_team.run_stream(task="天"))

对话在达到最大消息限制后停止,所以 agent1 智能体没有机会继续接龙,下面让我们继续对话。 

# 如果你将此脚本作为独立脚本运行,请使用 asyncio.run(...)。
await Console(round_robin_team.run_stream())

团队从上次停止的地方继续,允许agent1智能体响应反馈。

接下来,让我们展示如何使用 AND (&) 和 OR (|) 运算符组合终止条件以创建更复杂的终止逻辑。 例如,我们将创建一个团队,该团队在生成 10 条消息后或当评论员智能体批准消息时停止。

max_msg_termination = MaxMessageTermination(max_messages=10)
text_termination = TextMentionTermination("隐姓埋名")
combined_termination = max_msg_termination | text_termination

round_robin_team = RoundRobinGroupChat([agent1, agent2], 
                                       termination_condition=combined_termination)

# 如果你将此脚本作为独立脚本运行,请使用 asyncio.run(...)。
await Console(round_robin_team.run_stream(task="无法无天"))

 

对话在评论员智能体批准消息后停止,尽管它也可能在生成 10 条消息后停止。

或者,如果我们希望仅在满足两个条件时才停止运行,我们可以使用 AND (&) 运算符。

combined_termination = max_msg_termination & text_termination

管理状态

到目前为止,我们已经讨论了如何在多智能体应用程序中构建组件 - 智能体、团队、终止条件。 在许多情况下,将这些组件的状态保存到磁盘并在以后加载它们会很有用。 这在 Web 应用程序中特别有用,在 Web 应用程序中,无状态端点响应请求,并且需要从持久性存储加载应用程序的状态。

这里我们将讨论如何保存和加载智能体、团队和终止条件的状态。

保存和加载智能体

我们可以通过调用  AssistantAgent上的  save_state()方法来获取智能体的状态。

from autogen_agentchat.agents import AssistantAgent
from autogen_agentchat.conditions import MaxMessageTermination
from autogen_agentchat.messages import TextMessage
from autogen_agentchat.teams import RoundRobinGroupChat
from autogen_agentchat.ui import Console
from autogen_core import CancellationToken
from autogen_ext.models.openai import OpenAIChatCompletionClient

#创建grok 模型客户端
model_client = OpenAIChatCompletionClient(
    model="grok-2-latest",
    base_url="https://api.x.ai/v1",
    api_key="xai-xxxxxxxx",
    model_info={
        "vision": True,
        "function_calling": True,
        "json_output": True,
        "family": "unknown",
    },
    )

assistant_agent = AssistantAgent(
    name="assistant_agent",
    system_message="你是一个乐于助人的助手",
    model_client=model_client,
)

# 如果你将此脚本作为独立脚本运行,请使用 asyncio.run(...)。
response = await assistant_agent.on_messages(
    [TextMessage(content="写一首关于'躺平'的3行打油诗", source="user")], 
    CancellationToken()
)
print(response.chat_message.content)

 下面我们保存一下当前智能体的状态:

#保存状态
agent_state = await assistant_agent.save_state()
print(agent_state)

 

接下来我们加载状态

new_assistant_agent = AssistantAgent(
    name="assistant_agent",
    system_message="你是一个乐于助人的助手",
    model_client=model_client,
)
await new_assistant_agent.load_state(agent_state)

# 如果你将此脚本作为独立脚本运行,请使用 asyncio.run(...)。
response = await new_assistant_agent.on_messages(
    [TextMessage(content="你写的上一首诗的最后一行是什么?", source="user")], CancellationToken()
)
print(response.chat_message.content)

注意: 对于 AssistantAgent,其状态由 model_context 组成。 如果你编写自己的自定义智能体,请考虑重写  save_state() 和 load_state() 方法以自定义行为。 默认实现保存和加载空状态。 

保存和加载团队

我们可以通过在团队上调用 save_state 方法来获取团队的状态,并通过调用团队上的 load_state 方法将其加载回来。

当我们在团队上调用 save_state 时,它会保存团队中所有智能体的状态。

我们将从创建一个简单的  RoundRobinGroupChat 团队和一个智能体开始,并要求它写一首诗。


#创建grok 模型客户端
model_client = OpenAIChatCompletionClient(
    model="grok-2-latest",
    base_url="https://api.x.ai/v1",
    api_key="xai-xxxxx",
    model_info={
        "vision": True,
        "function_calling": True,
        "json_output": True,
        "family": "unknown",
    },
    )

# 定义一个团队。
assistant_agent = AssistantAgent(
    name="assistant_agent",
    system_message="你是一个乐于助人的助手",
    model_client=model_client,
)
agent_team = RoundRobinGroupChat([assistant_agent], 
                                 termination_condition=MaxMessageTermination(max_messages=2))

# 运行团队并将消息流式传输到控制台。
stream = agent_team.run_stream(task="写一首关于'躺平'的3行打油诗")

# 如果你将此脚本作为独立脚本运行,请使用 asyncio.run(...)。
await Console(stream)

# 保存智能体团队的状态。
team_state = await agent_team.save_state()

如果 我们重置团队(模拟团队的实例化),并询问“你写的上一首诗的最后一行是什么?”,我们看到团队无法完成此操作,因为没有对先前运行的引用: 

await agent_team.reset()
stream = agent_team.run_stream(task="你写的上一首诗的最后一行是什么?")
await Console(stream)

接下来,我们加载团队的状态并提出相同的问题。 我们看到该团队能够准确地返回它所写的诗的最后一行:

print(team_state)
print()

# 加载团队状态。
await agent_team.load_state(team_state)
stream = agent_team.run_stream(task="你写的上一首诗的最后一行是什么?")
await Console(stream)

 

持久化状态(文件或数据库)

在许多情况下,我们可能希望将团队的状态持久化到磁盘(或数据库)并在以后加载它。状态是一个可以序列化到文件或写入数据库的字典。

import json

## 将状态保存到磁盘

with open("coding/team_state.json", "w") as f:
    json.dump(team_state, f)

## 从磁盘加载状态
with open("coding/team_state.json", "r") as f:
    team_state = json.load(f)

new_agent_team = RoundRobinGroupChat([assistant_agent], 
                                     termination_condition=MaxMessageTermination(max_messages=2))
await new_agent_team.load_state(team_state)
stream = new_agent_team.run_stream(task="你写的上一首诗的最后一行是什么?")
await Console(stream)

 

总结 

AutoGen AgentChat 提供了一套精细的机制来构建更智能、更可控的对话系统。终止机制 (Termination) 允许你定义明确的结束条件,无论是基于对话轮数、特定关键词、时间限制还是外部信号,确保对话在适当的时机停止。而状态管理 (Managing State) 则提供了持久化智能体和团队记忆的能力,从而支持跨会话的任务,即使服务重启也能无缝衔接,共同创造灵活、持久的多智能体应用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

-派神-

感谢您慷慨解囊,我会更加努力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值