Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Agent cookbook增加异步调用内容(appbuilder_client、chatflow、tool_call) #684

Merged
merged 3 commits into from
Dec 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading