跳转至

AppConnector 应用连接器

Agently AppConnector 是3.3.4版本引入并完善的一项实验性功能,该功能旨在帮助开发者快速将自己开发的业务逻辑连接到可以试用的App界面,以方便进一步调试或是向他人展示开发效果。

基础使用方法

使用AppConnector方法非常简单,您只需要定义一个消息处理器函数(message handler)即可:

import Agently

agent = (
    Agently.create_agent()
        #.set_settings(...)
)

# 创建一个AppConnector实例
app = Agently.AppConnector()

# 定义该实例使用的message handler
def message_handler(message, chat_history):
    # 使用AgenticRequest在3.3.4版本引入的generator获取方法取得一个generator
    generator = (
        agent
            # chat_history参数值为Agently框架内通用的OpenAI格式消息队列
            .chat_history(chat_history)
            # message参数值为用户在App界面输入的文本信息
            .input(message)
            # 通过在.start()指令中传入return_generator=True
            # 声明需要返回一个generator
            .start(return_generator=True)
    )
    # generator可以使用for循环进行轮询访问,适合流式输出
    # 更多关于generator的知识请阅读Python官方语法说明
    for delta in generator:
        # 通过app.emit_delta()对App界面呈现的消息进行增量更新
        # 增量部分将更新在当前消息后
        app.emit_delta(delta)
    # 通过app.emit_done()告知App本次处理已经完成
    # 可以让用户进行下一轮输入交互
    app.emit_done()

# 唤起App
(
    app
        # 选择需要使用的App界面,目前支持"gradio"、"streamlit"和"shell"
        # 注意:Agently框架默认没有pip install这些界面所需使用的框架
        #      需要开发者自行在shell中安装
        #      shell界面无需安装其他依赖
        .use_app("gradio")
        .set_message_handler(message_handler)
        # 在.run()中依照kwargs格式传递的额外参数,都将被传递给实际的App插件,根据插件约定调用生效
        # 在gradio中:
        # interface参数内的字典将被传递给.ChatInterface()
        # launch参数内的字典将被传递给.launch()
        .run(launch={"server_name": "0.0.0.0"})
)

Message Handler参数及方法说明

Message Handler内会接收到两个参数messagechat_history

  • message:用户通过AppConnector连接的App界面发送的消息
  • chat_history:以OpenAI格式{ "role": ..., "content": ... }为元素的历史消息队列(和App界面呈现的消息保持一致)

在Message Handler中,我们通过app.emit_delta()app.emit_buffer()app.emit_done()和App界面进行交互,其中:

  • emit_delta(delta_str):接受增量传入字符串,传入的字符串将自动加入到当前已经在界面上呈现给用户看到的字符串的后方
  • emit_buffer(buffer_str):接受实时传入当前输出的完整字符串,传入的字符串将覆盖替换掉当前已经在界面上呈现给用户看到的字符串,使用emit_buffer()更新界面之后,还可以继续使用emit_delta()或emit_buffer()更新
  • emit_done(full_content_str[optional]):在消息更新完毕后,需要使用emit_done()指令告知App界面,本次处理已经结束,可以通知用户进行下一轮输入了,如果emit_done()不传入值,则不会变更当前App界面上的消息,如果emit_done()传入值,则会以本次传入的值作为最终呈现给用户的消息,替换掉App界面上的消息

我可以自己添加新的App插件吗?

Agently AppConnector 是一个实验性功能,框架内内置了对Gradio、Streamlit和Shell界面的支持方案。

当然,我们也支持开发者自行添加新的App插件(更欢迎社区开发者为框架贡献自己的App插件方案),添加新的App插件方法如下:

  1. 阅读https://github.com/Maplemx/Agently/tree/main/Agently/AppConnector/buildin文件夹中的插件代码,理解App插件的工作原理,主要需要理解:
    • AppConnector如何将接收到的Message Handler传递给App框架
    • 如何从App框架获取并清洗message和chat_history两个参数的值,并在适当时机传递并调用Message Handler
    • 如何使用AppConnector提供的DataGenerator实例获取Message Handler通过app.emit_delta()和app.emit_done()传递的更新数据信息,并将这些更新信息传递给App框架
    • 如何通过**kwargs参数获得更多当前App框架需要的补充参数
    • 在一次处理结束后,如何通过.reset_data_generator()重置DataGenerator实例
  2. 参考上述App插件的格式,写好自己的App插件函数my_app(app_connector, **kwargs),然后通过AppConnector实例的.register_app(<app_name>, <app_plugin_func>)方法注册到当前实例,即可通过app.use_app(<app_name>)的方式激活新开发的App插件啦!

只绑定一个Agent实例的简易用法

有时候,我们只是想快速将开发好的多轮对话Agent绑定到界面,是否可以用更简单的方式快速创建一个界面?当然可以,只需要通过如下方式创建即可:

import Agently

agent = (
    Agently.create_agent()
        #.set_settings(...)
)
# 编辑更多agent相关的设定
# agent.set_role(...)
# agent.set_agent_prompt(...)

# 创建一个AppConnector实例
app = Agently.AppConnector()

# 唤起App
(
    app
        # 选择App
        .use_app("gradio")
        # 绑定Agent
        .bind_agent(agent)
        # 启动App
        .run()
)

但要注意,通过这种方式绑定的agent并不能应对更复杂的业务逻辑,因为它只是通过下方代码完成的快速绑定,更复杂的业务逻辑还是需要通过基础使用方法自行管理:

# 注入方式
class AppConnector:
    # ...

    def bind_agent(self, agent):
        self.binded_agent = agent
        if self.message_handler == None:
            self.set_message_handler(
                lambda message, chat_history: agent.chat_history(chat_history).input(message).start()
            )
        return self