在NiceGUI中集成AutoGen并捕获Agent响应的教程

在NiceGUI中集成AutoGen并捕获Agent响应的教程

本教程旨在解决在nicegui应用中集成autogen时,如何实时捕获并显示agent对话响应的问题。通过深入解析autogen的`register_reply`机制,我们将展示如何注册自定义回调函数来拦截并处理agent的每一条消息,从而将autogen的强大对话能力无缝桥接到nicegui的交互式聊天界面中,确保所有对话内容都能在前端准确呈现。

1. 引言:AutoGen与NiceGUI的融合挑战

在构建基于大型语言模型(LLM)的交互式应用时,我们经常需要结合强大的LLM编排框架(如AutoGen)与灵活的Web UI框架(如NiceGUI)。AutoGen以其多Agent协作能力著称,能够模拟复杂的对话和任务执行流程。然而,当我们将AutoGen集成到NiceGUI等Web界面时,一个常见的问题是如何将AutoGen Agent在后台产生的实时对话内容准确、及时地呈现在用户界面上。AutoGen的initiate_chat方法通常会返回一个包含最终对话结果的对象,但它并不直接提供一个简单的方式来获取对话过程中Agent的每一步回复,而这些中间步骤对于构建流畅的用户体验至关重要。

2. AutoGen与NiceGUI基础设置

首先,我们来看一下AutoGen Agent和NiceGUI界面的基本配置。以下代码展示了如何初始化AutoGen Agent以及一个简单的NiceGUI聊天界面结构。

import autogenfrom nicegui import ui, contextfrom uuid import uuid4# 1. AutoGen 配置config_list = [    {        'model': 'gpt-4',        'api_key': 'YOUR_API_KEY' # 请替换为您的实际API密钥    }]llm_config = {    'seed': 42,    'config_list': config_list,    'temperature': 0.2}# 2. 初始化AutoGen Agentassistant = autogen.AssistantAgent(name='Albert', llm_config=llm_config)user_proxy = autogen.UserProxyAgent(    name='user_proxy',    human_input_mode="NEVER", # 在NiceGUI中,用户输入通过UI提供,Agent无需直接请求    max_consecutive_auto_reply=10, # 允许更多轮次自动回复    is_termination_msg=lambda x: x.get("content", "").rstrip().endswith("TERMINATE"),    code_execution_config={"work_dir": "web"}, # 设定代码执行的工作目录    llm_config=llm_config)# 3. NiceGUI 界面定义@ui.page('/')def main():    # 存储聊天消息的列表,用于UI显示    messages = []    user_id = str(uuid4()) # 为每个用户会话生成唯一ID    @ui.refreshable    def chat_messages():        """刷新聊天消息显示区域"""        for name, text in messages:            ui.chat_message(text=text, name=name, sent=name == 'You')        if context.get_client().has_socket_connection:            # 自动滚动到底部            ui.run_javascript('setTimeout(() => window.scrollTo(0, document.body.scrollHeight), 0)')    # ... (发送消息的逻辑将在后面修改)    # ... (UI布局)

在上述代码中,我们配置了AssistantAgent和UserProxyAgent。UserProxyAgent的human_input_mode设置为”NEVER”,因为用户输入将通过NiceGUI的文本框提供。NiceGUI部分则定义了一个messages列表来存储对话历史,并通过@ui.refreshable装饰器实现消息的动态更新和滚动。

3. 核心挑战:捕获Agent的实时响应

最初的尝试可能是在send函数中调用user_proxy.initiate_chat后,尝试从其返回值中提取Agent的响应。然而,initiate_chat返回的是一个ChatResult对象,其中包含了整个对话的概要和最终状态,但并不直接提供Agent在对话过程中每一步的详细回复内容。这意味着,如果Agent进行了多轮思考或与UserProxyAgent进行了多次交互,这些中间过程将不会被NiceGUI捕获并显示,用户只能看到最终结果,这严重影响了用户体验。

例如,原始代码中尝试这样获取响应:

# 原始的尝试response = await user_proxy.initiate_chat(assistant, message=user_message)if response and 'content' in response[0]: # 这里的response[0]通常是最后一条消息    assistant_response = response[0]['content']    messages.append(('Albert', assistant_response))

这种方法只能捕获到initiate_chat结束后,对话中最后一条消息的内容,无法实时跟踪整个对话流程。

4. 解决方案:利用register_reply机制

AutoGen提供了一个强大的回调机制——register_reply,它允许我们在Agent发送或接收消息时注册一个自定义函数。这个函数会在每次消息交换时被调用,从而使我们能够实时捕获并处理Agent的对话内容。

Lifetoon Lifetoon

免费的AI漫画创作平台

Lifetoon 92 查看详情 Lifetoon

4.1 register_reply的工作原理

register_reply方法允许你为Agent注册一个或多个回调函数。每当Agent准备发送回复或接收到消息时,这些回调函数就会被触发。其基本签名如下:

agent.register_reply(    trigger: Union[Type[Agent], Agent, List[Union[Type[Agent], Agent]], None],    reply_func: Callable,    config: Optional[Any] = None,    reset_config: Optional[Callable] = None,    position: Optional[int] = None)

其中:

trigger: 指定何时触发回调。可以是一个Agent实例、Agent类型、Agent列表,或者None(表示对所有消息都触发)。reply_func: 这是一个可调用对象(函数),它将在消息交换时被执行。它的签名通常是 (recipient, messages, sender, config)。recipient: 接收当前消息的Agent。messages: 一个列表,包含当前对话回合中所有的消息(通常是最新消息)。sender: 发送当前消息的Agent。config: 注册时传递的配置字典。reply_func的返回值:回调函数需要返回一个元组 (bool, Optional[str])。True表示回调函数已经处理了回复,Agent无需再生成回复。False表示Agent应继续其默认的回复生成逻辑。Optional[str]是回调函数生成的回复内容,如果返回True,则此内容将作为Agent的回复。

4.2 关键回调函数设计

为了将Agent的实时消息显示在NiceGUI界面上,我们需要设计一个回调函数,它能够从messages参数中提取出最新的消息内容和发送者,然后将其添加到NiceGUI的messages列表中,并触发UI刷新。

# 定义一个辅助函数来更新UI消息列表并刷新def append_and_refresh_ui_messages(sender_name: str, content: str):    """将消息添加到UI列表并刷新NiceGUI界面"""    messages.append((sender_name, content))    chat_messages.refresh()# AutoGen回调函数def autogen_reply_callback(recipient, current_messages, sender, config):    """    AutoGen Agent消息回调函数,用于捕获Agent的实时回复。    """    # current_messages 是一个列表,包含当前回合的所有消息。    # 最后一条消息是刚刚发送或接收的消息。    if current_messages:        last_message = current_messages[-1]        sender_name = last_message.get('name', sender.name) # 优先使用消息中的name,否则使用sender的name        content = last_message.get('content', '')        if content:            # 使用NiceGUI的run_sync将UI更新操作调度到主线程            ui.run_sync(lambda: append_and_refresh_ui_messages(sender_name, content))    # 返回 False, None 表示Agent应继续其默认的回复生成逻辑    return False, None

注意: 由于AutoGen的Agent对话可能在后台线程中进行,而NiceGUI的UI更新必须在主线程执行,因此我们使用ui.run_sync来安全地调度append_and_refresh_ui_messages函数。

4.3 注册回调函数

现在,我们将这个回调函数注册到assistant和user_proxy这两个Agent上。这样,无论是assistant回复user_proxy,还是user_proxy向assistant发送消息,我们都能捕获到。

# 在 main() 函数内部,在 Agent 初始化之后,NiceGUI UI定义之前# 注册回调函数assistant.register_reply(    [autogen.Agent, None], # 捕获assistant发送给任何Agent的消息    reply_func=autogen_reply_callback,    config={"callback": None},)user_proxy.register_reply(    [autogen.Agent, None], # 捕获user_proxy发送给任何Agent的消息    reply_func=autogen_reply_callback,    config={"callback": None},)

5. 整合到NiceGUI聊天界面

将register_reply回调机制整合到NiceGUI的main函数中,并调整send函数。现在,send函数只需要负责接收用户输入并启动AutoGen对话,具体的Agent回复将由autogen_reply_callback处理。

import autogenfrom nicegui import ui, contextfrom uuid import uuid4# AutoGen Configurationconfig_list = [    {        'model': 'gpt-4',        'api_key': 'YOUR_API_KEY' # 替换为您的实际API密钥    }]llm_config = {    'seed': 42,    'config_list': config_list,    'temperature': 0.2}# Initialize AutoGen Agents (在 main() 外部初始化,以便在回调中访问)assistant = autogen.AssistantAgent(name='Albert', llm_config=llm_config)user_proxy = autogen.UserProxyAgent(    name='user_proxy',    human_input_mode="NEVER",    max_consecutive_auto_reply=10,    is_termination_msg=lambda x: x.get("content", "").rstrip().endswith("TERMINATE"),    code_execution_config={"work_dir": "web"},    llm_config=llm_config)@ui.page('/')def main():    messages = [] # 存储聊天消息的列表    user_id = str(uuid4())    @ui.refreshable    def chat_messages():        for name, text in messages:            ui.chat_message(text=text, name=name, sent=name == 'You')        if context.get_client().has_socket_connection:            ui.run_javascript('setTimeout(() => window.scrollTo(0, document.body.scrollHeight), 0)')    # 定义辅助函数和回调函数,它们需要访问到 main() 作用域内的 messages 和 chat_messages    def append_and_refresh_ui_messages(sender_name: str, content: str):        messages.append((sender_name, content))        chat_messages.refresh()    def autogen_reply_callback(recipient, current_messages, sender, config):        if current_messages:            last_message = current_messages[-1]            sender_name = last_message.get('name', sender.name)            content = last_message.get('content', '')            if content:                ui.run_sync(lambda: append_and_refresh_ui_messages(sender_name, content))        return False, None    # 注册回调函数    assistant.register_reply(        [autogen.Agent, None],        reply_func=autogen_reply_callback,        config={"callback": None},    )    user_proxy.register_reply(        [autogen.Agent, None],        reply_func=autogen_reply_callback,        config={"callback": None},    )    async def send():        user_message = task_input.value        if not user_message.strip():            return # 防止发送空消息        # 用户自己的消息直接添加到UI列表        append_and_refresh_ui_messages('You', user_message)        task_input.value = '' # 清空输入框        try:            # 启动AutoGen对话,Agent的回复将通过回调函数处理            await user_proxy.initiate_chat(assistant, message=user_message)        except Exception as e:            # 异常处理,显示错误信息            ui.run_sync(lambda: append_and_refresh_ui_messages('Albert', f"Error: {e}"))        finally:            # 确保在对话结束后刷新UI(虽然回调已经刷新,但以防万一)            ui.run_sync(chat_messages.refresh)    with ui.scroll_area().classes('w-full h-60 p-3 bg-white overflow-auto'):        chat_messages()    with ui.footer().style('position: fixed; left: 0; bottom: 0; width: 100%; background: white; padding: 10px; box-shadow: 0 -2px 5px rgba(0,0,0,0.1);'):        task_input = ui.input().style('width: calc(100% - 100px);').on('keydown.enter', send) # 支持回车发送        ui.button('Send', on_click=send).style('width: 90px;')ui.run(title='Chat with Albert')

6. 注意事项与最佳实践

Agent初始化位置:将AutoGen Agent的初始化放在ui.page装饰的main()函数外部,可以确保Agent实例在整个应用生命周期中只被创建一次,并能在main()函数内部的回调中被访问。回调函数的线程安全:由于AutoGen Agent的运行可能涉及多线程,而NiceGUI的UI更新必须在主线程进行,因此使用ui.run_sync()是至关重要的。它确保了对messages列表和chat_messages.refresh()的调用是在NiceGUI的主事件循环中安全执行的。reply_func的返回值:在我们的场景中,回调函数仅用于监听和显示消息,不应干预Agent的默认回复逻辑,因此返回False, None是正确的选择。如果需要自定义Agent的回复行为,可以返回True和一个字符串作为新的回复。max_consecutive_auto_reply:为了让Agent能够进行多轮次的自主对话,将UserProxyAgent的max_consecutive_auto_reply设置为一个较大的值(例如10),可以避免对话过早终止。错误处理:在send函数中使用try…except块来捕获initiate_chat可能抛出的异常,并将错误信息显示在UI上,提升用户体验。消息来源识别:在autogen_reply_callback中,last_message.get(‘name’, sender.name)能够更准确地识别消息的发送者,因为有时消息字典中会包含name字段,它可能比sender.name更具描述性。终止消息:is_termination_msg参数对于控制Agent何时停止对话至关重要。确保您的Agent在完成任务后发送一个符合终止条件的字符串(例如TERMINATE)。

7.

以上就是在NiceGUI中集成AutoGen并捕获Agent响应的教程的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/904779.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
电脑如何清理磁盘空间(快速有效地释放磁盘空间)
上一篇 2025年11月28日 22:23:29
Grok AI推「长按图变成短片」功能 马斯克亲自教你怎么玩
下一篇 2025年11月28日 22:23:29

相关推荐

  • 如何下载豆包电脑网页版_豆包电脑网页版正版链接

    豆包AI电脑及网页版可通过官网和官方应用商店安全获取。1、访问https://www.doubao.com登录使用网页版;2、官网下载电脑客户端,支持Windows和macOS;3、通过Microsoft Store或App Store搜索“豆包 AI”,认准北京字节跳动网络技术有限公司开发,确保正…

    2026年9月21日
    100
  • Linux目录结构与文件系统设计理念

    Linux目录结构以根目录为起点,遵循“一切皆文件”理念,通过标准化层级划分(如/bin、/etc、/home等)实现资源统一管理,结合FHS标准、灵活挂载机制与权限模型,提升系统可维护性、安全性和跨发行版兼容性,体现简洁高效的设计哲学。 Linux的目录结构与文件系统设计体现了简洁、统一和高度模块…

    2026年9月21日
    100
  • 如何避免协程中的共享资源竞争?

    避免协程中的共享资源竞争可以通过以下方法:1. 使用锁(locks),如互斥锁或读写锁,确保同一时间只有一个协程访问共享资源。2. 采用无锁数据结构(lock-free data structures),通过原子操作和cas操作提高并发性能。3. 实施消息传递(message passing),通过…

    2026年9月21日
    000
  • windows怎么设置锁屏超时时间_Windows锁屏时间设置方法

    首先调整电源和睡眠设置以解决锁屏时间不当问题,依次通过系统设置修改屏幕关闭时间、利用控制面板自定义高级电源选项,或使用命令提示符快速配置,确保设备在不同电源状态下按需锁屏。 如果您发现Windows设备在不使用时过早或过晚进入锁屏状态,可能是电源和睡眠设置未按需求配置。以下是调整锁屏超时时间的具体步…

    2026年9月21日
    000
  • Java构造方法的执行顺序及注意事项

    构造方法执行顺序为:父类静态代码块→子类静态代码块→父类实例初始化块→父类构造方法→子类实例初始化块→子类构造方法,且super()必须位于子类构造方法首行。 Java构造方法的执行顺序涉及继承关系中父类与子类的初始化过程,理解这一流程对掌握对象创建机制非常重要。当创建一个子类对象时,JVM会自动确…

    2026年9月21日
    000
  • mysql如何配置默认存储引擎

    首先查看当前默认存储引擎,通过SHOW VARIABLES命令确认;然后编辑my.cnf或my.ini文件,在[mysqld]下添加default-storage-engine=InnoDB;接着重启MySQL服务使配置生效;最后验证更改结果并检查建表默认引擎。 MySQL 默认存储引擎的配置可以通…

    2026年9月21日
    000
  • 微软 Windows 10 停服在即,官方升级工具却突然罢工

    10月13日,随着Windows 10的官方支持即将于次日(10月14日)正式终止,微软近期加大了对Windows 11的宣传力度,频繁推出广告和推广活动,强调新系统的多项升级与优势,吸引了不少用户考虑迁移至Windows 11。 然而颇具讽刺意味的是,在这一关键节点,微软自家的关键工具却出现了故障…

    2026年9月21日
    000
  • google浏览器开发者工具怎么打开_google浏览器打开开发者工具方法

    1、使用F12或Ctrl+Shift+I快捷键可快速打开开发者工具;2、右键点击页面元素选择“检查”能直接定位HTML节点;3、通过浏览器右上角菜单进入“更多工具”-“开发者工具”也可启动;4、在地址栏输入chrome://inspect可管理远程设备调试并打开对应开发者工具窗口。 如果您在使用 G…

    2026年9月21日
    000
  • win10键盘打字错乱怎么办_win10键盘错乱排查与修复教程

    首先检查Num Lock状态并关闭数字小键盘锁定,接着更新或重装键盘驱动程序,再禁用Program Compatibility Assistant Service服务,最后使用360安全卫士等工具修复系统错误,逐步排查键盘输入混乱问题。 如果您在使用Windows 10系统时,发现键盘输入的字符与按…

    2026年9月21日
    000
  • Jedis jsonGet 方法返回字节数组值末尾出现 .0 的处理策略

    当使用jedis客户端的`jsonget`方法从redis获取json数据时,如果其中包含字节数组(如xml字符串的字节表示),可能会因底层json库(如gson或org.json)的默认行为,导致数字被统一上转型为`double`类型,从而在输出中显示`.0`后缀。本文将深入探讨此问题产生的原因,…

    2026年9月21日
    200
  • mysql索引的类型和作用有哪些

    MySQL常见索引类型包括:1. 普通索引用于加速查询;2. 唯一索引确保列值唯一;3. 主键索引为唯一非空且自动创建聚簇索引;4. 聚簇索引决定数据物理存储顺序,每表仅一个;5. 非聚簇索引保存主键值,需回表查询;6. 覆盖索引避免回表提升性能;7. 联合索引遵循最左前缀原则;8. 全文索引支持文…

    2026年9月21日
    000
  • AI推文助手如何制作用户指南 AI推文助手的说明文档创作

    AI推文助手如何制作用户指南 AI推文助手的说明文档创作AI推文助手如何制作用户指南 AI推文助手的说明文档创作AI推文助手如何制作用户指南 AI推文助手的说明文档创作AI推文助手如何制作用户指南 AI推文助手的说明文档创作

    答案:配置账户、设定风格模板、生成推文、安排发布时间、监控数据。依次完成绑定社交账号、选择语气类型与关键词、输入主题生成内容、设置定时发布及查看分析仪表板,实现高效创作与优化。 ☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 免费无限量使用 DeepSeek R1 模型☜☜☜ 如果您希望使用A…

    2026年9月21日 用户投稿
    000
  • windows怎么使用放大镜工具_Windows放大镜功能使用方法

    首先通过快捷键Win+加号开启放大镜,再通过设置调整模式与参数;具体包括全屏、镜头、停靠三种视图模式,并支持自定义热键与鼠标联动,提升操作效率。 如果您在使用Windows系统时遇到屏幕内容过小或难以看清的情况,可以借助系统自带的放大镜工具来放大显示区域。以下是关于如何使用Windows放大镜功能的…

    2026年9月21日
    000
  • 安卓跑分第一 Redmi K70 至尊版本月发布

    redmi 今日正式宣布,备受期待的 k70 至尊版将于本月盛大发布,预计将与小米 mix 系列折叠旗舰同台竞技,共同演绎科技之美。据官方最新消息,redmi k70 至尊版将搭载联发科天玑 9300+ 处理器,这款处理器在安兔兔跑分测试中一举突破 238 万分大关,目前稳居安卓性能之巅。天玑 93…

    2026年9月21日
    000
  • 如何为特定语言配置VSCode的语法高亮?

    安装对应语言扩展并关联文件类型,可实现VSCode语法高亮。首先通过扩展面板安装目标语言插件,如Ruby或Rust;若文件扩展名未被识别,需手动将扩展名关联至正确语言;最后可在settings.json中配置editor.tokenColorCustomizations来自定义高亮颜色,确保语法解析…

    2026年9月21日
    000
  • Linux怎么使用systemctl管理服务

    Linux怎么使用systemctl管理服务Linux怎么使用systemctl管理服务Linux怎么使用systemctl管理服务Linux怎么使用systemctl管理服务

    systemctl是Linux中管理systemd服务的核心工具,提供统一命令集来启动、停止、重启、查看服务状态及设置开机自启,支持并行启动、依赖管理与Cgroups资源控制,相比SysVinit更高效;通过创建/etc/systemd/system/下的.service文件可自定义服务,包含[Un…

    2026年9月21日 用户投稿
    100
  • 苹果手机如何清理应用缓存数据

    苹果手机可通过系统设置和应用内操作管理缓存。1. 进入“设置”>“通用”>“iPhone存储空间”查看各App占用,卸载或删除不常用App以释放空间;2. 在微信中清理“缓存”及管理“聊天记录”,在抖音、快手等App内使用“清理缓存”功能;3. 清除Safari浏览器的历史记录与网站数据…

    2026年9月21日
    000
  • VSCode的自动保存与文件监听功能如何结合以避免不必要的构建触发?

    通过配置VSCode自动保存延迟和构建工具防抖,减少频繁触发构建。设置”files.autoSave”: “afterDelay”与”files.autoSaveDelay”: 3000,结合Vite或Webpack的watch…

    2026年9月21日
    000
  • Java中如何使用Thread.interrupt安全终止线程

    interrupt() 是协作式线程终止机制,设置中断状态并由线程自行处理;2. 阻塞时抛 InterruptedException 且清除状态,需捕获并响应;3. 非阻塞循环中应显式调用 isInterrupted() 检查;4. 捕获异常后应重置中断状态以确保信号传递;5. 使用 Executo…

    2026年9月21日
    200
  • 抖音订单助手购买流程步骤详解

    引言 随着抖音平台的迅猛发展,越来越多用户将其作为核心营销渠道。在这一背景下,高效管理商品订单成为关键。那么,如何通过抖音订单助手实现订单的便捷管理?本文将为您全面解析抖音订单助手的购买流程,助您快速掌握使用方法。 什么是抖音订单助手 抖音订单助手是抖音官方推出的一款订单管理辅助工具,旨在帮助用户更…

    2026年9月21日
    000

发表回复

登录后才能评论
关注微信