Skip to content

Commit

Permalink
Agent cookbook增加异步调用内容(appbuilder_client、chatflow、tool_call)
Browse files Browse the repository at this point in the history
  • Loading branch information
userpj committed Dec 23, 2024
1 parent 7a79a75 commit d7c816b
Show file tree
Hide file tree
Showing 3 changed files with 263 additions and 2 deletions.
58 changes: 57 additions & 1 deletion cookbooks/end2end_application/agent/appbuilder_client.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"1. 在[百度智能云千帆AppBuilder官网](https://cloud.baidu.com/product/AppBuilder)创建并发布应用、获取应用ID、获取密钥\n",
"2. 引用AppBuilderSDK代码,初始化AppBuilderClient实例、创建会话、上传文档(可选)、执行对话\n",
"\n",
"以下分别提供三个样例,快递查询小助手、植物识别小助手、篮球教练来说明使用流程,注意以下流程用到的密钥可在图示位置中获取:\n",
"以下分别提供三个样例,快递查询小助手、植物识别小助手、篮球教练来说明使用流程,并提供了一个异步调用示例加速调用流程。注意以下流程用到的密钥可在图示位置中获取:\n",
"<img src=\"./app_builder_resources/secret.png\" alt=\"drawing\" width=\"1000\"/>\n",
"\n",
"\n",
Expand Down Expand Up @@ -179,6 +179,62 @@
"msg = builder.run(conversation_id, \"突破技巧中如何运用胯下变向?\", )\n",
"print(\"篮球教练回答内容:\", msg.content.answer)"
]
},
{
"cell_type": "markdown",
"id": "7acaf6bb",
"metadata": {},
"source": [
"## 4. 使用异步调用加速AppBuilderClient并发执行\n",
"SDK提供异步调用工作流Agent的接口。下面以3章节的“篮球教练”为例,演示如何使用异步调用加速AppBuilderClient并发执行。"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "fa87ffcb",
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"import appbuilder\n",
"import asyncio\n",
"\n",
"# 注意以下示例正确运行依赖的条件包括:\n",
"# 1. 在百度智能云千帆AppBuilder官网使用AppBuilderClient创建应用且应用已发布\n",
"# 2. 密钥正确有效\n",
"# 3. 密钥需要与发布的应用正确对应,即需要使用发布应用的账户下的密钥\n",
"\n",
"# 配置密钥与应用ID\n",
"os.environ[\"APPBUILDER_TOKEN\"] = \"...\"\n",
"app_id = \"4316a7cb-b6b2-4448-b6fa-ff131c484ec9\"\n",
"\n",
"async def agent_run(client, conversation_id, text):\n",
" ans = await client.run(conversation_id, text, stream=True)\n",
" async for data in ans.content:\n",
" print(data)\n",
"\n",
"\n",
"async def agent_sample():\n",
" client = appbuilder.AsyncAppBuilderClient(app_id)\n",
" conversation_id = await client.create_conversation()\n",
" file_id = await client.upload_local_file(\n",
" conversation_id, \"./python/tests/data/qa_appbuilder_client_demo.pdf\"\n",
" )\n",
" print(\"file_id is {}\".format(file_id))\n",
" task1 = asyncio.create_task(\n",
" agent_run(client, conversation_id, \"篮球技巧中如何三步上篮?\")\n",
" )\n",
" task2 = asyncio.create_task(\n",
" agent_run(client, conversation_id, \"突破技巧中如何运用胯下变向?\")\n",
" )\n",
" await asyncio.gather(task1, task2)\n",
" await client.http_client.session.close()\n",
"\n",
"if __name__ == \"__main__\":\n",
" loop = asyncio.get_event_loop()\n",
" loop.run_until_complete(agent_sample())"
]
}
],
"metadata": {
Expand Down
97 changes: 97 additions & 0 deletions cookbooks/end2end_application/agent/chatflow.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,103 @@
" 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": {},
Expand Down
110 changes: 109 additions & 1 deletion cookbooks/end2end_application/agent/tool_call.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -1147,7 +1147,115 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"# 6、项目总结\n",
"# 6 使用异步调用优化toolcall并发执行效率\n",
"SDK提供了异步调用接口,可以大幅提升并发执行效率。"
]
},
{
"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",
"\n",
"import appbuilder\n",
"import asyncio\n",
"from appbuilder.core.console.appbuilder_client.async_event_handler import (\n",
" AsyncAppBuilderEventHandler,\n",
")\n",
"\n",
"\n",
"class MyEventHandler(AsyncAppBuilderEventHandler):\n",
" def get_current_weather(self, location=None, unit=\"摄氏度\"):\n",
" return \"{} 的温度是 {} {}\".format(location, 20, unit)\n",
"\n",
" async def interrupt(self, run_context, run_response):\n",
" thought = run_context.current_thought\n",
" # 绿色打印\n",
" print(\"\\033[1;32m\", \"-> Agent 中间思考: \", thought, \"\\033[0m\")\n",
"\n",
" tool_output = []\n",
" for tool_call in run_context.current_tool_calls:\n",
" tool_call_id = tool_call.id\n",
" tool_res = self.get_current_weather(**tool_call.function.arguments)\n",
" # 蓝色打印\n",
" print(\"\\033[1;34m\", \"-> 本地ToolCallId: \", tool_call_id, \"\\033[0m\")\n",
" print(\"\\033[1;34m\", \"-> ToolCall结果: \", tool_res, \"\\033[0m\\n\")\n",
" tool_output.append({\"tool_call_id\": tool_call_id, \"output\": tool_res})\n",
" return tool_output\n",
"\n",
" async def success(self, run_context, run_response):\n",
" print(\"\\n\\033[1;31m\", \"-> Agent 非流式回答: \", run_response.answer, \"\\033[0m\")\n",
"\n",
"\n",
"def main():\n",
" app_id = \"b2a972c5-e082-46e5-b313-acbf51792422\"\n",
" tools = [\n",
" {\n",
" \"type\": \"function\",\n",
" \"function\": {\n",
" \"name\": \"get_current_weather\",\n",
" \"description\": \"仅支持中国城市的天气查询,参数location为中国城市名称,其他国家城市不支持天气查询\",\n",
" \"parameters\": {\n",
" \"type\": \"object\",\n",
" \"properties\": {\n",
" \"location\": {\n",
" \"type\": \"string\",\n",
" \"description\": \"城市名,举例:北京\",\n",
" },\n",
" \"unit\": {\"type\": \"string\", \"enum\": [\"摄氏度\", \"华氏度\"]},\n",
" },\n",
" \"required\": [\"location\", \"unit\"],\n",
" },\n",
" },\n",
" }\n",
" ]\n",
"\n",
" appbuilder.logger.setLoglevel(\"ERROR\")\n",
"\n",
" async def agent_run(client, query):\n",
" conversation_id = await client.create_conversation()\n",
" with await client.run_with_handler(\n",
" conversation_id=conversation_id,\n",
" query=query,\n",
" tools=tools,\n",
" event_handler=MyEventHandler(),\n",
" ) as run:\n",
" await run.until_done()\n",
"\n",
" async def agent_handle():\n",
" client = appbuilder.AsyncAppBuilderClient(app_id)\n",
" task1 = asyncio.create_task(agent_run(client, \"北京的天气怎么样\"))\n",
" task2 = asyncio.create_task(agent_run(client, \"上海的天气怎么样\"))\n",
" await asyncio.gather(task1, task2)\n",
" await client.http_client.session.close()\n",
"\n",
" loop = asyncio.get_event_loop()\n",
" loop.run_until_complete(agent_handle())\n",
"\n",
"\n",
"if __name__ == \"__main__\":\n",
" main()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 7、项目总结\n",
"\n",
"本项目通过多个知识点的学习,以及两个使用AppBuilder-SDK的实操,最终完成了一个支持ToolCall AIAgent的构建。\n",
"\n",
Expand Down

0 comments on commit d7c816b

Please sign in to comment.