Skip to main content
Glama

baidu-ai-search

Official
by baidubce
chatflow.ipynb18.7 kB
{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# 前言 - 学习本项目你可以获得什么\n", "- 入门百度智能云千帆AppBuilder,搭建一个工作流Agent应用\n", "- 使用AppBuilder-SDK进行工作流Agent对话\n", "- 了解如何使用AppBuilder-SDK简化多轮对话的开发" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 1. 项目背景\n", "\n", "### 1.1、 什么是AppBuilder\n", "[百度智能云千帆AppBuilder](https://appbuilder.cloud.baidu.com/)(以下简称AppBuilder)是基于大模型搭建AI原生应用的工作台,旨在降低AI原生应用的开发门槛,赋能开发者和企业快速实现应用搭建。\n", "\n", "平台提供了RAG(检索增强生成)、Agent(智能体)等应用框架,内置了文档问答、表格问答、多轮对话、生成创作等多种应用组件,还包括百度搜索和百度地图等特色组件,以及文本处理、图像处理和语音处理等传统AI组件,支持零代码、低代码、全代码三种开发方式,满足不同开发能力的开发者和企业的场景需求。\n", "\n", "### 1.2、 什么是AppBuilder-SDK\n", "\n", "[百度智能云千帆AppBuilder-SDK](https://github.com/baidubce/app-builder)(以下简称AB-SDK),百度智能云千帆AppBuilder-SDK是百度智能云千帆AppBuilder面向AI原生应用开发者提供的一站式开发平台的客户端SDK。\n", "\n", "<img src=\"https://chengmo-dev1.bj.bcebos.com/page2.png\" alt=\"drawing\" width=\"1000\"/>" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 2. 创建工作流Agent应用并对话\n", "\n", "## 2.1 什么是工作流Agent?\n", "通过工作流编排的形式还原业务流程,每轮对话均严格按照工作流执行,提高了AI应用的可控性,并可编排出复杂业务流程,适用于客服、营销、生成、办公等高可控及高复杂度等场景。\n", "\n", "**工作流Agent无需设置角色人设,通过工作流编排的形式实现应用功能。**\n", "\n", "用户的所有对话均会触发此工作流处理,适用于严格按照流程执行的任务,例如:\n", "\n", "* 客服对话智能体,判断终端用户的意图后严格按照任务分支自动执行,无需大模型思考选择。\n", "* MBTI小助手,根据开发者编排的问题逐个提问,严格按照任务分支和结果执行后续的流程。\n", "\n", "工作流Agent支持用户配置工作流完成整个应用的对话过程,通过开始节点的Rawquery传入首轮对话,利用信息收集节点可以进行一组工作流中的多轮对话,最后以结束节点作为整个工作流结束的标志。开始节点和结束节点之前的完整流程构成一组工作流,每个信息收集节点都可以支持终端用户和应用的一次交互。\n", "\n", "## 2.2 创建工作流Agent应用-飞行客服小助手\n", "\n", "参考产品文档[飞行客服小助手](https://cloud.baidu.com/doc/AppBuilder/s/cm38k8nqr)创建示例应用。通过阅读本篇最佳实践,读者可以深度理解问答节点、信息处理节点、全局跳转节点的功能点和使用方式,搭建自己的工作流agent。对话效果如下:\n", "\n", "<p float=\"left\">\n", " <img src=\"https://bce.bdstatic.com/doc/ai-cloud-share/AppBuilder/image_f11055c.png\" width=\"33%\" />\n", " <img src=\"https://bce.bdstatic.com/doc/ai-cloud-share/AppBuilder/image_a680834.png\" width=\"33%\" /> \n", " <img src=\"https://bce.bdstatic.com/doc/ai-cloud-share/AppBuilder/image_b602fef.png\" width=\"33%\" />\n", "</p>\n", "\n", "## 2.3 使用AppBuilder-SDK进行对话\n", "### 2.3.1 方式一:使用SDK直接对话(不推荐)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import appbuilder\n", "import os\n", "from appbuilder.core.console.appbuilder_client import data_class\n", "\n", "# 请前往千帆AppBuilder官网创建密钥,流程详见:https://cloud.baidu.com/doc/AppBuilder/s/Olq6grrt6#1%E3%80%81%E5%88%9B%E5%BB%BA%E5%AF%86%E9%92%A5\n", "# 设置环境变量\n", "os.environ[\"APPBUILDER_TOKEN\"] = \"...\"\n", "appbuilder.logger.setLoglevel(\"ERROR\")\n", "\n", "# 飞行客服小助手的应用id\n", "app_id = \"...\"\n", "# 初始化智能体\n", "client = appbuilder.AppBuilderClient(app_id)\n", "# 创建会话\n", "conversation_id = client.create_conversation()\n", "interrupt_ids = []\n", "\n", "msg = client.run(conversation_id, \"查天气\", stream=True)\n", "interrupt_event_id = None\n", "for ans in msg.content:\n", " for event in ans.events:\n", " if event.content_type == \"publish_message\":\n", " print(event.detail.get(\"message\"))\n", " if event.content_type == \"chatflow_interrupt\":\n", " interrupt_event_id = event.detail.get(\"interrupt_event_id\")\n", " break\n", "interrupt_ids.append(interrupt_event_id)\n", "\n", "msg2 = client.run(\n", " conversation_id,\n", " \"查航班\",\n", " stream=True,\n", " action=data_class.Action.create_resume_action(interrupt_event_id),\n", ")\n", "interrupt_event_id = None\n", "for ans in msg2.content:\n", " for event in ans.events:\n", " if event.content_type == \"publish_message\":\n", " print(event.detail.get(\"message\"))\n", " if event.content_type == \"chatflow_interrupt\":\n", " interrupt_event_id = event.detail.get(\"interrupt_event_id\")\n", " break\n", " interrupt_ids.append(interrupt_event_id)\n", "\n", "msg3 = client.run(\n", " conversation_id=conversation_id,\n", " query=\"CA1234\",\n", " stream=True,\n", " action=data_class.Action.create_resume_action(interrupt_ids.pop()),\n", ")\n", "interrupt_event_id = None\n", "for ans in msg3.content:\n", " for event in ans.events:\n", " if event.content_type == \"text\":\n", " print(event.detail.get(\"text\"))\n", " if event.content_type == \"chatflow_interrupt\":\n", " interrupt_event_id = event.detail.get(\"interrupt_event_id\")\n", " break\n", "interrupt_ids.append(interrupt_event_id)\n", "\n", "msg4 = client.run(\n", " conversation_id=conversation_id,\n", " query=\"北京的\",\n", " stream=True,\n", " action=data_class.Action.create_resume_action(interrupt_ids.pop()),\n", ")\n", "has_multiple_dialog_event = False\n", "for ans in msg4.content:\n", " for event in ans.events:\n", " if event.content_type == \"text\":\n", " print(event.detail.get(\"text\"))\n", " if event.content_type == \"multiple_dialog_event\":\n", " has_multiple_dialog_event = True\n", " break" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 2.3.2 方式二 实现自己的EventHandler,更方便地进行对话(推荐)\n", "直接调用处理较为繁琐。SDK提供了使用AppBuilderEventHandler简化tool_call操作的功能。**继承AppBuilderEventHandler类,并实现针对各类型event的处理方法。**" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import os\n", "import appbuilder\n", "from appbuilder.core.console.appbuilder_client.event_handler import (\n", " AppBuilderEventHandler,\n", ")\n", "\n", "\n", "class MyEventHandler(AppBuilderEventHandler):\n", " def __init__(self):\n", " super().__init__()\n", " self.interrupt_ids = []\n", "\n", " def handle_content_type(self, run_context, run_response):\n", " interrupt_event_id = None\n", " event = run_response.events[-1]\n", " if event.content_type == \"chatflow_interrupt\":\n", " interrupt_event_id = event.detail.get(\"interrupt_event_id\")\n", " if interrupt_event_id is not None:\n", " self.interrupt_ids.append(interrupt_event_id)\n", "\n", " def _create_action(self):\n", " if len(self.interrupt_ids) == 0:\n", " return None\n", " event_id = self.interrupt_ids.pop()\n", " return {\n", " \"action_type\": \"resume\",\n", " \"parameters\": {\"interrupt_event\": {\"id\": event_id, \"type\": \"chat\"}},\n", " }\n", "\n", " def run(self, query=None):\n", " super().new_dialog(\n", " query=query,\n", " action=self._create_action(),\n", " )\n", "\n", "\n", "def main():\n", " # 请前往千帆AppBuilder官网创建密钥,流程详见:https://cloud.baidu.com/doc/AppBuilder/s/Olq6grrt6#1%E3%80%81%E5%88%9B%E5%BB%BA%E5%AF%86%E9%92%A5\n", " # 设置环境变量\n", " os.environ[\"APPBUILDER_TOKEN\"] = \"...\"\n", " appbuilder.logger.setLoglevel(\"DEBUG\")\n", "\n", " # 飞行客服小助手的应用id\n", " app_id = \"...\"\n", " # 初始化智能体\n", " client = appbuilder.AppBuilderClient(app_id)\n", " conversation_id = client.create_conversation()\n", "\n", " event_handler = MyEventHandler()\n", " event_handler.init(\n", " appbuilder_client=client,\n", " conversation_id=conversation_id,\n", " stream=True,\n", " query=\"查天气\",\n", " )\n", " for data in event_handler:\n", " pass\n", " event_handler.run(\n", " query=\"查航班\",\n", " )\n", " for data in event_handler:\n", " pass\n", " event_handler.run(\n", " query=\"CA1234\",\n", " )\n", " for data in event_handler:\n", " pass\n", " event_handler.run(\n", " query=\"北京的\",\n", " )\n", " for data in event_handler:\n", " pass\n", "\n", "\n", "if __name__ == \"__main__\":\n", " main()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 2.3.3 方式三、实现自己的EventHandler,更方便地进行多轮对话(推荐)\n", "SDK提供了run_multiple_dialog_with_handler方法来进行多轮对话,按需传入iterable对象(queries、actions等参数),即可一次调用完成多轮对话。" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import os\n", "import appbuilder\n", "from appbuilder.core.console.appbuilder_client.event_handler import (\n", " AppBuilderEventHandler,\n", ")\n", "\n", "\n", "class MyEventHandler(AppBuilderEventHandler):\n", " def __init__(self):\n", " super().__init__()\n", " self.interrupt_ids = []\n", "\n", " def handle_content_type(self, run_context, run_response):\n", " interrupt_event_id = None\n", " event = run_response.events[-1]\n", " if event.content_type == \"chatflow_interrupt\":\n", " interrupt_event_id = event.detail.get(\"interrupt_event_id\")\n", " if interrupt_event_id is not None:\n", " self.interrupt_ids.append(interrupt_event_id)\n", "\n", " def _create_action(self):\n", " if len(self.interrupt_ids) == 0:\n", " return None\n", " event_id = self.interrupt_ids.pop()\n", " return {\n", " \"action_type\": \"resume\",\n", " \"parameters\": {\"interrupt_event\": {\"id\": event_id, \"type\": \"chat\"}},\n", " }\n", "\n", " def gen_action(self):\n", " while True:\n", " yield self._create_action()\n", "\n", "\n", "def main():\n", " # 请前往千帆AppBuilder官网创建密钥,流程详见:https://cloud.baidu.com/doc/AppBuilder/s/Olq6grrt6#1%E3%80%81%E5%88%9B%E5%BB%BA%E5%AF%86%E9%92%A5\n", " # 设置环境变量\n", " os.environ[\"APPBUILDER_TOKEN\"] = \"...\"\n", " appbuilder.logger.setLoglevel(\"DEBUG\")\n", "\n", " # 飞行客服小助手的应用id\n", " app_id = \"...\"\n", " # 初始化智能体\n", " client = appbuilder.AppBuilderClient(app_id)\n", " conversation_id = client.create_conversation()\n", "\n", " queries = [\"查天气\", \"查航班\", \"CA1234\", \"北京的\"]\n", " event_handler = MyEventHandler()\n", " event_handler = client.run_multiple_dialog_with_handler(\n", " conversation_id=conversation_id,\n", " queries=queries,\n", " event_handler=event_handler,\n", " stream=True,\n", " actions=event_handler.gen_action(),\n", " )\n", " for data in event_handler:\n", " for ans in data:\n", " pass\n", "\n", "\n", "if __name__ == \"__main__\":\n", " main()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 2.3.4 异步调用工作流Agent\n", "SDK提供异步调用工作流Agent的接口,下面是一个异步调用工作流Agent的实例。" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Copyright (c) 2024 Baidu, Inc. All Rights Reserved.\n", "#\n", "# Licensed under the Apache License, Version 2.0 (the \"License\");\n", "# you may not use this file except in compliance with the License.\n", "# You may obtain a copy of the License at\n", "#\n", "# http://www.apache.org/licenses/LICENSE-2.0\n", "#\n", "# Unless required by applicable law or agreed to in writing, software\n", "# distributed under the License is distributed on an \"AS IS\" BASIS,\n", "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n", "# See the License for the specific language governing permissions and\n", "# limitations under the License.\n", "import os\n", "import asyncio\n", "import appbuilder\n", "from appbuilder.core.console.appbuilder_client.async_event_handler import (\n", " AsyncAppBuilderEventHandler,\n", ")\n", "\n", "class MyEventHandler(AsyncAppBuilderEventHandler):\n", " def __init__(self):\n", " super().__init__()\n", " self.interrupt_ids = []\n", "\n", " async def handle_content_type(self, run_context, run_response):\n", " interrupt_event_id = None\n", " event = run_response.events[-1]\n", " if event.content_type == \"chatflow_interrupt\":\n", " interrupt_event_id = event.detail.get(\"interrupt_event_id\")\n", " if interrupt_event_id is not None:\n", " self.interrupt_ids.append(interrupt_event_id)\n", "\n", " def _create_action(self):\n", " if len(self.interrupt_ids) == 0:\n", " return None\n", " event_id = self.interrupt_ids.pop()\n", " return {\n", " \"action_type\": \"resume\",\n", " \"parameters\": {\"interrupt_event\": {\"id\": event_id, \"type\": \"chat\"}},\n", " }\n", "\n", " async def run(self, query=None):\n", " await super().new_dialog(\n", " query=query,\n", " action=self._create_action(),\n", " )\n", "\n", " def gen_action(self):\n", " while True:\n", " yield self._create_action()\n", "\n", "\n", "async def agent_run():\n", " # 请前往千帆AppBuilder官网创建密钥,流程详见:https://cloud.baidu.com/doc/AppBuilder/s/Olq6grrt6#1%E3%80%81%E5%88%9B%E5%BB%BA%E5%AF%86%E9%92%A5\n", " # 设置环境变量\n", " os.environ[\"APPBUILDER_TOKEN\"] = \"...\"\n", " appbuilder.logger.setLoglevel(\"DEBUG\")\n", "\n", " # 飞行客服小助手的应用id\n", " app_id = \"...\"\n", " client = appbuilder.AsyncAppBuilderClient(app_id)\n", " conversation_id = await client.create_conversation()\n", " event_handler = MyEventHandler()\n", " queries = [\"查天气\", \"查航班\", \"CA1234\", \"北京的\"]\n", " event_handler = client.run_multiple_dialog_with_handler(\n", " conversation_id=conversation_id,\n", " queries=queries,\n", " event_handler=event_handler,\n", " stream=False,\n", " actions=event_handler.gen_action(),\n", " )\n", " async for data in event_handler:\n", " async for answer in data:\n", " print(answer)\n", "\n", " await client.http_client.session.close()\n", "\n", "if __name__ == \"__main__\":\n", " loop = asyncio.get_event_loop()\n", " loop.run_until_complete(agent_run())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 3、项目总结\n", "\n", "本项目最终完成了一个工作流Agent应用的创建,并使用Appbuilder-SDK进行对话功能。\n", "\n", "希望您可以不吝`Star`,给`AppBuilder-SDK`一些鼓励,期待您的`PR`,一起共建AIAgent生态。\n", "\n", "Github地址:https://github.com/baidubce/app-builder\n", "\n", "<img src=\"https://chengmo-dev1.bj.bcebos.com/page10.png\" alt=\"drawing\" width=\"1000\"/>\n", "\n", "最后,您也可以进入`AppBuilder-SDK`的WX交流群,和大家一起交流AppBuilder使用及开发心得。\n", "\n", "<img src=\"https://chengmo-dev1.bj.bcebos.com/wechat_group.png\" alt=\"drawing\" width=\"1000\"/>" ] } ], "metadata": { "kernelspec": { "display_name": "testenv", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.20" } }, "nbformat": 4, "nbformat_minor": 2 }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/baidubce/app-builder'

If you have feedback or need assistance with the MCP directory API, please join our Discord server