├── 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 |
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 |
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 | 
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 |
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 |
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 |
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 | 
8 |
9 | [高德Web服务API](https://lbs.amap.com/api/webservice/summary)开放了大量能力,并且提供给个人开发者较多的调用次数,完全能够满足个人开发者日常开发需求。
10 |
11 | 
12 | 
13 |
14 |
15 | ## 创建高德API的AK
16 |
17 | ### 注册登陆
18 | 点击注册按钮,完成注册后即可登陆
19 |
20 | 
21 | 
22 |
23 |
24 | 
25 |
26 | 登陆后进入控制台
27 | 
28 |
29 |
30 | ### 生成AK
31 | 进入应用管理,创建应用并生成AK,这个AK是我们调用API能力的密钥。
32 | 
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 | 
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 | 
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 | 
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 | 
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 | 
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 | 
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 | 
313 |
314 | 首先需要修改`README.md`,将`entry_file`后面的值改成`appBot.py`。
315 |
316 | 其次是需要在设置中,完善对环境变量的配置,这里的两个AK都必须要填入。
317 | 
318 |
319 | 当完成如上内容后,即可上线创空间。
320 |
321 |
322 | ## 实现效果
323 |
324 | 进一步在创空间中查看实现效果,发现tool已经可以被调用。
325 |
326 |
327 | 
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
--------------------------------------------------------------------------------