├── README.md └── docs ├── _sidebar.md ├── 第一章:Agent简介 ├── 1.1 Agent原理.md ├── 1.2 Agent原理深入+环境配置.md ├── demo-code │ ├── cfg_tool_template.json │ ├── 本地Function demo.ipynb │ └── 远程Function demo.ipynb └── imgs │ ├── 3_envs.png │ ├── Agent_bone.png │ ├── Agent_config.png │ ├── ReAct.png │ ├── ask_Agent_1.png │ ├── ask_Agent_2.png │ ├── ask_weather.png │ ├── create_Agent_1.png │ ├── dashscope_token.png │ ├── do_circle.png │ ├── load.png │ ├── model_list.png │ ├── modelscope_token.png │ ├── modelscope_tools.png │ ├── simple_LLM.png │ ├── using_AgentFabric.png │ ├── using_ChatGPT.png │ └── weather_2.jpg ├── 第三章:Agent应用展望 ├── 3.1 Agent通用创作思路.md ├── 3.2 Agent应用展望.md ├── demo-code │ ├── .gitignore │ └── dashscope-demo.ipynb └── imgs │ ├── 3-1.png │ ├── 3-3.png │ ├── 3-4.png │ ├── 3-5.png │ ├── 3-6.png │ ├── 3-7.png │ ├── 3-8.png │ └── 3-9.png └── 第二章:Agent实践 ├── 2.1 高德开放API实践.md ├── 2.2 日程规划小助手.md └── imgs ├── img.png ├── img_1.png ├── img_10.png ├── img_11.png ├── img_12.png ├── img_13.png ├── img_14.png ├── img_15.png ├── img_16.png ├── img_2.png ├── img_3.png ├── img_4.png ├── img_5.png ├── img_6.png ├── img_7.png ├── img_8.png └── img_9.png /README.md: -------------------------------------------------------------------------------- 1 | # agent-tutorial 2 | 3 | ## 教程介绍 4 | 本教程是 Datawhale 成员写作的关于 Agent 的教程,特点是通过实践引导学习者加深对Agent的理解。 5 | 6 | 目前已有的内容,主要用于支持《动手学Agent开发》学习活动,介绍如何使用 [ModelScope Agent](https://github.com/modelscope/modelscope-agent/tree/master) 开发一个智能助手,并探讨一些 Agent 的通用创作思路及应用展望。 7 | 8 | 学习活动详见[《动手学Agent应用开发》学习手册](https://datawhaler.feishu.cn/docx/DqaydpsFdovWonxDrYxcrBYxnkf)。 9 | 10 | ## 教程大纲 11 | 第1章:Agent入门简介 12 | - [Agent原理](./docs/第一章:Agent简介/1.1%20Agent原理.md) 13 | - [Agent原理深入+环境配置](./docs/第一章:Agent简介/1.2%20Agent原理深入+环境配置.md) 14 | 15 | 第2章:Agent实践:日程规划小助手 16 | - [高德开放API实践](./docs/第二章:Agent实践/2.1%20高德开放API实践.md) 17 | - [日程规划小助手](./docs/第二章:Agent实践/2.2%20日程规划小助手.md) 18 | 19 | 第3章:Agent应用展望 20 | - [Agent通用创作思路](./docs/第三章:Agent应用展望/3.1%20Agent通用创作思路.md) 21 | - [Agent应用展望](./docs/第三章:Agent应用展望/3.2%20Agent应用展望.md) 22 | -------------------------------------------------------------------------------- /docs/_sidebar.md: -------------------------------------------------------------------------------- 1 | - 目录 2 | - 第1章:Agent入门简介 3 | - [Agent原理](./第一章:Agent简介/1.1%20Agent原理.md) 4 | - [Agent原理深入+环境配置](./第一章:Agent简介/1.2%20Agent原理深入+环境配置.md) 5 | 6 | - 第2章:Agent实践:日程规划小助手 7 | - [高德开放API实践](./第二章:Agent实践/2.1%20高德开放API实践.md) 8 | - [基础准备:日程规划小助手](./第二章:Agent实践/2.2%20日程规划小助手.md) 9 | 10 | - 第3章:Agent应用展望 11 | - [Agent通用创作思路](./第三章:Agent应用展望/3.1%20Agent通用创作思路.md) 12 | - [Agent应用展望](./第三章:Agent应用展望/3.2%20Agent应用展望.md) 13 | -------------------------------------------------------------------------------- /docs/第一章:Agent简介/1.1 Agent原理.md: -------------------------------------------------------------------------------- 1 | # Agent原理 2 | 3 | ## 何为Agent 4 | 5 | Agent一词起源于拉丁语中的Agere,意思是“to do”。在LLM语境下,**Agent可以理解为在某种能自主理解、规划决策、执行复杂任务的智能体**。 6 | 7 | 比尔·盖茨曾发过一篇[长文](https://www.gatesnotes.com/AI-agents?ref=blog.glasp.co),里面如此评价Agent:**“一个对科技行业的冲击波”、“一场自‘输入命令到点击图标’变革之后计算机领域的最大变革”**。 8 | 9 | 盖茨坦言,现在软件还是相当笨的,不论你想在电脑上做什么,都必须自己选取应用程序。你可以用Word或是谷歌Docs起草商业计划书,但却无法让他们帮你发送电子邮件、分享自拍、分析数据、安排聚会或是购买电影票。因为再顶尖的程序,也没法全面了解你的工作、生活、兴趣爱好与人际关系,能为你做事的能力也极为有限。往往只有通过另一个人,比如你的好朋友或秘书,才有可能实现。 10 | 11 | 盖茨断言,未来五年,这种情况将彻底改变,你不必再为不同任务选用不同应用程序,只需用日常用语告诉Agent你的需求,Agent就能获取自己能获取到的信息,为你量身定做一个结果。在不久的将来,任何一个上网的用户都能拥有一个由AI驱动的助理,其功能将远超当今技术水平。 12 | 13 | 举个例子,当你想买一台相机,Agent将会帮你阅读淘宝上所有相机的评论区,总结它们,提出建议,并在您做出决定后帮你下订单,而不是简单的根据价格、销量、好评率等数据筛选商品。 14 | 15 | 而这所谓的Agent,可以被理解为一颗能自主使用工具、执行任务的“人造大脑”。 16 | 17 | **Agent并非ChatGPT升级版,它不仅告诉你“如何做”,更会帮你去做!** 18 | 19 | ## 进化:从LLM到Agent 20 | 21 | 人们一直期待能有个强悍的人工智能助手,帮助我们处理日常中各种复杂的问题,完成各种琐碎的任务。而以ChatGPT为首的LLM(大语言模型),因其“全知全能”的表现而闻名全球,同时也在学界和业界消灭了大多数的传统NLP(自然语言处理)任务,开辟了全新的NLP范式,同时被人们寄予厚望,将其看做是通向AGI(通用人工智能)的曙光。 22 | 23 |
24 |
25 | ChatGPT 26 |
27 |
28 |
图1.1 笔者向ChatGPT咨询专业问题,回答的头头是道
29 | 30 | 31 | 尽管ChatGPT的知识储备接近“全知全能”,但当你试着以AI助手的方式使用时就会发现,它只会“动嘴皮子”,不会“动手”,同时也不能回答一些如天气,时间之类的简单问题。 32 | 33 |
34 |
35 | 问天气 36 |
37 |
38 |
ChatGPT无法回答天气信息
39 | 40 | 41 | 笔者向ChatGPT查询今天天气,ChatGPT委婉的告诉笔者,其无法提供天气信息,原因是 42 | 43 | 1. 无法浏览互联网 44 | 2. 无法获取当前日期 45 | 46 | 至于为什么ChatGPT连当前日期都获取不了,这就得先了解下LLM的原理了。 47 | 48 | 关于ChatGPT等LLM最基本的原理,Datawhale有一篇专门的[教程(so-large-lm)](https://github.com/datawhalechina/so-large-lm),其引言部分写的比较详细。这里我简单阐述下其原理 49 | 50 | 对于GPT这类生成式语言模型而言,其本质上是一个自回归语言模型(Autoregressive Language Model),所谓自回归语言模型,就是基于序列数据的概率分布,通过建模当前词语与前面已生成词语的条件概率来预测下一个词语。 51 | 52 |
53 | 54 |
55 | 56 | 比如上图的例子, 模型输入不完整的一句话,随后每步会迭代输出下一个词组,直到结束。 57 | 58 | 尽管实际的模型远比这复杂,但总归都是自回归的模型。模型的输入只有文本,输出也只是文本,模型除了会打字,就没其他会的了,至于上网、查时间就没办法了。 59 | 60 | 尽管模型本身不支持除了打字以外的其他操作,但总有办法能用笔杆子曲线救国的,而这方法就是**Agent**。 61 | 62 | ## Agent的架构&用ModelScope简单实现一个Agent 63 | 64 | OpenAI应用研究主管翁丽莲(Lilian Weng)撰写过一篇blog: [LLM Powered Autonomous Agents](https://lilianweng.github.io/posts/2023-06-23-agent/),将 Agents 定义为LLM + memory + planning skills + tool use,即大语言模型、记忆、任务规划、工具使用的集合。 65 | 66 |
67 |
68 | ChatGPT 69 |
70 |

(Lilian Weng定义的Agent结构图)

71 |
72 | 73 | 其中,LLM是Agent的大脑,属于“中枢”模型,要求有以下3种能力: 74 | 75 | 1. planning skills:对问题进行拆解得到解决路径,既进行任务规划 76 | 2. tool use:评估自己所需的工具,进行工具选择,并生成调用工具请求 77 | 3. memory:短期记忆包括工具的返回值,已经完成的推理路径;长期记忆包括可访问的外部长期存储,例如知识库 78 | 79 | 光说不练假把式,笔者这就用ModelScope的AgentFabric给大家简单实现一个Agent演示下这个流程: 80 | 81 | 1. 打开AgentFabric 82 | 咱们点开[https://modelscope.cn/studios/modelscope/AgentFabric/summary](https://modelscope.cn/studios/modelscope/AgentFabric/summary),注册好账户登录进去 83 | 84 | 进去后,就会看到左边有一个聊天界面,你不用写任何代码,只需要在这打字就能创建一个Agent,而右边是体验界面,因为我之前创建过的原因,不小心提前泄露了结果。 85 | 86 |
87 | 88 |
89 | 90 | 2. 在聊天框中输入你想要的功能 91 | 92 | 这里我给个example,大家懒得打字的就填这个进去 93 | 94 | ``` 95 | 我想做一个能查询天气的agent,名字就叫“Datawhale&Modelscopeの天気予報”,要求能查询我指定城市今天的天气情况和温度信息,并画一幅图向我形象的展示出来。 96 | ``` 97 | 98 | 可以看到,它在回复的同时,多了2行字,分别是 “✅Config Updated! ✅Logo Updated!” 99 | 这是因为它在帮你调整Agent的配置,以及logo,不信你看看右边的logo和下方的那行小字是不是变了。 100 | 此外它还反问了你一些问题,比如城市和展示风格啥的,你可以不回复它,因为它会问个不停,你根本回复不完。这并不影响右边的Agent使用,当你在使用的过程中觉得效果不符合预期时,再回复让它修改就行。 101 | 102 |
103 | 104 |
105 | 106 | 107 | 3. 检查配置&提供Tool 108 | 咱们点进左上角的“Configure”,这里就是Agent的配置了,可以看到配置非常的简单,就是用自然语言做prompt描述功能而已。如果你是个Prompt Engineer,那就大胆的自己写prompt进去试试吧。 109 | 110 | 另外下面会有一栏“Capabilities”,这是这个Agent所具备的Tool,如“Wanx Image Generation”就是画画的,“高德天气”就是查天气的,这2个要勾选上,因为Agent要用到。 111 | 112 |
113 | 114 |
115 | 116 | 117 | 3. 体验我们的Agent 118 | 好了,现在就可以在右边的聊天框里体验我们的Agent了,这里我输入指令 119 | 120 | ``` 121 | 告诉我,今天广州市的天气怎么样?并为其画一幅图。 122 | ``` 123 | 124 | 它很给力的查出了广州的天气,并将其画了出来。 125 | 126 |
127 | 128 |
129 | 130 | 咱们再点开这几个▶试试 131 | 132 |
133 | 134 |
135 | 136 | 可以看到,在我发出指令后,Agent就已经将我的指令拆分成“天气查询”和“画图”这2个子任务了,并成功的调用了对应的工具完成任务~ 137 | 138 | 参考文献: 139 | 140 | [OpenAI打了个“响指”,AI Agent厂商重建护城河|36氪新风向-36氪 (36kr.com)](https://www.36kr.com/p/2550551402240391) 141 | 142 | [AI is about to completely change how you use computers | Bill Gates (gatesnotes.com)](https://www.gatesnotes.com/AI-agents?ref=blog.glasp.co) 143 | 144 | [AI Agent统一互联网? 比尔·盖茨重磅发文:彻底改变人机交互、颠覆软件行业 (qq.com)](https://mp.weixin.qq.com/s/vrF7gW1-aG9JkycA7kdk9A) 145 | 146 | [LLM Powered Autonomous Agents | Lil'Log (lilianweng.github.io)](https://lilianweng.github.io/posts/2023-06-23-agent/) 147 | 148 | [Lilian Weng on X: "Agent = LLM + memory + planning skills + tool use This is probably just a start of a new era :) https://t.co/Qtp6cHpz2Q" / X (twitter.com)](https://twitter.com/lilianweng/status/1673535600690102273) 149 | 150 | [Agent创建专用 · 创空间 (modelscope.cn)](https://modelscope.cn/studios/modelscope/AgentFabric/summary) 151 | 152 | [魔搭Agent大本营 · 魔搭社区 (modelscope.cn)](https://www.modelscope.cn/brand/view/agent) 153 | 154 | [datawhalechina/so-large-lm (github.com)](https://github.com/datawhalechina/so-large-lm) 155 | 156 | [【AI Agent】Agent的原理介绍与应用发展思考 - 知乎 (zhihu.com)](https://zhuanlan.zhihu.com/p/654652104) 157 | -------------------------------------------------------------------------------- /docs/第一章:Agent简介/1.2 Agent原理深入+环境配置.md: -------------------------------------------------------------------------------- 1 | # Agent原理深入+快速搭建demo 2 | 3 | ## 从prompt的角度再谈Agent 4 | 前面提到,Agent的核心是一个LLM(大语言模型),输入是文字、输出也是文字,那究竟是什么让一个语言模型拥有这么强大的能力呢?这之间关键的一点是模型Function Calling(函数调用)的能力。 5 | 6 | 在没有Function Calling的情况下,模型只能做到对输入的文字进行理解,然后输出对应的文字,没法主动与外部进行交互,只能做思想的巨人,行动的矮子。而有了Function Calling的能力,模型就能主动的与外部进行交互,从而实现更多的功能,这就是Agent的核心能力。 7 | 8 | 相信有不少同学应该都想过一个问题,如何让LLM不说废话,直接输出某个字眼?有过这个想法的同学,恭喜你,你已经有了Function Calling的雏形。因为这个问题背后的本质是:怎么用代码解析LLM输出的毫无章法的文字? 9 | 10 | 在各种实际应用中,没人会自找麻烦的解析LLM不可控的输出,而是会事先和LLM约法三章,约定好输出格式,自己按规则进行解析。比如ReAct范数约定的回复格式就是: 11 | - Thought: (LLM的思考/想说的话) 12 | - Action: (想调用的函数) 13 | - Observation: (刚才调用函数的返回) 14 | 15 | 而在业界,Agent的工作原理和[ReAct](https://arxiv.org/abs/2210.03629)论文的实现大同小异,即"想"清楚再"行动" 16 |
17 |
18 | 19 |
20 |
21 |
ReAct的工作流程
22 | 23 | 工作流程大体是如此,在Action那一步调用函数,Observation返回函数执行结果,但到这步应该还有同学会疑惑,一个语言模型是怎么调用函数的?没关系,下面我接着讲。 24 | 25 | 这里我用ModelScope-Agent-7B做为Agent中枢,选它的原因主要是prompt更本土化(中文的,方便演示)。 26 | 27 | 我们以modelscope-agent框架的一个例子为例 28 | https://mp.weixin.qq.com/s/L3GiV2QHeybhVZSg_g_JRw 29 | 30 | 首先,咱们先注册一个Tool,让Agent调用,代码见下 31 | ~~~python 32 | from modelscope_agent.tools import Tool 33 | 34 | class AliyunRenewInstanceTool(Tool): 35 | description = '续费一台包年包月ECS实例' 36 | name = 'RenewInstance' 37 | parameters: list = [{ 38 | 'name': 'instance_id', 39 | 'description': 'ECS实例ID', 40 | 'required': True 41 | }, 42 | { 43 | 'name': 'period', 44 | 'description': '续费时长以月为单位', 45 | 'required': True 46 | } 47 | ] 48 | 49 | def _local_call(self, *args, **kwargs): 50 | instance_id = kwargs['instance_id'] 51 | period = kwargs['period'] 52 | return {'result': f'成功为{instance_id}续费,续费时长{period}月'} 53 | ~~~ 54 | 这个Tool的注册很简单,简单的从Tool类继承个子类,然后在子类中定义好这几个属性即可。 55 | 56 | 1. name 57 | 2. description、parameters 58 | 3. _local_call(远程版为:_remote_call) 59 | 60 | 其中,name和description是Tool的基本信息,parameters是Tool的参数信息,_local_call是Tool的调用方法。现在不理解这些没关系,看下面的prompt你就懂了,下面的内容为方便肉眼分析,我把里面的json格式化为了易于人类阅读的格式。 61 | 62 | 63 | ~~~ 64 | <|system|>:你是达摩院的ModelScopeGPT(魔搭助手),你是个大语言模型, 是2023年达摩院的工程师训练得到的。你有多种能力,可以通过插件集成魔搭社区的模型api来回复用户的问题,还能解答用户使用模型遇到的问题和模型知识相关问答。 65 | 66 | 67 | 当前对话可以使用的插件信息如下,请自行判断是否需要调用插件来解决当前用户问题。若需要调用插件,则需要将插件调用请求按照json格式给出,必须包含api_name、parameters字段,并在其前后使用<|startofthink|>和<|endofthink|>作为标志。然后你需要根据插件API调用结果生成合理的答复; 若无需调用插件,则直接给出对应回复即可。 68 | 69 | 1. { 70 | "name": "RenewInstance", 71 | "description": "续费一台包年包月ECS实例", 72 | "parameters": [ 73 | { 74 | "name": "instance_id", 75 | "description": "ECS实例ID", 76 | "required": true 77 | }, 78 | { 79 | "name": "period", 80 | "description": "续费时长以月为单位", 81 | "required": true 82 | } 83 | ] 84 | } 85 | 86 | <|user|>:请帮我续费一台ECS实例,实例id是:i-rj90a7e840y5cde,续费时长10个月 87 | 88 | <|assistant|>: 89 | ~~~ 90 | 91 | 这prompt大概意思是,你现在能用的工具就这个,想调用就在<|startofthink|>和<|endofthink|>中用json格式写出来。 92 | 93 | 具体怎么写,让我们看看ModelScope-Agent-7B模型的回复 94 | 95 | ~~~ 96 | 好的,我现在帮你调用续费接口,请稍等片刻 97 | <|startofthink|>```JSON 98 | { 99 | "api_name": "RenewInstance", 100 | "url": "https://ecs.aliyuncs.com/renewinstance", 101 | "parameters": { 102 | "instance_id": "i-rj90a7e840y5cde", 103 | "period": 10 104 | } 105 | } 106 | ```<|endofthink|> 107 | ~~~ 108 | 109 | 熟悉json和markdown的同学应该都看出来了,尽管我没要求输出 \```JSON ... \```,但模型还是自动的给我加上了。这里给不熟悉markdown的朋友科普下,这语法是代码块,并且注明了里面的语言是json,如果我不加任何转义符就写在教程里,呈现出的效果就是这样。 110 | 111 | ~~~JSON 112 | { 113 | "api_name": "RenewInstance", 114 | "url": "https://ecs.aliyuncs.com/renewinstance", 115 | "parameters": { 116 | "instance_id": "i-rj90a7e840y5cde", 117 | "period": 10 118 | } 119 | } 120 | ~~~ 121 | 122 | 这是因为,模型的输出能被解析为代码块,因此能用程序定位出json的位置。然后咱们再解析下这段json,出来的结果是这样的 123 | 124 |
125 |
126 | 127 |
128 |
129 | 130 | 相信会python的同学到这步已经看出来了,目标函数的名称和参数都列好了,至于怎么进行function call,相信有点编程基础的都是轻车熟路,我就不多说了。 131 | 132 | 眼尖的同学可能会注意到,这里面多了个url字段,这纯粹是模型自作多情加上去的,但不影响我们调用函数,可以忽略。 133 | 134 | ### 用LLM的第一视角体验流程 135 | 为方便理解,我基于modelscope-agent和gradio开发了一个小游戏demo,简而言之就是让玩家扮演LLM,自己根据任务要求人工进行规划和函数调用…… 136 | 137 | ![image](https://github.com/datawhalechina/agent-tutorial/assets/28804414/f7bfa6b1-3d22-4966-963b-10e386c66644) 138 | 139 | 链接: 140 | 141 | huggingface版:https://huggingface.co/spaces/jianuo/I-am-agent 142 | 143 | 魔搭版:https://modelscope.cn/studios/nuonuo/I-am-agent/summary 144 | 145 | 146 | ## ModelScope-Agent框架本地安装 147 | 148 | 尽管ModelScope社区为开发者提供了更加便捷的云开发服务,如[PAI-DSW](https://modelscope.cn/my/mynotebook/preset)和[AgentFabric](https://modelscope.cn/studios/modelscope/AgentFabric/summary),但我还是要教大家本地开发,一是云开发有一定局限性,二是当你能解决好本地开发中的各种问题如环境配置、依赖安装后,云开发对你来说就是小菜一碟了。 149 | 150 | ### 1. 安装框架与依赖 151 | 152 | 第一步需要clone下ModelScope-Agent的代码,然后安装。没安装过git的,看这篇教程安装下:[git安装教程](https://www.liaoxuefeng.com/wiki/896043488029600/896067074338496) 153 | 154 | ~~~bash 155 | git clone https://github.com/modelscope/modelscope-agent.git 156 | cd modelscope-agent && pip install -r requirements.txt 157 | ~~~ 158 | 159 | ### 2. 获取api-key 160 | 我们一共要获取2个key,一个是用于LLM推理的dashscope平台的key,一个是用于远程Tool调用的modelscope平台的key(可选)。 161 | 162 | 首先是dashscope平台的key,直接点击下方链接登录上去就能获取key了 163 | https://dashscope.console.aliyun.com/apiKey 164 |
165 |
166 | 167 |
168 |
169 | 170 | 这里建议优先用qwen-max或qwen-max-longcontext模型,因为它们是免费的。 171 | 172 |
173 |
174 | 175 |
176 |
177 | 178 | 179 | 然后是modelscope平台的key,modelscope-agent内置了一些Tools,可以很方便的调用,但调用它们之前得先获取key。 180 | https://modelscope.cn/my/myaccesstoken 181 | 182 |
183 |
184 | 185 |
186 |
187 | 188 | 下面是modelscope-agent内置的Tools,挺丰富的。 189 | 190 |
191 |
192 | 193 |
194 |
195 | 196 | ### 3. 配置环境变量 197 | 在代码开头,咱们直接把之前获取的api key写进环境变量里就行。 198 | 此外还要额外设置`KMP_DUPLICATE_LIB_OK=TRUE`,否则容易出现一些玄学BUG,这个BUG一时半会讲不清,详细看我的这篇文章:[就是他!让你的python内核莫名挂掉 | KMP_DUPLICATE_LIB_OK=TRUE 的始作俑者](https://zhuanlan.zhihu.com/p/655915099) 199 | ~~~python 200 | import os 201 | 202 | os.environ['KMP_DUPLICATE_LIB_OK'] = "TRUE" 203 | os.environ['DASHSCOPE_API_KEY'] = "xxxxxxxxxxxxxx" 204 | os.environ['MODELSCOPE_API_TOKEN'] = 'xxxxxxxxxxxxxx' 205 | ~~~ 206 | 207 |
208 |
209 | 210 |
211 |
212 | 213 | ### 4. 运行demo 214 | 这里我写了2个demo,分别是本地调用自己的Tool和远程调用modelscope-agent内置的Tool,大家进去后看下代码就能照猫画虎的学会写法了。 215 | 216 | [本地函数调用demo](./demo-code/本地Function%20demo.ipynb) 217 | 218 | [远程函数调用demo](./demo-code/远程Function%20demo.ipynb) 219 | 220 | modelscope-agent的文档还不算完善,但主要的功能文档基本都写在repo的README里了,直接看就行。 221 | 222 | https://github.com/modelscope/modelscope-agent/tree/master 223 | 224 | 下面这些是官方的demo,不过可能会因为版本更新的原因跑不通,参考下就好。 225 | 226 | https://github.com/modelscope/modelscope-agent/tree/master/demo 227 | -------------------------------------------------------------------------------- /docs/第一章:Agent简介/demo-code/cfg_tool_template.json: -------------------------------------------------------------------------------- 1 | { 2 | "modelscope_text-address": { 3 | "url": "https://api-inference.modelscope.cn/api-inference/v1/models/damo/mgeo_geographic_elements_tagging_chinese_base", 4 | "use": true 5 | }, 6 | "modelscope_text-ner": { 7 | "url": "https://api-inference.modelscope.cn/api-inference/v1/models/damo/nlp_raner_named-entity-recognition_chinese-base-cmeee", 8 | "use": true 9 | }, 10 | "modelscope_text-ie": { 11 | "url": "https://api-inference.modelscope.cn/api-inference/v1/models/damo/nlp_structbert_siamese-uie_chinese-base", 12 | "use": true 13 | }, 14 | "modelscope_speech-generation": { 15 | "url": "https://api-inference.modelscope.cn/api-inference/v1/models/damo/speech_sambert-hifigan_tts_zh-cn_16k", 16 | "use": true 17 | }, 18 | "modelscope_video-generation": { 19 | "url": "https://api-inference.modelscope.cn/api-inference/v1/models/damo/text-to-video-synthesis", 20 | "use": true 21 | }, 22 | "modelscope_image-chat": { 23 | "url": "https://api-inference.modelscope.cn/api-inference/v1/models/damo/multi-modal_mplug_owl_multimodal-dialogue_7b", 24 | "use": true 25 | }, 26 | "modelscope_text-translation-en2zh": { 27 | "url": "https://api-inference.modelscope.cn/api-inference/v1/models/damo/nlp_csanmt_translation_en2zh", 28 | "use": true 29 | }, 30 | "modelscope_text-translation-zh2en": { 31 | "url": "https://api-inference.modelscope.cn/api-inference/v1/models/damo/nlp_csanmt_translation_zh2en", 32 | "use": true 33 | }, 34 | "image_gen": { 35 | "url": "https://api-inference.modelscope.cn/api-inference/v1/models/AI-ModelScope/stable-diffusion-xl-base-1.0", 36 | "use": true, 37 | "pipeline_params": { 38 | "use_safetensors": true 39 | } 40 | }, 41 | "amap_weather": { 42 | "use": false, 43 | "token": "need to be filled when you use weather" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /docs/第一章:Agent简介/demo-code/本地Function demo.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "outputs": [], 7 | "source": [ 8 | "import os\n", 9 | "\n", 10 | "os.environ['KMP_DUPLICATE_LIB_OK'] = \"TRUE\"\n", 11 | "os.environ['DASHSCOPE_API_KEY'] = \"xxxxxxxxxxx\"\n", 12 | "os.environ['MODELSCOPE_API_TOKEN'] = 'xxxxxxxxxxxx'" 13 | ], 14 | "metadata": { 15 | "collapsed": false, 16 | "is_executing": true 17 | }, 18 | "id": "5f5e1266bed5714f" 19 | }, 20 | { 21 | "cell_type": "code", 22 | "execution_count": null, 23 | "outputs": [], 24 | "source": [ 25 | "prompts = []\n", 26 | "outputs = []\n", 27 | "\n", 28 | "# 这个是python的猴子补丁(Monkey Patching) ,这里用于hook住modelscope_agent的代码,以便我们可以查看模型的input和output\n", 29 | "def fix_1():\n", 30 | " import os\n", 31 | " import random\n", 32 | " import traceback\n", 33 | " from http import HTTPStatus\n", 34 | " from typing import Union\n", 35 | "\n", 36 | " import dashscope\n", 37 | " import json\n", 38 | " from dashscope import Generation\n", 39 | " from modelscope_agent.agent_types import AgentType\n", 40 | "\n", 41 | " from modelscope_agent.llm.base import LLM\n", 42 | " from modelscope_agent.llm.utils import DEFAULT_MESSAGE, CustomOutputWrapper\n", 43 | "\n", 44 | " class my_DashScopeLLM(LLM):\n", 45 | " name = 'dashscope_llm'\n", 46 | "\n", 47 | " def __init__(self, cfg):\n", 48 | " super().__init__(cfg)\n", 49 | " self.model = self.cfg.get('model', 'modelscope-agent-llm-v1')\n", 50 | " self.model_id = self.model\n", 51 | " self.generate_cfg = self.cfg.get('generate_cfg', {})\n", 52 | " self.agent_type = self.cfg.get('agent_type', AgentType.DEFAULT)\n", 53 | "\n", 54 | " def generate(self,\n", 55 | " llm_artifacts: Union[str, dict],\n", 56 | " functions=[],\n", 57 | " **kwargs):\n", 58 | " prompts.append(llm_artifacts)\n", 59 | "\n", 60 | " # TODO retry and handle message\n", 61 | " try:\n", 62 | " if self.agent_type == AgentType.Messages:\n", 63 | " messages = llm_artifacts if len(\n", 64 | " llm_artifacts) > 0 else DEFAULT_MESSAGE\n", 65 | " self.generate_cfg['use_raw_prompt'] = False\n", 66 | " response = dashscope.Generation.call(\n", 67 | " model=self.model,\n", 68 | " messages=messages,\n", 69 | " # set the random seed, optional, default to 1234 if not set\n", 70 | " seed=random.randint(1, 10000),\n", 71 | " result_format=\n", 72 | " 'message', # set the result to be \"message\" format.\n", 73 | " stream=False,\n", 74 | " **self.generate_cfg)\n", 75 | " llm_result = CustomOutputWrapper.handle_message_chat_completion(\n", 76 | " response)\n", 77 | " else:\n", 78 | " response = Generation.call(\n", 79 | " model=self.model,\n", 80 | " prompt=llm_artifacts,\n", 81 | " stream=False,\n", 82 | " **self.generate_cfg)\n", 83 | " llm_result = CustomOutputWrapper.handle_message_text_completion(\n", 84 | " response)\n", 85 | " outputs.append(llm_result)\n", 86 | " return llm_result\n", 87 | " except Exception as e:\n", 88 | " error = traceback.format_exc()\n", 89 | " error_msg = f'LLM error with input {llm_artifacts} \\n dashscope error: {str(e)} with traceback {error}'\n", 90 | " print(error_msg)\n", 91 | " raise RuntimeError(error)\n", 92 | "\n", 93 | " if self.agent_type == AgentType.MS_AGENT:\n", 94 | " # in the form of text\n", 95 | " idx = llm_result.find('<|endofthink|>')\n", 96 | " if idx != -1:\n", 97 | " llm_result = llm_result[:idx + len('<|endofthink|>')]\n", 98 | " return llm_result\n", 99 | " elif self.agent_type == AgentType.Messages:\n", 100 | " # in the form of message\n", 101 | " return llm_result\n", 102 | " else:\n", 103 | " # in the form of text\n", 104 | " return llm_result\n", 105 | "\n", 106 | " def stream_generate(self,\n", 107 | " llm_artifacts: Union[str, dict],\n", 108 | " functions=[],\n", 109 | " **kwargs):\n", 110 | " print('stream_generate')\n", 111 | " prompts.append(llm_artifacts)\n", 112 | "\n", 113 | " total_response = ''\n", 114 | " try:\n", 115 | " if self.agent_type == AgentType.Messages:\n", 116 | " self.generate_cfg['use_raw_prompt'] = False\n", 117 | " responses = Generation.call(\n", 118 | " model=self.model,\n", 119 | " messages=llm_artifacts,\n", 120 | " stream=True,\n", 121 | " result_format='message',\n", 122 | " **self.generate_cfg)\n", 123 | " else:\n", 124 | " responses = Generation.call(\n", 125 | " model=self.model,\n", 126 | " prompt=llm_artifacts,\n", 127 | " stream=True,\n", 128 | " **self.generate_cfg)\n", 129 | " except Exception as e:\n", 130 | " error = traceback.format_exc()\n", 131 | " error_msg = f'LLM error with input {llm_artifacts} \\n dashscope error: {str(e)} with traceback {error}'\n", 132 | " print(error_msg)\n", 133 | " raise RuntimeError(error)\n", 134 | "\n", 135 | " for response in responses:\n", 136 | " if response.status_code == HTTPStatus.OK:\n", 137 | " if self.agent_type == AgentType.Messages:\n", 138 | " llm_result = CustomOutputWrapper.handle_message_chat_completion(\n", 139 | " response)\n", 140 | " frame_text = llm_result['content'][len(total_response):]\n", 141 | " else:\n", 142 | " llm_result = CustomOutputWrapper.handle_message_text_completion(\n", 143 | " response)\n", 144 | " frame_text = llm_result[len(total_response):]\n", 145 | " yield frame_text\n", 146 | "\n", 147 | " if self.agent_type == AgentType.Messages:\n", 148 | " total_response = llm_result['content']\n", 149 | " else:\n", 150 | " total_response = llm_result\n", 151 | " else:\n", 152 | " err_msg = 'Error Request id: %s, Code: %d, status: %s, message: %s' % (\n", 153 | " response.request_id, response.status_code, response.code,\n", 154 | " response.message)\n", 155 | " print(err_msg)\n", 156 | " raise RuntimeError(err_msg)\n", 157 | "\n", 158 | " from modelscope_agent.llm import dashscope_llm\n", 159 | " dashscope_llm.DashScopeLLM = my_DashScopeLLM\n", 160 | "\n", 161 | "fix_1() # 如果不需要查看模型的input和output,可以不用执行这个cell" 162 | ], 163 | "metadata": { 164 | "collapsed": false, 165 | "is_executing": true 166 | }, 167 | "id": "ec5665513daf6d22" 168 | }, 169 | { 170 | "cell_type": "code", 171 | "execution_count": null, 172 | "outputs": [], 173 | "source": [ 174 | "from modelscope_agent.tools import Tool\n", 175 | "from modelscope_agent.llm import LLMFactory\n", 176 | "from modelscope_agent.prompt import MSPromptGenerator, MrklPromptGenerator\n", 177 | "from modelscope_agent.output_parser import MsOutputParser, MRKLOutputParser\n", 178 | "from modelscope.utils.config import Config\n", 179 | "from modelscope_agent.agent import AgentExecutor\n", 180 | "\n", 181 | "model_name = 'modelscope-agent'\n", 182 | "model_cfg = {\n", 183 | " \"qwen-max\": {\n", 184 | " \"type\": \"dashscope\",\n", 185 | " \"model\": \"qwen-max\",\n", 186 | " \"generate_cfg\": {\n", 187 | " \"use_raw_prompt\": True,\n", 188 | " \"top_p\": 0.8,\n", 189 | " \"debug\": False\n", 190 | " }\n", 191 | " },\n", 192 | " \"modelscope-agent\": {\n", 193 | " \"type\": \"dashscope\",\n", 194 | " \"model\": \"modelscope-agent-llm-v1\",\n", 195 | " \"generate_cfg\": {\n", 196 | " \"use_raw_prompt\": True,\n", 197 | " \"top_p\": 0.8,\n", 198 | " \"seed\": 666,\n", 199 | " \"debug\": True\n", 200 | " }\n", 201 | " }\n", 202 | "}\n", 203 | "\n", 204 | "llm = LLMFactory.build_llm(model_name, model_cfg)" 205 | ], 206 | "metadata": { 207 | "collapsed": false, 208 | "is_executing": true 209 | }, 210 | "id": "6fa67f0021c05bdb" 211 | }, 212 | { 213 | "cell_type": "code", 214 | "execution_count": null, 215 | "outputs": [], 216 | "source": [ 217 | "# prompt_generator = MrklPromptGenerator(llm=llm)\n", 218 | "# output_parser = MRKLOutputParser()\n", 219 | "\n", 220 | "prompt_generator = MSPromptGenerator()\n", 221 | "output_parser = MsOutputParser()\n", 222 | "\n", 223 | "from modelscope_agent.tools import Tool\n", 224 | "\n", 225 | "class AliyunRenewInstanceTool(Tool):\n", 226 | " description = '续费一台包年包月ECS实例'\n", 227 | " name = 'RenewInstance'\n", 228 | " parameters: list = [{\n", 229 | " 'name': 'instance_id',\n", 230 | " 'description': 'ECS实例ID',\n", 231 | " 'required': True\n", 232 | " },\n", 233 | " {\n", 234 | " 'name': 'period',\n", 235 | " 'description': '续费时长以月为单位',\n", 236 | " 'required': True\n", 237 | " }\n", 238 | " ]\n", 239 | "\n", 240 | " def _local_call(self, *args, **kwargs):\n", 241 | " instance_id = kwargs['instance_id']\n", 242 | " period = kwargs['period']\n", 243 | " return {'result': f'成功为{instance_id}续费,续费时长{period}月'}\n", 244 | "\n", 245 | "\n", 246 | "additional_tool_list = {\n", 247 | " 'RenewInstance': AliyunRenewInstanceTool()\n", 248 | "}\n", 249 | "\n", 250 | "agent = AgentExecutor(llm, additional_tool_list=additional_tool_list, tool_retrieval=False,\n", 251 | " prompt_generator=prompt_generator, output_parser=output_parser)\n" 252 | ], 253 | "metadata": { 254 | "collapsed": false, 255 | "is_executing": true 256 | }, 257 | "id": "ba8d856e4d435135" 258 | }, 259 | { 260 | "cell_type": "code", 261 | "execution_count": null, 262 | "outputs": [], 263 | "source": [ 264 | "# 重置对话,清空对话历史\n", 265 | "agent.reset()\n", 266 | "available_tool_list = ['RenewInstance']\n", 267 | "agent.set_available_tools(available_tool_list)\n", 268 | "agent.run(\"请帮我续费一台ECS实例,实例id是:i-rj90a7e840y5cde,续费时长10个月\", remote=False, print_info=True)" 269 | ], 270 | "metadata": { 271 | "collapsed": false, 272 | "is_executing": true 273 | }, 274 | "id": "fd9e2d7205344908" 275 | }, 276 | { 277 | "cell_type": "code", 278 | "execution_count": null, 279 | "outputs": [], 280 | "source": [ 281 | "print(prompts[0])" 282 | ], 283 | "metadata": { 284 | "collapsed": false, 285 | "is_executing": true 286 | }, 287 | "id": "848a11d80f4362d5" 288 | }, 289 | { 290 | "cell_type": "code", 291 | "execution_count": null, 292 | "outputs": [], 293 | "source": [ 294 | "print(prompts[1])" 295 | ], 296 | "metadata": { 297 | "collapsed": false, 298 | "is_executing": true 299 | }, 300 | "id": "16cf6c9e0c518368" 301 | }, 302 | { 303 | "cell_type": "code", 304 | "execution_count": null, 305 | "outputs": [], 306 | "source": [ 307 | "print(outputs[0])" 308 | ], 309 | "metadata": { 310 | "collapsed": false, 311 | "is_executing": true 312 | }, 313 | "id": "27afd9f150b629f4" 314 | }, 315 | { 316 | "cell_type": "code", 317 | "execution_count": null, 318 | "outputs": [], 319 | "source": [ 320 | "print(outputs[1])" 321 | ], 322 | "metadata": { 323 | "collapsed": false, 324 | "is_executing": true 325 | }, 326 | "id": "bd804553cc4220c2" 327 | }, 328 | { 329 | "cell_type": "code", 330 | "execution_count": null, 331 | "outputs": [], 332 | "source": [ 333 | "import json\n", 334 | "txt = \"\"\"\n", 335 | "{\n", 336 | " \"api_name\": \"RenewInstance\",\n", 337 | " \"url\": \"https://ecs.aliyuncs.com/renewinstance\",\n", 338 | " \"parameters\": {\n", 339 | " \"instance_id\": \"i-rj90a7e840y5cde\",\n", 340 | " \"period\": 10\n", 341 | " }\n", 342 | "}\n", 343 | "\"\"\"\n", 344 | "data = json.loads(txt)" 345 | ], 346 | "metadata": { 347 | "collapsed": false, 348 | "is_executing": true 349 | }, 350 | "id": "8e5a86268d97a375" 351 | }, 352 | { 353 | "cell_type": "code", 354 | "execution_count": null, 355 | "outputs": [], 356 | "source": [ 357 | "data" 358 | ], 359 | "metadata": { 360 | "collapsed": false, 361 | "is_executing": true 362 | }, 363 | "id": "5797addb7e0ec342" 364 | }, 365 | { 366 | "cell_type": "code", 367 | "execution_count": null, 368 | "outputs": [], 369 | "source": [], 370 | "metadata": { 371 | "collapsed": false, 372 | "is_executing": true 373 | }, 374 | "id": "2a782e05a4e39c8b" 375 | } 376 | ], 377 | "metadata": { 378 | "kernelspec": { 379 | "display_name": "Python 3", 380 | "language": "python", 381 | "name": "python3" 382 | }, 383 | "language_info": { 384 | "codemirror_mode": { 385 | "name": "ipython", 386 | "version": 2 387 | }, 388 | "file_extension": ".py", 389 | "mimetype": "text/x-python", 390 | "name": "python", 391 | "nbconvert_exporter": "python", 392 | "pygments_lexer": "ipython2", 393 | "version": "2.7.6" 394 | } 395 | }, 396 | "nbformat": 4, 397 | "nbformat_minor": 5 398 | } 399 | -------------------------------------------------------------------------------- /docs/第一章:Agent简介/imgs/3_envs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/agent-tutorial/1efa90d39740846b0e5e038aa01438993e5dfe60/docs/第一章:Agent简介/imgs/3_envs.png -------------------------------------------------------------------------------- /docs/第一章:Agent简介/imgs/Agent_bone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/agent-tutorial/1efa90d39740846b0e5e038aa01438993e5dfe60/docs/第一章:Agent简介/imgs/Agent_bone.png -------------------------------------------------------------------------------- /docs/第一章:Agent简介/imgs/Agent_config.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/agent-tutorial/1efa90d39740846b0e5e038aa01438993e5dfe60/docs/第一章:Agent简介/imgs/Agent_config.png -------------------------------------------------------------------------------- /docs/第一章:Agent简介/imgs/ReAct.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/agent-tutorial/1efa90d39740846b0e5e038aa01438993e5dfe60/docs/第一章:Agent简介/imgs/ReAct.png -------------------------------------------------------------------------------- /docs/第一章:Agent简介/imgs/ask_Agent_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/agent-tutorial/1efa90d39740846b0e5e038aa01438993e5dfe60/docs/第一章:Agent简介/imgs/ask_Agent_1.png -------------------------------------------------------------------------------- /docs/第一章:Agent简介/imgs/ask_Agent_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/agent-tutorial/1efa90d39740846b0e5e038aa01438993e5dfe60/docs/第一章:Agent简介/imgs/ask_Agent_2.png -------------------------------------------------------------------------------- /docs/第一章:Agent简介/imgs/ask_weather.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/agent-tutorial/1efa90d39740846b0e5e038aa01438993e5dfe60/docs/第一章:Agent简介/imgs/ask_weather.png -------------------------------------------------------------------------------- /docs/第一章:Agent简介/imgs/create_Agent_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/agent-tutorial/1efa90d39740846b0e5e038aa01438993e5dfe60/docs/第一章:Agent简介/imgs/create_Agent_1.png -------------------------------------------------------------------------------- /docs/第一章:Agent简介/imgs/dashscope_token.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/agent-tutorial/1efa90d39740846b0e5e038aa01438993e5dfe60/docs/第一章:Agent简介/imgs/dashscope_token.png -------------------------------------------------------------------------------- /docs/第一章:Agent简介/imgs/do_circle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/agent-tutorial/1efa90d39740846b0e5e038aa01438993e5dfe60/docs/第一章:Agent简介/imgs/do_circle.png -------------------------------------------------------------------------------- /docs/第一章:Agent简介/imgs/load.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/agent-tutorial/1efa90d39740846b0e5e038aa01438993e5dfe60/docs/第一章:Agent简介/imgs/load.png -------------------------------------------------------------------------------- /docs/第一章:Agent简介/imgs/model_list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/agent-tutorial/1efa90d39740846b0e5e038aa01438993e5dfe60/docs/第一章:Agent简介/imgs/model_list.png -------------------------------------------------------------------------------- /docs/第一章:Agent简介/imgs/modelscope_token.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/agent-tutorial/1efa90d39740846b0e5e038aa01438993e5dfe60/docs/第一章:Agent简介/imgs/modelscope_token.png -------------------------------------------------------------------------------- /docs/第一章:Agent简介/imgs/modelscope_tools.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/agent-tutorial/1efa90d39740846b0e5e038aa01438993e5dfe60/docs/第一章:Agent简介/imgs/modelscope_tools.png -------------------------------------------------------------------------------- /docs/第一章:Agent简介/imgs/simple_LLM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/agent-tutorial/1efa90d39740846b0e5e038aa01438993e5dfe60/docs/第一章:Agent简介/imgs/simple_LLM.png -------------------------------------------------------------------------------- /docs/第一章:Agent简介/imgs/using_AgentFabric.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/agent-tutorial/1efa90d39740846b0e5e038aa01438993e5dfe60/docs/第一章:Agent简介/imgs/using_AgentFabric.png -------------------------------------------------------------------------------- /docs/第一章:Agent简介/imgs/using_ChatGPT.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/agent-tutorial/1efa90d39740846b0e5e038aa01438993e5dfe60/docs/第一章:Agent简介/imgs/using_ChatGPT.png -------------------------------------------------------------------------------- /docs/第一章:Agent简介/imgs/weather_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/agent-tutorial/1efa90d39740846b0e5e038aa01438993e5dfe60/docs/第一章:Agent简介/imgs/weather_2.jpg -------------------------------------------------------------------------------- /docs/第三章:Agent应用展望/3.1 Agent通用创作思路.md: -------------------------------------------------------------------------------- 1 | # Agent 通用创作思路 2 | 通过前面章节的学习,我们已经对 Agent 有了基本的了解,并能根据教程的说明,通过 [ModelScope Agent](https://github.com/modelscope/modelscope-agent/tree/master) 的框架完成自己的 Agent 构建。 3 | 4 | 本章将回顾前文所提到的与 Agent 相关的概念,介绍其他 Agent 框架,并总结 Agent 通用创作思路 和未来的发展前景。 5 | 6 | ## 回顾 Agent 相关概念 7 | LLM的潜力不仅限于生成写得很好的副本、故事、文章和程序,通过 构建Agent级别的应用 ,还可以作为一种强大的工具解决通用问题。 8 |
9 |
10 | 11 |
12 |
13 |
生成式AI产品的分级 @ZhenFund 14 |

15 | 16 | Agent 可大致被定义为如下图所示的系统:Agents = LLM + memory + planning skills + tool use 17 | 18 |
19 |
20 | 21 |
22 |
23 |
由LLM驱动的Autonomouse Agent 系统
24 | @Lilian Weng 25 |

26 | 27 | Agent 在 Planning(规划)的过程中,涉及到拆解步骤(Subgoal decomposition)并提前规划(Chain of thoughts),并在进行相应的 执行与反思(Self-critics + Reflection),对过去执行的动作进行反思,以进一步推进任务进展。 28 | 29 | 执行与反思,目前大部分 Agent 框架,都会使用 ReAct (Reason + Act) 的框架进行实现,即 Thought + Action + Observation 框架: 30 | 31 |
32 |
33 | 34 |
35 |
36 |
知识密集型任务(如HotpotQA、FEVER)和
37 | 决策型任务(如AlfWorld Env、WebShop)
38 | 的推理轨迹示例
39 | @Shunyu Yao等 40 |

41 | 42 | ## 常见的主流 Agent 框架简介 43 | 除了魔搭开源的[ModelScope-Agent](https://github.com/modelscope/modelscope-agent/blob/master/README_CN.md),AI Agent 领域还有许多开源框架,它们各自有不同的特点和应用场景,一些较为常见的主流框架有: 44 | 45 | ### [ModelScope-Agent](https://github.com/modelscope/modelscope-agent/blob/master/README_CN.md) 46 | 47 | [ModelScope-Agent](https://github.com/modelscope/modelscope-agent/blob/master/README_CN.md)是由阿里云AI模型社区魔搭(ModelScope)2023.8.7发布的开源框架,代码清晰简洁。 48 | 49 | 提供了一个通用的、可定制的Agent框架。它提供了一个用户友好的系统库, 具有可定制且功能全面的框架、使用开源LLMs作为核心组件、支持多样化且全面的API。 50 | 51 |
52 |
53 | 54 |
55 |
56 | 57 | 并提供了[AgentFabric](https://github.com/modelscope/modelscope-agent/tree/master/apps/agentfabric)应用,可快速创建一个基本的Agent,并已部署上线在[创空间](https://modelscope.cn/studios/modelscope/AgentFabric/summary)。 58 | 59 |
60 |
61 | 62 |
63 |
64 |
AgentFabric最新UI 65 |

66 | 67 | 相关论文详见:[ModelScope-Agent: Building Your Customizable Agent System with Open-source Large Language Models](https://arxiv.org/abs/2309.00986) 68 | 69 | ### [Langchain](https://github.com/langchain-ai/langchain) 70 | 71 | [Langchain](https://github.com/langchain-ai/langchain) 72 | 由 Harrison Chase 2022 年 10 月开源,并迅速转变为一家初创公司,是一个轻量级框架,专门用于构建基于LLM的应用,不仅限于 Agent 应用,其中关于Agent的开发方法可查看其文档中的[Agents | 🦜️🔗 Langchain](https://python.langchain.com/docs/modules/agents/)。 73 | 74 |
75 |
76 | 77 |
78 |
79 | 80 | 但Agent不是其主要框架,而是其中一个功能,其常见的应用方案是外接知识库,通过向量化的方式给LLM外接一个大脑。​ 81 | 82 | ### [MetaGPT](https://github.com/geekan/MetaGPT) 83 | 84 | [MetaGPT](https://github.com/geekan/MetaGPT)由DeepWisdom于2023年8月1号发布,是一个多智能体协作的框架,旨在解决基于大型语言模型(LLMs)的多智能体协作中的复杂问题,核心理念是使 GPTs 组成团队,将协作的SOP具象化,通过SOP(Team)协作处理更复杂的任务。 85 | 86 |
87 |
88 | 89 |
90 |
91 |
案例:软件公司 92 |

93 | 94 | 95 | ### Agently 96 | 待完善 97 | 98 | ### AutoGPT 99 | 待完善 100 | 101 | ### BabyGPT 102 | 待完善 103 | 104 | ## 通用创作思路参考 105 | 笔者根据自己的经验,参考软件设计流程大致整理了以下通用的 Agent 应用设计SOP: 106 | 107 |
108 |
109 | 110 |
111 |
112 |
Agent应用设计SOP 113 |

114 | 115 | 1. 首先需要进行 Agent 开发框架 和 大语言模型的选型; 116 | 117 | 在此次比赛中,选型非常明确,即 [ModelScope-Agent](https://github.com/modelscope/modelscope-agent/blob/master/README_CN.md) + qwen大模型 + 各种已有的tools和其他你比较熟悉且感兴趣的API. 118 | 119 | 2. 然后需要搭建开发环境,熟悉开发流程; 120 | 121 | ModelScope-Agent 框架使用时,最核心的内容就是LLM, tool_list, PromptGenerator, OutputParser 这几个组件: 122 | 123 |
124 |
125 | 126 |
127 |
128 |
ModelScope-Agent 核心组件 129 |

130 | 131 | 而这几个组件的参数如何进行更改,则需要进一步对代码进行理解和梳理,此处不做更多展开,有需要可自行阅读代码,并在交流群进行分享和交流. 132 | 133 | 除了熟悉Agent框架的实现外,还需要熟悉tools的调用方式. 134 | 135 | 若要增加额外的tools能力,则需要进行代码级的开发,至少需要知道选定的Agent框架能力边界、如何修改其Prompt、如何保存和替换KEY、记忆存储方案、如何使Agent能调用相关工具、如何开发和部署应用上线. 136 | 137 | 这些能力均需要一点点进行学习和验证,需要一定的时间,来完成这个学习过程. 138 | 139 | 3. **寻找灵感,确定创作方向** 140 | 141 | 确定应用的功能方向是整个比赛中最重要的一环,创意和想法是一切的起点和动力源. 142 | 143 | 在这里,我推荐三种思考方向: 144 | 145 | 复现现有软件/游戏功能? 146 | 147 | 解决日常生活痛点? 148 | 149 | 从自己的创意进行延伸和细化? 150 | ... 151 | 152 | 如果在遇到这些问题时,仍然没有思路,则可以通过现有的好用的 GPTs 的内容,以及尝试现有市场上的可用Agent的功能并进行拆解分析,找到更多灵感并进行尝试. 153 | 154 | 又或者可以直接与大语言模型进行交互,向它要更多的灵感和思路,以及问题解决方案. 155 | 156 | 4. 确定好具体的方向后,细化具体功能、设计UI,设计大致开发路径,并享受漫长的开发和效果验证调试之旅. 157 | 158 | 虽然开发过程也许很累,甚至某些部分有些枯燥, 159 | 160 | 但选择让自己开心,会帮助到自己的 Agent 创作方向. 161 | 162 | 一边享受知识进入大脑的快感, 一边愉快地将好的创意落地, 让自己的思考变成改善生活的新工具. 163 | 164 | 用好Agent开发工具, 放大更多创意的力量和个人能力,让自己在未来的AI时代更加游刃有余,如鱼得水~ 165 | 166 | 那就再好不过啦! 167 | 168 | 希望大家都能愉快地创作Agent,并享受 Agent 创作的乐趣. 169 | 170 | # 参考资料 171 | 1. [万字长文!何谓Agent,为何Agent?](https://mp.weixin.qq.com/s/jFf0fmZLehLDaNNzgqeAIQ) 172 | 2. [魔搭社区推出ModelScope-Agent开发框架,打造属于你的智能体](https://mp.weixin.qq.com/s/L3GiV2QHeybhVZSg_g_JRw) 173 | 3. [生成式 AI 的评估和监视指标 - Azure AI Studio](https://learn.microsoft.com/zh-cn/azure/ai-studio/concepts/evaluation-metrics-built-in) 174 | 4. [LangChain Agent 原理解析](https://zhuanlan.zhihu.com/p/655141968) 175 | 5. [GPT Engineer 实践与源码解析](https://zhuanlan.zhihu.com/p/667865664) 176 | 6. [我为什么放弃了 LangChain?](https://zhuanlan.zhihu.com/p/645358531) 177 | 7. [LangChain:介绍与入门](https://zhuanlan.zhihu.com/p/639458788) 178 | 8. [LangChain 中文文档 v0.0.291 | 🦜️🔗 Langchain](https://python.langchain.com.cn/docs/) 179 | 9. [一文详解最热的 LLM 应用框架 LangChain](https://zhuanlan.zhihu.com/p/651151321) -------------------------------------------------------------------------------- /docs/第三章:Agent应用展望/3.2 Agent应用展望.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/agent-tutorial/1efa90d39740846b0e5e038aa01438993e5dfe60/docs/第三章:Agent应用展望/3.2 Agent应用展望.md -------------------------------------------------------------------------------- /docs/第三章:Agent应用展望/demo-code/.gitignore: -------------------------------------------------------------------------------- 1 | key.txt -------------------------------------------------------------------------------- /docs/第三章:Agent应用展望/demo-code/dashscope-demo.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 12, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import os\n", 10 | "\n", 11 | "with open('key.txt', 'r') as file:\n", 12 | " DASHSCOPE_API_KEY = file.read()\n", 13 | " os.environ['DASHSCOPE_API_KEY'] = DASHSCOPE_API_KEY" 14 | ] 15 | }, 16 | { 17 | "cell_type": "code", 18 | "execution_count": 4, 19 | "metadata": {}, 20 | "outputs": [ 21 | { 22 | "name": "stdout", 23 | "output_type": "stream", 24 | "text": [ 25 | "Defaulting to user installation because normal site-packages is not writeable\n", 26 | "Collecting dashscope\n", 27 | "\u001b[33m WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ConnectTimeoutError(, 'Connection to files.pythonhosted.org timed out. (connect timeout=15)')': /packages/c4/b2/df8ec42b16471af34e2d17de723d028e77a702f524c44afa83a4d08c41b2/dashscope-1.13.5-py3-none-any.whl\u001b[0m\u001b[33m\n", 28 | "\u001b[0m\u001b[33m WARNING: Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ReadTimeoutError(\"HTTPSConnectionPool(host='files.pythonhosted.org', port=443): Read timed out. (read timeout=15)\")': /packages/c4/b2/df8ec42b16471af34e2d17de723d028e77a702f524c44afa83a4d08c41b2/dashscope-1.13.5-py3-none-any.whl\u001b[0m\u001b[33m\n", 29 | "\u001b[0m Downloading dashscope-1.13.5-py3-none-any.whl (78 kB)\n", 30 | "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m78.7/78.7 kB\u001b[0m \u001b[31m168.5 kB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0ma \u001b[36m0:00:01\u001b[0m\n", 31 | "\u001b[?25hRequirement already satisfied: aiohttp in /Users/mac/Library/Python/3.9/lib/python/site-packages (from dashscope) (3.8.4)\n", 32 | "Requirement already satisfied: requests in /Users/mac/Library/Python/3.9/lib/python/site-packages (from dashscope) (2.31.0)\n", 33 | "Requirement already satisfied: attrs>=17.3.0 in /Users/mac/Library/Python/3.9/lib/python/site-packages (from aiohttp->dashscope) (23.1.0)\n", 34 | "Requirement already satisfied: charset-normalizer<4.0,>=2.0 in /Users/mac/Library/Python/3.9/lib/python/site-packages (from aiohttp->dashscope) (3.1.0)\n", 35 | "Requirement already satisfied: multidict<7.0,>=4.5 in /Users/mac/Library/Python/3.9/lib/python/site-packages (from aiohttp->dashscope) (6.0.4)\n", 36 | "Requirement already satisfied: async-timeout<5.0,>=4.0.0a3 in /Users/mac/Library/Python/3.9/lib/python/site-packages (from aiohttp->dashscope) (4.0.2)\n", 37 | "Requirement already satisfied: yarl<2.0,>=1.0 in /Users/mac/Library/Python/3.9/lib/python/site-packages (from aiohttp->dashscope) (1.9.2)\n", 38 | "Requirement already satisfied: frozenlist>=1.1.1 in /Users/mac/Library/Python/3.9/lib/python/site-packages (from aiohttp->dashscope) (1.3.3)\n", 39 | "Requirement already satisfied: aiosignal>=1.1.2 in /Users/mac/Library/Python/3.9/lib/python/site-packages (from aiohttp->dashscope) (1.3.1)\n", 40 | "Requirement already satisfied: idna<4,>=2.5 in /Users/mac/Library/Python/3.9/lib/python/site-packages (from requests->dashscope) (3.4)\n", 41 | "Requirement already satisfied: urllib3<3,>=1.21.1 in /Users/mac/Library/Python/3.9/lib/python/site-packages (from requests->dashscope) (1.26.6)\n", 42 | "Requirement already satisfied: certifi>=2017.4.17 in /Users/mac/Library/Python/3.9/lib/python/site-packages (from requests->dashscope) (2023.5.7)\n", 43 | "Installing collected packages: dashscope\n", 44 | "Successfully installed dashscope-1.13.5\n", 45 | "\n", 46 | "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.1.2\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m23.3.1\u001b[0m\n", 47 | "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49m/Library/Developer/CommandLineTools/usr/bin/python3 -m pip install --upgrade pip\u001b[0m\n", 48 | "Note: you may need to restart the kernel to use updated packages.\n" 49 | ] 50 | } 51 | ], 52 | "source": [ 53 | "pip install dashscope" 54 | ] 55 | }, 56 | { 57 | "cell_type": "code", 58 | "execution_count": 13, 59 | "metadata": {}, 60 | "outputs": [ 61 | { 62 | "name": "stdout", 63 | "output_type": "stream", 64 | "text": [ 65 | "Speech synthesizer is opened.\n" 66 | ] 67 | }, 68 | { 69 | "ename": "RuntimeError", 70 | "evalue": "Cannot run the event loop while another loop is running", 71 | "output_type": "error", 72 | "traceback": [ 73 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 74 | "\u001b[0;31mRuntimeError\u001b[0m Traceback (most recent call last)", 75 | "\u001b[1;32m/Users/mac/Documents/Working/1_Me/2_Datawhale/教程编写/动手学Agent开发/agent-tutorial/notebook/第三章:Agent应用展望/demo-code/dashscope-demo.ipynb 单元格 3\u001b[0m line \u001b[0;36m3\n\u001b[1;32m 28\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39m'\u001b[39m\u001b[39mtimestamp result:\u001b[39m\u001b[39m'\u001b[39m, \u001b[39mstr\u001b[39m(result\u001b[39m.\u001b[39mget_timestamp()))\n\u001b[1;32m 30\u001b[0m callback \u001b[39m=\u001b[39m Callback()\n\u001b[0;32m---> 31\u001b[0m SpeechSynthesizer\u001b[39m.\u001b[39;49mcall(model\u001b[39m=\u001b[39;49m\u001b[39m'\u001b[39;49m\u001b[39msambert-zhichu-v1\u001b[39;49m\u001b[39m'\u001b[39;49m,\n\u001b[1;32m 32\u001b[0m text\u001b[39m=\u001b[39;49m\u001b[39m'\u001b[39;49m\u001b[39m今天天气怎么样\u001b[39;49m\u001b[39m'\u001b[39;49m,\n\u001b[1;32m 33\u001b[0m sample_rate\u001b[39m=\u001b[39;49m\u001b[39m48000\u001b[39;49m,\n\u001b[1;32m 34\u001b[0m callback\u001b[39m=\u001b[39;49mcallback,\n\u001b[1;32m 35\u001b[0m word_timestamp_enabled\u001b[39m=\u001b[39;49m\u001b[39mTrue\u001b[39;49;00m,\n\u001b[1;32m 36\u001b[0m phoneme_timestamp_enabled\u001b[39m=\u001b[39;49m\u001b[39mTrue\u001b[39;49;00m)\n", 76 | "File \u001b[0;32m~/Library/Python/3.9/lib/python/site-packages/dashscope/audio/tts/speech_synthesizer.py:143\u001b[0m, in \u001b[0;36mSpeechSynthesizer.call\u001b[0;34m(cls, model, text, callback, **kwargs)\u001b[0m\n\u001b[1;32m 140\u001b[0m \u001b[39mif\u001b[39;00m _callback \u001b[39mis\u001b[39;00m \u001b[39mnot\u001b[39;00m \u001b[39mNone\u001b[39;00m:\n\u001b[1;32m 141\u001b[0m _callback\u001b[39m.\u001b[39mon_open()\n\u001b[0;32m--> 143\u001b[0m \u001b[39mfor\u001b[39;00m part \u001b[39min\u001b[39;00m response:\n\u001b[1;32m 144\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39misinstance\u001b[39m(part\u001b[39m.\u001b[39moutput, \u001b[39mbytes\u001b[39m):\n\u001b[1;32m 145\u001b[0m \u001b[39mif\u001b[39;00m _callback \u001b[39mis\u001b[39;00m \u001b[39mnot\u001b[39;00m \u001b[39mNone\u001b[39;00m:\n", 77 | "File \u001b[0;32m~/Library/Python/3.9/lib/python/site-packages/dashscope/api_entities/websocket_request.py:71\u001b[0m, in \u001b[0;36m\u001b[0;34m(.0)\u001b[0m\n\u001b[1;32m 69\u001b[0m response \u001b[39m=\u001b[39m async_to_sync(\u001b[39mself\u001b[39m\u001b[39m.\u001b[39mconnection_handler())\n\u001b[1;32m 70\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mstream:\n\u001b[0;32m---> 71\u001b[0m \u001b[39mreturn\u001b[39;00m (item \u001b[39mfor\u001b[39;00m item \u001b[39min\u001b[39;00m response)\n\u001b[1;32m 72\u001b[0m \u001b[39melse\u001b[39;00m:\n\u001b[1;32m 73\u001b[0m output \u001b[39m=\u001b[39m \u001b[39mnext\u001b[39m(response)\n", 78 | "File \u001b[0;32m~/Library/Python/3.9/lib/python/site-packages/dashscope/common/utils.py:95\u001b[0m, in \u001b[0;36masync_to_sync\u001b[0;34m(async_generator)\u001b[0m\n\u001b[1;32m 93\u001b[0m loop \u001b[39m=\u001b[39m asyncio\u001b[39m.\u001b[39mget_event_loop_policy()\u001b[39m.\u001b[39mnew_event_loop()\n\u001b[1;32m 94\u001b[0m asyncio\u001b[39m.\u001b[39mset_event_loop(loop)\n\u001b[0;32m---> 95\u001b[0m \u001b[39mfor\u001b[39;00m message \u001b[39min\u001b[39;00m iter_over_async(async_generator, loop):\n\u001b[1;32m 96\u001b[0m \u001b[39myield\u001b[39;00m message\n", 79 | "File \u001b[0;32m~/Library/Python/3.9/lib/python/site-packages/dashscope/common/utils.py:85\u001b[0m, in \u001b[0;36miter_over_async\u001b[0;34m(ait, loop)\u001b[0m\n\u001b[1;32m 82\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mTrue\u001b[39;00m, \u001b[39mNone\u001b[39;00m\n\u001b[1;32m 84\u001b[0m \u001b[39mwhile\u001b[39;00m \u001b[39mTrue\u001b[39;00m:\n\u001b[0;32m---> 85\u001b[0m done, obj \u001b[39m=\u001b[39m loop\u001b[39m.\u001b[39;49mrun_until_complete(get_next())\n\u001b[1;32m 86\u001b[0m \u001b[39mif\u001b[39;00m done:\n\u001b[1;32m 87\u001b[0m loop\u001b[39m.\u001b[39mclose()\n", 80 | "File \u001b[0;32m/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/asyncio/base_events.py:618\u001b[0m, in \u001b[0;36mBaseEventLoop.run_until_complete\u001b[0;34m(self, future)\u001b[0m\n\u001b[1;32m 607\u001b[0m \u001b[39m\u001b[39m\u001b[39m\"\"\"Run until the Future is done.\u001b[39;00m\n\u001b[1;32m 608\u001b[0m \n\u001b[1;32m 609\u001b[0m \u001b[39mIf the argument is a coroutine, it is wrapped in a Task.\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 615\u001b[0m \u001b[39mReturn the Future's result, or raise its exception.\u001b[39;00m\n\u001b[1;32m 616\u001b[0m \u001b[39m\"\"\"\u001b[39;00m\n\u001b[1;32m 617\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_check_closed()\n\u001b[0;32m--> 618\u001b[0m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49m_check_running()\n\u001b[1;32m 620\u001b[0m new_task \u001b[39m=\u001b[39m \u001b[39mnot\u001b[39;00m futures\u001b[39m.\u001b[39misfuture(future)\n\u001b[1;32m 621\u001b[0m future \u001b[39m=\u001b[39m tasks\u001b[39m.\u001b[39mensure_future(future, loop\u001b[39m=\u001b[39m\u001b[39mself\u001b[39m)\n", 81 | "File \u001b[0;32m/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/asyncio/base_events.py:580\u001b[0m, in \u001b[0;36mBaseEventLoop._check_running\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 578\u001b[0m \u001b[39mraise\u001b[39;00m \u001b[39mRuntimeError\u001b[39;00m(\u001b[39m'\u001b[39m\u001b[39mThis event loop is already running\u001b[39m\u001b[39m'\u001b[39m)\n\u001b[1;32m 579\u001b[0m \u001b[39mif\u001b[39;00m events\u001b[39m.\u001b[39m_get_running_loop() \u001b[39mis\u001b[39;00m \u001b[39mnot\u001b[39;00m \u001b[39mNone\u001b[39;00m:\n\u001b[0;32m--> 580\u001b[0m \u001b[39mraise\u001b[39;00m \u001b[39mRuntimeError\u001b[39;00m(\n\u001b[1;32m 581\u001b[0m \u001b[39m'\u001b[39m\u001b[39mCannot run the event loop while another loop is running\u001b[39m\u001b[39m'\u001b[39m)\n", 82 | "\u001b[0;31mRuntimeError\u001b[0m: Cannot run the event loop while another loop is running" 83 | ] 84 | } 85 | ], 86 | "source": [ 87 | "# coding=utf-8\n", 88 | "\n", 89 | "import dashscope\n", 90 | "import sys\n", 91 | "from dashscope.api_entities.dashscope_response import SpeechSynthesisResponse\n", 92 | "from dashscope.audio.tts import ResultCallback, SpeechSynthesizer, SpeechSynthesisResult\n", 93 | "\n", 94 | "dashscope.api_key='DASHSCOPE_API_KEY'\n", 95 | "\n", 96 | "class Callback(ResultCallback):\n", 97 | " def on_open(self):\n", 98 | " print('Speech synthesizer is opened.')\n", 99 | "\n", 100 | " def on_complete(self):\n", 101 | " print('Speech synthesizer is completed.')\n", 102 | "\n", 103 | " def on_error(self, response: SpeechSynthesisResponse):\n", 104 | " print('Speech synthesizer failed, response is %s' % (str(response)))\n", 105 | "\n", 106 | " def on_close(self):\n", 107 | " print('Speech synthesizer is closed.')\n", 108 | "\n", 109 | " def on_event(self, result: SpeechSynthesisResult):\n", 110 | " if result.get_audio_frame() is not None:\n", 111 | " asyncio.run_in_executor(None, print, 'audio result length:', sys.getsizeof(result.get_audio_frame()))\n", 112 | "\n", 113 | " if result.get_timestamp() is not None:\n", 114 | " asyncio.run_in_executor(None, print, 'timestamp result:', str(result.get_timestamp()))\n", 115 | "\n", 116 | "callback = Callback()\n", 117 | "SpeechSynthesizer.call(model='sambert-zhichu-v1',\n", 118 | " text='今天天气怎么样',\n", 119 | " sample_rate=48000,\n", 120 | " callback=callback,\n", 121 | " word_timestamp_enabled=True,\n", 122 | " phoneme_timestamp_enabled=True)" 123 | ] 124 | } 125 | ], 126 | "metadata": { 127 | "kernelspec": { 128 | "display_name": "Python 3", 129 | "language": "python", 130 | "name": "python3" 131 | }, 132 | "language_info": { 133 | "codemirror_mode": { 134 | "name": "ipython", 135 | "version": 3 136 | }, 137 | "file_extension": ".py", 138 | "mimetype": "text/x-python", 139 | "name": "python", 140 | "nbconvert_exporter": "python", 141 | "pygments_lexer": "ipython3", 142 | "version": "3.9.6" 143 | } 144 | }, 145 | "nbformat": 4, 146 | "nbformat_minor": 2 147 | } 148 | -------------------------------------------------------------------------------- /docs/第三章:Agent应用展望/imgs/3-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/agent-tutorial/1efa90d39740846b0e5e038aa01438993e5dfe60/docs/第三章:Agent应用展望/imgs/3-1.png -------------------------------------------------------------------------------- /docs/第三章:Agent应用展望/imgs/3-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/agent-tutorial/1efa90d39740846b0e5e038aa01438993e5dfe60/docs/第三章:Agent应用展望/imgs/3-3.png -------------------------------------------------------------------------------- /docs/第三章:Agent应用展望/imgs/3-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/agent-tutorial/1efa90d39740846b0e5e038aa01438993e5dfe60/docs/第三章:Agent应用展望/imgs/3-4.png -------------------------------------------------------------------------------- /docs/第三章:Agent应用展望/imgs/3-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/agent-tutorial/1efa90d39740846b0e5e038aa01438993e5dfe60/docs/第三章:Agent应用展望/imgs/3-5.png -------------------------------------------------------------------------------- /docs/第三章:Agent应用展望/imgs/3-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/agent-tutorial/1efa90d39740846b0e5e038aa01438993e5dfe60/docs/第三章:Agent应用展望/imgs/3-6.png -------------------------------------------------------------------------------- /docs/第三章:Agent应用展望/imgs/3-7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/agent-tutorial/1efa90d39740846b0e5e038aa01438993e5dfe60/docs/第三章:Agent应用展望/imgs/3-7.png -------------------------------------------------------------------------------- /docs/第三章:Agent应用展望/imgs/3-8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/agent-tutorial/1efa90d39740846b0e5e038aa01438993e5dfe60/docs/第三章:Agent应用展望/imgs/3-8.png -------------------------------------------------------------------------------- /docs/第三章:Agent应用展望/imgs/3-9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/agent-tutorial/1efa90d39740846b0e5e038aa01438993e5dfe60/docs/第三章:Agent应用展望/imgs/3-9.png -------------------------------------------------------------------------------- /docs/第二章:Agent实践/2.1 高德开放API实践.md: -------------------------------------------------------------------------------- 1 | 为了帮助大家更好的构建Agent,我们首先针对高德开放API做一些专项讲解,以帮助大家理解这些API所提供的能力。同时也希望大家自己可以探索更多的开发API积极融入到自己的agnet开发中 2 | 3 | ## 高德API介绍 4 | 5 | [高德地图开放API](https://lbs.amap.com/api/)是高德地图提供的一套开放接口,可以实现地图展示、地理编码、逆地理编码、路径规划、地点搜索等功能。开发者可以通过调用这些API来实现自己的地图应用。 6 | 7 | ![img.png](imgs/img.png) 8 | 9 | [高德Web服务API](https://lbs.amap.com/api/webservice/summary)开放了大量能力,并且提供给个人开发者较多的调用次数,完全能够满足个人开发者日常开发需求。 10 | 11 | ![img_1.png](imgs/img_1.png) 12 | ![img_2.png](imgs/img_2.png) 13 | 14 | 15 | ## 创建高德API的AK 16 | 17 | ### 注册登陆 18 | 点击注册按钮,完成注册后即可登陆 19 | 20 | ![img_3.png](imgs/img_3.png) 21 | ![img_5.png](imgs/img_5.png) 22 | 23 | 24 | ![img_4.png](imgs/img_4.png) 25 | 26 | 登陆后进入控制台 27 | ![img_6.png](imgs/img_6.png) 28 | 29 | 30 | ### 生成AK 31 | 进入应用管理,创建应用并生成AK,这个AK是我们调用API能力的密钥。 32 | ![img_7.png](imgs/img_7.png) 33 | 34 | 35 | ## 高德API的调用 36 | 37 | ### 地理/逆地理编码 38 | 39 | [地理编码/逆地理编码API](https://lbs.amap.com/api/webservice/guide/api/georegeo) 是通过 HTTP/HTTPS 协议访问远程服务的接口,提供结构化地址与经纬度之间的相互转化的能力。 40 | 41 | 结构化地址的定义: 首先,地址肯定是一串字符,内含国家、省份、城市、区县、城镇、乡村、街道、门牌号码、屋邨、大厦等建筑物名称。按照由大区域名称到小区域名称组合在一起的字符。一个有效的地址应该是独一无二的。注意:针对大陆、港、澳地区的地理编码转换时可以将国家信息选择性的忽略,但省、市、城镇等级别的地址构成是不能忽略的。暂时不支持返回台湾省的详细地址信息。 42 | 43 | 调用示例:https://restapi.amap.com/v3/geocode/geo?key=AK=%E6%B5%99%E6%B1%9F%E7%9C%81%E6%9D%AD%E5%B7%9E%E5%B8%82%E6%B5%B7%E5%BA%95%E6%8D%9E%E7%81%AB%E9%94%85(%E5%A5%A5%E8%8E%B1%E9%87%91%E8%A1%97%E5%BA%97) 44 | 45 | 调用结果: 46 | 47 | ![img_9.png](imgs/img_9.png) 48 | 49 | 50 | 51 | 52 | 53 | ### POI搜索接口 54 | 55 | [地点搜索服务2.0](https://lbs.amap.com/api/webservice/guide/api/newpoisearch)是一类Web API接口服务;服务提供多种场景的地点搜索能力,包括关键字搜索、周边搜索、多边形区域搜索、ID搜索。 56 | 57 | - **关键字搜索**:开发者可通过文本关键字搜索地点信息,文本可以是结构化地址,例如:北京市朝阳区望京阜荣街10号;也可以是POI名称,例如:首开广场; 58 | 59 | - **周边搜索**: 开发者可设置圆心和半径,搜索圆形区域内的地点信息; 60 | 61 | - **多边形区域搜索**:开发者可设置首尾连接的几何点组成多边形区域,搜索坐标对应多边形内的地点信息; 62 | 63 | - **ID搜索**: 开发者可通过已知的地点ID(POI ID)搜索对应地点信息,建议结合输入提示接口使用。 64 | 65 | 调用示例:https://restapi.amap.com/v5/place/text?key=AK&keywords=%E6%B5%B7%E5%BA%95%E6%8D%9E®ion=%E6%9D%AD%E5%B7%9E 66 | 67 | 调用结果: 68 | ![img_8.png](imgs/img_8.png) 69 | 70 | 71 | ### 路径规划 72 | [路线规划接口2.0](https://lbs.amap.com/api/webservice/guide/api/newroute)是一类Web API接口服务,以HTTP/HTTPS形式提供了多种路线规划服务。支持驾车、公交、步行、骑行、电动车路线规划。 73 | 74 | - **驾车路线规划**:开发者可根据起终点坐标检索符合条件的驾车路线规划方案,支持一次请求返回多条路线结果、支持传入多个途经点、支持传入车牌规避限行、支持根据不同业务场景设置不同的算路策略等。 75 | 76 | - **步行路线规划**: 开发者可根据起终点坐标检索符合条件的步行路线规划方案。 77 | 78 | - **公交路线规划**: 开发者可根据起终点坐标检索符合条件的公共交通路线规划方案,支持结合业务场景设置不同的公交换乘策略。 79 | 80 | - **骑行路线规划**: 开发者可根据起终点坐标检索符合条件的骑行路线规划方案。 81 | 82 | - **电动车路线规划**: 开发者可根据起终点坐标检索符合条件的电动车路线规划方案,与骑行略有不同的是会考虑限行等条件。 83 | 84 | 85 | 调用示例:从当前位置(120.061159,30.255079 西溪湿地附近)驾驶导航前往海底捞火锅(奥莱金街店) 86 | https://restapi.amap.com/v5/direction/driving?key=AK&origin=120.061159,30.255079&destination=120.070370,30.145497&destination_id=B0I3VUFPND&show_fields=cost 87 | 88 | 调用结果: 89 | ![img_10.png](imgs/img_10.png) 90 | 91 | 92 | -------------------------------------------------------------------------------- /docs/第二章:Agent实践/2.2 日程规划小助手.md: -------------------------------------------------------------------------------- 1 | # 设计背景 2 | 3 | 基于上述对Agent的初步了解,本部分使用一个具体的例子,结合model scope的agent能力进行实操演示。 4 | 5 | 本部分将正式开始介绍日程规划小助手的设计,为了完成一个优质的Agent,我们一定要思考清楚Agent的用户及用户使用场景。 6 | 1. **场景**:支持用户输入日程(目的地、赴约时间等),根据日程进一步规划出行方式和时间。 7 | 2. **关键技术**:本部分将大量使用高德地图的开放API,如[搜索POI](https://lbs.amap.com/api/webservice/guide/api/newpoisearch)、[逆地理编码](https://lbs.amap.com/api/webservice/guide/api/georegeo)、[路程规划](https://lbs.amap.com/api/webservice/guide/api/newroute)等,以此来介绍function call和tool的使用。 8 | 9 | 延展设计:基于日程规划小助手,可以进行如下方向延展: 10 | 1. **绑定日历**:可以接入外部日历(如飞书日历、google日历等),将规划后的日程同步到日历中。日历不仅有日程信息,还会将出行所消耗时间考虑在内。 11 | 2. **智能建议**:基于用户输入地区、时间、赴约对象等,为用户提供一系列建议。如是否下雨、是否需要准备礼物等。 12 | 3. **个人助手**:更进一步可以思考打造用户的个人助手,日历可以看作个人助手的长期记忆。设计更多复杂的场景实现,如用户添加体检日程,可以进一步追踪体检报告,根据体检报告进行饮食、运动建议规划。 13 | 14 | 15 | # 技术背景 16 | 由于本部分需要详细使用大量高德地图API,不熟悉的同学清先参考高德开放API实践 17 | 18 | 针对model scope提供的系列开发教程参考 19 | - [0代码创建、发布并分享一个专属Agent](https://modelscope.cn/headlines/article/266) 20 | - [低代码调用API创建更加酷炫的Agent](https://modelscope.cn/headlines/article/267) 21 | - [将API注册为tool,成为smart API](https://modelscope.cn/headlines/article/268) 22 | - [Agent自带的Code Interpreter如何使用](https://modelscope.cn/headlines/article/272) 23 | - [如何在本地/云端创建并发布更定制化的Agent](https://modelscope.cn/headlines/article/278) 24 | 25 | 更多model socpe文档见 26 | - [魔搭文档中心](https://modelscope.cn/docs/%E9%A6%96%E9%A1%B5) 27 | 28 | 29 | # 基础版 30 | ## 实现逻辑 31 | 32 | 基础版可以通过0代码方案进行构建,参考[0代码创建、发布并分享一个专属Agent](https://modelscope.cn/headlines/article/266)能够快速构建出一个小助手。 33 | 34 | ![img.png](imgs/img_11.png) 35 | 36 | 构建完成后可以发布上线,帮助大家熟悉发布流程环境, 37 | 参考:https://www.modelscope.cn/studios/taiji007/scheduler_mvp/summary 38 | 39 | 40 | 41 | # 进阶版 42 | ## 实现逻辑 43 | 上述方案仅仅是帮助我们熟悉魔搭的构建环境,同时针对地点推荐,Agent使用的是内部知识库,这部分知识库存在消息滞后的问题,因此我们考虑使用魔搭tools功能来接入高德API。 44 | 45 | 因此,因此进阶版将将按照如下步骤进行进行改造,中间回针对modelscope_agent部分代码细节深入描述 46 | 1. modelscope_agent构建自定义tools,实现poi的查找功能 47 | 2. 进行modelscope_agent其他配置项改造 48 | 3. 创建创空间,并进行相关配置并发布。 49 | 50 | ## 实现路径 51 | 52 | ### 自定义tools 53 | 54 | 首先需要从 [modelscope_agent的仓库](https://github.com/modelscope/modelscope-agent)中拉取代码 55 | 56 | 完成代码拉取后,我们需要在 `modelscope_agent/tools` 下新增poi所搜API对应的tool。在写的过程中可以参考`amap_weather.py`(借助高德开放api实现地区天气情况查找)的写法。 57 | 58 | 新增tool如下,其中`amap_poi_query`是新增tool的名字,该名称还会被用于其他的配置项中。一些关键点如下 59 | - `__init__`中`cfg`是在一个大的`cfg`找到对应name`amap_poi_query`的配置信息。后续可以生成对应的`cfg`进行单测。 60 | - `__init__`中`url`即为API调用链接,这里需要吧必传参数占位符明确下来。 61 | - `__init__`中`token`即为API鉴权AK,从cfg中获取的,因此在我们上线后的环境变量中要新增AMAP_TOKEN 62 | - `__call__`是实现API调用和返回的关键,可以通过该函数测试我们对返回的解析是否正确。 63 | 64 | ```python 65 | import os 66 | 67 | import pandas as pd 68 | import requests 69 | from modelscope_agent.tools.tool import Tool, ToolSchema 70 | from pydantic import ValidationError 71 | 72 | 73 | class AMAPPOIQuery(Tool): 74 | description = '获取高德poi信息' 75 | name = 'amap_poi_query' 76 | parameters: list = [ 77 | { 78 | 'name': 'keywords', 79 | 'description': 'Text information for the location to be retrieved', 80 | 'required': True 81 | } 82 | ] 83 | 84 | def __init__(self, cfg={}): 85 | self.cfg = cfg.get(self.name, {}) 86 | 87 | # remote call 88 | self.url = 'https://restapi.amap.com/v5/place/text?key={key}&keywords=%{keywords}' 89 | self.token = self.cfg.get('token', os.environ.get('AMAP_TOKEN', '')) 90 | 91 | assert self.token != '', 'weather api token must be acquired through ' \ 92 | 'https://lbs.amap.com/api/webservice/guide/create-project/get-key and set by AMAP_TOKEN' 93 | 94 | try: 95 | all_param = { 96 | 'name': self.name, 97 | 'description': self.description, 98 | 'parameters': self.parameters 99 | } 100 | self.tool_schema = ToolSchema(**all_param) 101 | except ValidationError: 102 | raise ValueError(f'Error when parsing parameters of {self.name}') 103 | 104 | self._str = self.tool_schema.model_dump_json() 105 | self._function = self.parse_pydantic_model_to_openai_function( 106 | all_param) 107 | 108 | 109 | def __call__(self, *args, **kwargs): 110 | result = [] 111 | keywords = kwargs['keywords'] 112 | response = requests.get( 113 | self.url.format(keywords=keywords, key=self.token)) 114 | data = response.json() 115 | if data['status'] == '0': 116 | raise RuntimeError(data) 117 | else: 118 | return {'result': data.get('pois')} 119 | 120 | ``` 121 | 122 | 在完成自定义tool的基础上,我们可以进行一下单元测试。 123 | ```python 124 | cfg = { 125 | 'amap_poi_query': { 126 | 'token': AMAP_TOKEN # 填入自己的高德AK 127 | } 128 | } 129 | 130 | test = AMAPPOIQuery(cfg) 131 | data = test.__call__(keywords = '杭州海底捞') 132 | data 133 | ``` 134 | 135 | 136 | ![img_1.png](imgs/img_12.png) 137 | 138 | 139 | ### 进行modelscope_agent其他配置项改造 140 | 为了让注册的tool生效,我们还需要加入到一些配置项中。 141 | 142 | 首先是`modelscope_agent/tools/__init__.py`文件,我们需要在原来的基础上加入`amap_poi_query`tool,如下 143 | ```python 144 | from .amap_weather import AMAPWeather 145 | from .code_interperter import CodeInterpreter 146 | from .code_interpreter_jupyter import CodeInterpreterJupyter 147 | from .hf_tool import HFTool 148 | from .image_chat_tool import ImageChatTool 149 | from .pipeline_tool import ModelscopePipelineTool 150 | from .plugin_tool import LangchainTool 151 | from .text_address_tool import TextAddressTool 152 | from .text_ie_tool import TextInfoExtractTool 153 | from .text_ner_tool import TextNerTool 154 | from .text_to_image_tool import TextToImageTool 155 | from .text_to_speech_tool import TexttoSpeechTool 156 | from .text_to_video_tool import TextToVideoTool 157 | from .tool import Tool 158 | from .translation_en2zh_tool import TranslationEn2ZhTool 159 | from .translation_zh2en_tool import TranslationZh2EnTool 160 | from .wordart_tool import WordArtTexture 161 | from .amap_poi_query import AMAPPOIQuery 162 | 163 | TOOL_INFO_LIST = { 164 | 'modelscope_text-translation-zh2en': 'TranslationZh2EnTool', 165 | 'modelscope_text-translation-en2zh': 'TranslationEn2ZhTool', 166 | 'modelscope_text-ie': 'TextInfoExtractTool', 167 | 'modelscope_text-ner': 'TextNerTool', 168 | 'modelscope_text-address': 'TextAddressTool', 169 | 'image_gen': 'TextToImageTool', 170 | 'modelscope_video-generation': 'TextToVideoTool', 171 | 'modelscope_image-chat': 'ImageChatTool', 172 | 'modelscope_speech-generation': 'TexttoSpeechTool', 173 | 'amap_weather': 'AMAPWeather', 174 | 'code_interpreter': 'CodeInterpreterJupyter', 175 | 'wordart_texture_generation': 'WordArtTexture', 176 | 'amap_poi_query': 'AMAPPOIQuery', 177 | } 178 | ``` 179 | 180 | 其次是修改 `apps/agentfabric/config/tool_config.json`,同样需要在原来的基础上加入`amap_poi_query`tool,如下 181 | ```json 182 | { 183 | "image_gen": { 184 | "name": "Wanx Image Generation", 185 | "is_active": true, 186 | "use": true, 187 | "is_remote_tool": true 188 | }, 189 | "code_interpreter": { 190 | "name": "Code Interpreter", 191 | "is_active": true, 192 | "use": false, 193 | "is_remote_tool": false, 194 | "max_output": 2000 195 | }, 196 | "web_browser": { 197 | "name": "Web Browsing", 198 | "is_active": false, 199 | "use": false 200 | }, 201 | "amap_weather": { 202 | "name": "高德天气", 203 | "is_active": true, 204 | "use": false 205 | }, 206 | "wordart_texture_generation": { 207 | "name": "艺术字纹理生成", 208 | "is_active": true, 209 | "use": false 210 | }, 211 | "amap_poi_query": { 212 | "name": "获取高德poi信息", 213 | "is_active": true, 214 | "use": false 215 | } 216 | } 217 | 218 | ``` 219 | 220 | ### 部署到创空间 221 | 222 | 为了实现将改造后的日程规划助手部署到创空间,可以遵循一下步骤。 223 | 224 | **Step1: 创建创空间** 225 | 226 | 在[创建](https://modelscope.cn/studios/create)页面创建空间,会得到项目地址,如下图。 227 | ![img_2.png](imgs/img_13.png) 228 | 229 | **Step2: 构建新代码仓库** 230 | 231 | 我们可以在本地,或者[魔搭提供的环境](https://modelscope.cn/my/mynotebook/preset)里创建代码。依次执行如下命令,将创建的空间代码拉取到本地,并从`modelscope-agent`中获取必要内容。 232 | 233 | ```shell 234 | git clone http://oauth2:yourOwnTokens@www.modelscope.cn/studios/taiji007/scheduler_demo.git 235 | 236 | git clone https://github.com/modelscope/modelscope-agent.git 237 | 238 | cp -r modelscope-agent/modelscope_agent scheduler_demo/ 239 | cp -r modelscope-agent/apps/agentfabric/* scheduler_demo/ 240 | ``` 241 | 242 | **Step3: 修改代码和依赖** 243 | 244 | 进入`scheduler_demo`路径,依次执行以下步骤,如题部分可以参考上述内容 245 | 246 | 1. 新增`modelscope_agent/tools/amap_weather.py` 247 | 2. 修改`modelscope_agent/tools/__init__.py` 248 | 3. 修改`config/tool_config.json` 249 | 4. 修改`requirements.txt`,将`modelscope-agent/requirements.txt`的依赖复制进来 250 | 251 | **Step4: 修改页面配置图** 252 | 253 | 由于我们线上需要运行的是`appBot.py`代码,仔细观察代码可以看出,决定页面的文件是`config/builder_config.json`,因此这里针对需要使用的tool和目标页面进行初步构建,各位同学可以根据需求自行修改。 254 | 255 | ```json 256 | { 257 | "name": "日程规划小助手", 258 | "avatar": "image.png", 259 | "description": "一个全能的行程规划助手,从交通、住宿到美食,全方位为您打造专属的行程规划。", 260 | "instruction": "1. 理解并回应用户指令\n2. 根据用户指定判断是否需要进行地点查询\n3. 如果用户没有输入城市,默认为杭州\n4. 随时与用户沟通,及时解遇到的问题。", 261 | "prompt_recommend": [ 262 | "有哪些火锅店可以推荐", 263 | "有哪些按摩店可以推荐" 264 | ], 265 | "knowledge": [], 266 | "tools": { 267 | "image_gen": { 268 | "name": "Wanx Image Generation", 269 | "is_active": true, 270 | "use": true 271 | }, 272 | "code_interpreter": { 273 | "name": "Code Interpreter", 274 | "is_active": true, 275 | "use": false 276 | }, 277 | "amap_weather": { 278 | "name": "高德天气", 279 | "is_active": true, 280 | "use": true 281 | }, 282 | "amap_poi_query": { 283 | "name": "获取高德poi", 284 | "is_active": true, 285 | "use": true 286 | }, 287 | "wordart_texture_generation": { 288 | "name": "艺术字纹理生成", 289 | "is_active": true, 290 | "use": true 291 | } 292 | }, 293 | "model": "qwen-max" 294 | } 295 | ``` 296 | 297 | 298 | **Step5: 提交到创空间仓库** 299 | 300 | 运行如下shell脚本,将代码提交到创空间 301 | 302 | ```shell 303 | git add -A 304 | git commit -m "add tools" 305 | 306 | git push 307 | ``` 308 | 309 | **Step6: 修改创空间配置** 310 | 311 | 当代码推送到创空间后,我们可以看到空间下会出现我们提交的文件。 312 | ![img_3.png](imgs/img_14.png) 313 | 314 | 首先需要修改`README.md`,将`entry_file`后面的值改成`appBot.py`。 315 | 316 | 其次是需要在设置中,完善对环境变量的配置,这里的两个AK都必须要填入。 317 | ![img.png](imgs/img_15.png) 318 | 319 | 当完成如上内容后,即可上线创空间。 320 | 321 | 322 | ## 实现效果 323 | 324 | 进一步在创空间中查看实现效果,发现tool已经可以被调用。 325 | 326 | 327 | ![img_1.png](imgs/img_16.png) 328 | -------------------------------------------------------------------------------- /docs/第二章:Agent实践/imgs/img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/agent-tutorial/1efa90d39740846b0e5e038aa01438993e5dfe60/docs/第二章:Agent实践/imgs/img.png -------------------------------------------------------------------------------- /docs/第二章:Agent实践/imgs/img_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/agent-tutorial/1efa90d39740846b0e5e038aa01438993e5dfe60/docs/第二章:Agent实践/imgs/img_1.png -------------------------------------------------------------------------------- /docs/第二章:Agent实践/imgs/img_10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/agent-tutorial/1efa90d39740846b0e5e038aa01438993e5dfe60/docs/第二章:Agent实践/imgs/img_10.png -------------------------------------------------------------------------------- /docs/第二章:Agent实践/imgs/img_11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/agent-tutorial/1efa90d39740846b0e5e038aa01438993e5dfe60/docs/第二章:Agent实践/imgs/img_11.png -------------------------------------------------------------------------------- /docs/第二章:Agent实践/imgs/img_12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/agent-tutorial/1efa90d39740846b0e5e038aa01438993e5dfe60/docs/第二章:Agent实践/imgs/img_12.png -------------------------------------------------------------------------------- /docs/第二章:Agent实践/imgs/img_13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/agent-tutorial/1efa90d39740846b0e5e038aa01438993e5dfe60/docs/第二章:Agent实践/imgs/img_13.png -------------------------------------------------------------------------------- /docs/第二章:Agent实践/imgs/img_14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/agent-tutorial/1efa90d39740846b0e5e038aa01438993e5dfe60/docs/第二章:Agent实践/imgs/img_14.png -------------------------------------------------------------------------------- /docs/第二章:Agent实践/imgs/img_15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/agent-tutorial/1efa90d39740846b0e5e038aa01438993e5dfe60/docs/第二章:Agent实践/imgs/img_15.png -------------------------------------------------------------------------------- /docs/第二章:Agent实践/imgs/img_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/agent-tutorial/1efa90d39740846b0e5e038aa01438993e5dfe60/docs/第二章:Agent实践/imgs/img_16.png -------------------------------------------------------------------------------- /docs/第二章:Agent实践/imgs/img_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/agent-tutorial/1efa90d39740846b0e5e038aa01438993e5dfe60/docs/第二章:Agent实践/imgs/img_2.png -------------------------------------------------------------------------------- /docs/第二章:Agent实践/imgs/img_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/agent-tutorial/1efa90d39740846b0e5e038aa01438993e5dfe60/docs/第二章:Agent实践/imgs/img_3.png -------------------------------------------------------------------------------- /docs/第二章:Agent实践/imgs/img_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/agent-tutorial/1efa90d39740846b0e5e038aa01438993e5dfe60/docs/第二章:Agent实践/imgs/img_4.png -------------------------------------------------------------------------------- /docs/第二章:Agent实践/imgs/img_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/agent-tutorial/1efa90d39740846b0e5e038aa01438993e5dfe60/docs/第二章:Agent实践/imgs/img_5.png -------------------------------------------------------------------------------- /docs/第二章:Agent实践/imgs/img_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/agent-tutorial/1efa90d39740846b0e5e038aa01438993e5dfe60/docs/第二章:Agent实践/imgs/img_6.png -------------------------------------------------------------------------------- /docs/第二章:Agent实践/imgs/img_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/agent-tutorial/1efa90d39740846b0e5e038aa01438993e5dfe60/docs/第二章:Agent实践/imgs/img_7.png -------------------------------------------------------------------------------- /docs/第二章:Agent实践/imgs/img_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/agent-tutorial/1efa90d39740846b0e5e038aa01438993e5dfe60/docs/第二章:Agent实践/imgs/img_8.png -------------------------------------------------------------------------------- /docs/第二章:Agent实践/imgs/img_9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/agent-tutorial/1efa90d39740846b0e5e038aa01438993e5dfe60/docs/第二章:Agent实践/imgs/img_9.png --------------------------------------------------------------------------------