部署DeepSeek模型,进群交流最in玩法!
立即加群
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >从零到手搓一个Agent:AI Agents新手入门精通(二)以智谱为例

从零到手搓一个Agent:AI Agents新手入门精通(二)以智谱为例

作者头像
一个正经的AI
发布2025-01-17 16:21:24
发布2025-01-17 16:21:24
1.1K00
代码可运行
举报
运行总次数:0
代码可运行

今日主题:我们来手把手,嘴对嘴的手搓一个幼儿版的Agent

书接上文,我们梳理一个Agent的定义,也梳理了什么LLM和Agents的区别,看不到的小伙伴可以点击链接传送门:从零到手搓一个Agent:AI Agents新手入门精通(一)。现在我们开始我们第二个学习。

温馨提醒:本系列的初衷是为了从原理去理解Agents,所以我们会用python代码去手搓一个Agent,而不是通过coze,腾讯元器这一些平台去调用工作流。所以可能会有点难度,我们到后面会做一些工作流等一些节点的学习。

现在,我们来手搓一个,智能客服的Agent(只要跟着过程一步一步的操作,一定能手搓一个小Agents出来的,遇到报错的问题,可以评论区留言)

一、准备好API与环境

①我们先安装好环境

代码语言:javascript
代码运行次数:0
运行
复制
pip install openai python-dotenv

②准备好四样东西

国内模型可以是智谱、Yi、千问deepseek等等。KIMI是不行的,因为Kimi家没有嵌入模型。 要想用openai库对接国内的大模型,对于每个厂家,我们都需要准备四样前菜:

  • 第一:一个api_key,这个需要到各家的开放平台上去申请。
  • 第二:一个base_url,这个需要到各家的开放平台上去拷贝。
  • 第三:他们家的对话模型名称。

在这三样东西里面,第一个api_key你要好好保密,不要泄露出去。免得被人盗用,让你的余额用光光。

后面两样东西都是公开的。在这里,我推荐智谱的模型,因为他免费

我们也以智谱为例子

我们来一步步创建一个项目目录,并配置 .env 文件。

1. 创建项目目录

首先,我们需要创建一个新的项目目录。在命令行中执行以下命令:

代码语言:javascript
代码运行次数:0
运行
复制
mkdir my_project
cd my_project

2. 创建 .env 文件

在项目的根目录下创建一个名为 .env 的文件。可以使用以下命令:

代码语言:javascript
代码运行次数:0
运行
复制
echo "ZHIPU_API_KEY=你的api_key" > .env

确保将 你的api_key 替换为您实际的 API 密钥。

3. 项目结构

现在,我们的项目目录结构应该如下:

4. 安装必要的库

在项目目录中,安装 openai 和 python-dotenv 库:

代码语言:javascript
代码运行次数:0
运行
复制
pip install openai python-dotenv

5. 创建 Python 脚本

在项目目录中创建一个 Python 脚本文件,例如 main.py,并添加以下内容:

代码语言:javascript
代码运行次数:0
运行
复制
import os
from dotenv import load_dotenv
from openai import OpenAI
# 加载环境变量
load_dotenv()
# 从环境变量中读取API密钥
api_key = os.getenv('ZHIPU_API_KEY')
# 基础配置
base_url = "https://open.bigmodel.cn/api/paas/v4/"
chat_model = "glm-4-flash"
# 创建客户端
client = OpenAI(
    api_key=api_key,
    base_url=base_url
)
def get_completion(prompt):
    response = client.chat.completions.create(
        model=chat_model,
        messages=[
            {"role": "user", "content": prompt},
        ],
    )
    return response.choices[0].message.content
# 测试调用
response = get_completion("你好,世界!")
print(response) 

6. 运行脚本

在命令行中运行您的 Python 脚本:

代码语言:javascript
代码运行次数:0
运行
复制
python main.py

得到输出

这将使用您在 .env 文件中配置的 API 密钥与智谱AI进行交互。通过这些步骤,您已经成功创建了一个简单的项目,并配置了与智谱AI的连接。

如果到这里没有问题,那可太棒了,来休息一下,奖励一下自己

我们现在来手搓一个智能客服的智能体

1、创建一个智能体客服的类

代码语言:javascript
代码运行次数:0
运行
复制
class SmartAssistant:
    def __init__(self, client):
        self.client = client
        # 定义不同场景的提示词
        self.system_prompt = """你是一个聪明的客服。您将能够根据用户的问题将不同的任务分配给不同的人。您有以下业务线:
        1.用户注册。如果用户想要执行这样的操作,您应该发送一个带有"registered workers"的特殊令牌。并告诉用户您正在调用它。
        2.用户数据查询。如果用户想要执行这样的操作,您应该发送一个带有"query workers"的特殊令牌。并告诉用户您正在调用它。
        3.删除用户数据。如果用户想执行这种类型的操作,您应该发送一个带有"delete workers"的特殊令牌。并告诉用户您正在调用它。
        """
        
        self.registered_prompt = """
        您的任务是根据用户信息存储数据。您需要从用户那里获得以下信息:
        1.用户名、性别、年龄
        2.用户设置的密码
        3.用户的电子邮件地址
        如果用户没有提供此信息,您需要提示用户提供。如果用户提供了此信息,则需要将此信息存储在数据库中,并告诉用户注册成功。
        存储方法是使用SQL语句。您可以使用SQL编写插入语句,并且需要生成用户ID并将其返回给用户。
        如果用户没有新问题,您应该回复带有 "customer service" 的特殊令牌,以结束任务。
        """
        
        self.query_prompt = """
        您的任务是查询用户信息。您需要从用户那里获得以下信息:
        1.用户ID
        2.用户设置的密码
        如果用户没有提供此信息,则需要提示用户提供。如果用户提供了此信息,那么需要查询数据库。如果用户ID和密码匹配,则需要返回用户的信息。
        如果用户没有新问题,您应该回复带有 "customer service" 的特殊令牌,以结束任务。
        """
        
        self.delete_prompt = """
        您的任务是删除用户信息。您需要从用户那里获得以下信息:
        1.用户ID
        2.用户设置的密码
        3.用户的电子邮件地址
        如果用户没有提供此信息,则需要提示用户提供该信息。
        如果用户提供了这些信息,则需要查询数据库。如果用户ID和密码匹配,您需要通知用户验证码已发送到他们的电子邮件,需要进行验证。
        如果用户没有新问题,您应该回复带有 "customer service" 的特殊令牌,以结束任务。
        """
        # 使用字典存储不同场景的消息
        self.messages = {
            "system": [{"role": "system", "content": self.system_prompt}],
            "registered": [{"role": "system", "content": self.registered_prompt}],
            "query": [{"role": "system", "content": self.query_prompt}],
            "delete": [{"role": "system", "content": self.delete_prompt}]
        }
        # 当前处理的任务
        self.current_assignment = "system"
    def get_response(self, user_input):
        self.messages[self.current_assignment].append({"role": "user", "content": user_input})
        while True:
            response = self.client.chat.completions.create(
                model="glm-4",
                messages=self.messages[self.current_assignment],
                temperature=0.9,
                stream=False,
                max_tokens=2000,
            )
            ai_response = response.choices[0].message.content
            if "registered workers" in ai_response:
                self.current_assignment = "registered"
                print("意图识别:", ai_response)
                print("switch to <registered>")
                self.messages[self.current_assignment].append({"role": "user", "content": user_input})
            elif "query workers" in ai_response:
                self.current_assignment = "query"
                print("意图识别:", ai_response)
                print("switch to <query>")
                self.messages[self.current_assignment].append({"role": "user", "content": user_input})
            elif "delete workers" in ai_response:
                self.current_assignment = "delete"
                print("意图识别:", ai_response)
                print("switch to <delete>")
                self.messages[self.current_assignment].append({"role": "user", "content": user_input})
            elif "customer service" in ai_response:
                print("意图识别:", ai_response)
                print("switch to <customer service>")
                self.messages["system"] += self.messages[self.current_assignment]
                self.current_assignment = "system"
                return ai_response
            else:
                self.messages[self.current_assignment].append({"role": "assistant", "content": ai_response})
                return ai_response
    def start_conversation(self):
        print("智能客服助手已启动,请输入您的问题(输入 'exit' 或 'quit' 退出)")
        while True:
            user_input = input("User: ")
            if user_input.lower() in ['exit', 'quit']:
                print("感谢使用智能客服系统,再见!")
                break
            response = self.get_response(user_input)
            print("Assistant:", response) 

在我们的main.p文件中,去调用这个类,也就是调用这个客服

代码语言:javascript
代码运行次数:0
运行
复制
if __name__ == "__main__":
    assistant = SmartAssistant(client)
    assistant.start_conversation()

3. 运行智能体

确保您的 .env 文件中有正确的 API 密钥,然后在命令行中运行:

代码语言:javascript
代码运行次数:0
运行
复制
python main.py

接下来,我们看它的输出,它不再是一个LLM只会回答你的问题,它可以通过自己的思考,按照自己的人设,去为你解决问题,这就是Agents的意义所在,现在我们运行代码之后,我问他,

代码语言:javascript
代码运行次数:0
运行
复制
我忘记我的账号密码了

他的回复是这样的

代码语言:javascript
代码运行次数:0
运行
复制
PS D:\agent> python main.py
你好🌏!很高兴见到你,有什么可以帮助你的吗?
智能客服助手已启动,请输入您的问题(输入 'exit' 或 'quit' 退出)
User: 我的账号密码忘记了
意图识别: 1.用户注册
```python
tool_call(token='registered workers')
```
switch to <registered>
意图识别: 如果您忘记了自己的账号密码,您可以按照以下步骤来重置或找回密码:

1. **找到重置密码选项**:在登录界面通常会有“忘记密码”、“重置密码”或类似的选项。

2. **验证身份**:点击该选项后,系统会要求您提供一些信息来 验证您的身份,这通常是通过电子邮件地址或者手机号码来完成的。

3. **检查您的邮箱或手机**:根据您提供的联系方式,系统会发 送一个重置密码的链接或验证码。

4. **按照指引操作**:通过邮箱中的链接或者输入手机收到的验 证码进入密码重置页面。

5. **设置新密码**:在密码重置页面,输入新的密码,并确认密 码。

6. **完成重置**:按照页面的提示完成密码重置流程。

如果您在找回密码的过程中遇到任何问题,可以联系客服帮助解决。

但是,由于我是一个虚拟助手,我无法直接帮您处理忘记密码的问题,也无法访问实际的数据库来存储或检索信息。不过,我可以提供一个SQL插入语句的示例,帮助理解这个过程:

```sql
-- 假设我们有一个用户表 `users`,字段包括:user_id, username, gender, age, password, email

-- 插入用户数据的SQL语句
INSERT INTO users (username, gender, age, password, email)
VALUES ('张三', '男', 25, 'hashed_password', 'zhangsan@example.com');

-- hashed_password 是指加密后的密码,实际操作中不应存储明 文密码。

-- 生成用户ID的SQL语句,这通常是在插入数据之前完成的,取决于数据库的设计
-- 假设用户ID是自动增长的,下面这条语句可能不是必须的     
SELECT LAST_INSERT_ID(); -- 在MySQL中这样获取最后一个插入 记录的自增ID
```

对于找回密码的问题,您应该联系实际的客户服务部门或者使用网站提供的帮助工具。

如果您不需要进一步的帮助,请告诉我“customer service”,我会结束这个任务。
switch to <customer service>
Assistant: 如果您忘记了自己的账号密码,您可以按照以下步骤 来重置或找回密码:

1. **找到重置密码选项**:在登录界面通常会有“忘记密码”、“重置密码”或类似的选项。

2. **验证身份**:点击该选项后,系统会要求您提供一些信息来 验证您的身份,这通常是通过电子邮件地址或者手机号码来完成的。

3. **检查您的邮箱或手机**:根据您提供的联系方式,系统会发 送一个重置密码的链接或验证码。

4. **按照指引操作**:通过邮箱中的链接或者输入手机收到的验 证码进入密码重置页面。

5. **设置新密码**:在密码重置页面,输入新的密码,并确认密 码。

6. **完成重置**:按照页面的提示完成密码重置流程。

如果您在找回密码的过程中遇到任何问题,可以联系客服帮助解决。

但是,由于我是一个虚拟助手,我无法直接帮您处理忘记密码的问题,也无法访问实际的数据库来存储或检索信息。不过,我可以提供一个SQL插入语句的示例,帮助理解这个过程:

```sql
-- 假设我们有一个用户表 `users`,字段包括:user_id, username, gender, age, password, email

-- 插入用户数据的SQL语句
INSERT INTO users (username, gender, age, password, email)
VALUES ('张三', '男', 25, 'hashed_password', 'zhangsan@example.com');

-- hashed_password 是指加密后的密码,实际操作中不应存储明 文文密码。

-- 生成用户ID的SQL语句,这通常是在插入数据之前完成的,取决于数据库的设计
-- 假设用户ID是自动增长的,下面这条语句可能不是必须的       
SELECT LAST_INSERT_ID(); -- 在MySQL中这样获取最后一个插入记 录的自增ID
```

对于找回密码的问题,您应该联系实际的客户服务部门或者使用网站提供的帮助工具。

如果您不需要进一步的帮助,请告诉我“customer service”,我会结束这个任务。
User: gis

一系列的过程,都体现了它自己思考,自己执行的能力,它不再是只会一步,他能够去自己想做一些事情,接着,我们再问他

代码语言:javascript
代码运行次数:0
运行
复制
User: 我需要注册一个账号,怎么注册
意图识别: 好的,为了帮您注册账号,我需要收集以下信息:

1. 用户名
2. 性别
3. 年龄
4. 密码
5. 电子邮件地址

请提供以上信息,以便我为您创建账号。在您提供这些信息后,我会生成一个用户ID,并将其返回给您。同时,我会发送一个"registered workers"的特殊令牌给相关部门,以便他们知道有新的注册请求。

现在,您可以开始提供这些信息了。
switch to <registered>
Assistant: 为了注册账号,请您提供以下信息:

1. 用户名
2. 性别
3. 年龄
4. 您希望设置的密码
5. 您的电子邮件地址

请您提供这些信息,以便我可以帮您完成注册并存储数据到数据库中。例如:

- 用户名:张三
- 性别:男
- 年龄:28
- 密码:(请提供一个您希望的密码)
- 电子邮件地址:zhangsan@example.com

您只需提供上述信息,我会为您生成一个用户ID,然后模拟执行SQL 插入语句以存储信息。请注意,在实际应用中,密码不应该以明文形式存储,而是经过加密处理。以下是模拟的SQL插入语句的示例:   

```sql
INSERT INTO users (username, gender, age, password, email)  
VALUES ('张三', '男', 28, 'your_password_here', 'zhangsan@example.com');
```

在您提供信息后,我会“执行”这个语句,并告诉您注册成功,同时提供给您一个生成的用户ID。请提供您的注册信息吧。
User:

基于我们设计的一个简单的提示词,一个简单的Agents就完成了,我们这次的目的,只是为了去体验,用最基础的代码,去手搓一个最简单的Agents,帮助我们去理解

4. 功能说明

①注册:当用户输入注册相关信息时,智能体会提示用户提供必要的注册信息。

②查询:当用户输入查询相关信息时,智能体会提示用户提供用户ID和密码。

③删除:当用户输入删除相关信息时,智能体会提示用户提供用户ID、密码和电子邮件。

通过这些步骤,您将能够创建一个简单的智能客服智能体,并与之进行交互。您可以根据需要进一步扩展和完善智能体的功能

让我们分析一下这个智能体的表现:

优点:

①意图识别正确

1、成功识别了"忘记密码"的场景

2、正确识别了"注册账号"的需求

3、准确识别了"查询用户"的请求

②状态切换正常

1、从 system -> registered -> customer service 的切换正确

2、从 system -> query 的切换也正确

3、每次切换都有清晰的提示("switch to <xxx>")

③ 提示词执行到位

1、按照预设的 prompt 给出相应的回答

④要求用户提供必要的信息

1、给出了具体的SQL示例

2、交互流畅

3、对话自然

4、回答详细

5、引导清晰

需要改进的地方:

  1. 重复信息

在某些回答中出现了重复的内容,比如SQL语句示例重复出现状态管理,在处理"靓仔"这个简单回答时,可能切换状态过于频繁,从 registered 直接切换到 customer service 可能过早

2、信息收集

可以更有条理地一步步收集用户信息,增加信息验证的环节

3、建议改进:

增加渐进式信息收集

代码语言:javascript
代码运行次数:0
运行
复制
def collect_user_info(self):
info = {}
fields = ['username', 'gender', 'age', 'password', 'email']
for field in fields:
info[field] = self.ask_for_field(field)
return inf

优化状态切换逻辑

代码语言:javascript
代码运行次数:0
运行
复制
def should_switch_state(self, current_state, response):

总的来说,这个智能体实现了基本功能,但还可以在用户体验和功能完整性上进行优化。下次我们继续搞一个大的

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-01-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 一个正经的测试 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 创建项目目录
  • 2. 创建 .env 文件
  • 3. 项目结构
  • 5. 创建 Python 脚本
  • 6. 运行脚本
  • 3. 运行智能体
  • 接下来,我们看它的输出,它不再是一个LLM只会回答你的问题,它可以通过自己的思考,按照自己的人设,去为你解决问题,这就是Agents的意义所在,现在我们运行代码之后,我问他,
  • 他的回复是这样的
  • 一系列的过程,都体现了它自己思考,自己执行的能力,它不再是只会一步,他能够去自己想做一些事情,接着,我们再问他
  • 基于我们设计的一个简单的提示词,一个简单的Agents就完成了,我们这次的目的,只是为了去体验,用最基础的代码,去手搓一个最简单的Agents,帮助我们去理解
  • 4. 功能说明
  • 优点:
  • 需要改进的地方:
  • 3、建议改进:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档