如何手搓AI Agent

写在前面:本文源自2025年3月的一次公司内部分享。如果你也曾被“大模型无所不能”的宣传洗脑过,那今天咱们就一起拆穿它的“嘴强王者”本质,并亲手给它装上手脚——做一个真正能干活的AI Agent!

一、大模型这么强,为啥还要Agent?

你有没有试过对ChatGPT说:“帮我订张机票!”
它大概会温柔地回你一句:“亲,建议您打开携程哦~”

是不是瞬间感觉被敷衍了?
没错,这就是当前大语言模型(LLM)的三大“硬伤”:

  • 知识滞后:它可能还在怀念2012年的世界末日,根本不知道昨天的油价涨了。
  • 无法动手:它能教你追女神,但不会帮你发微信(毕竟它连手机都没有)。
  • 缺乏主见:像极了开会时说“我都行”的同事,最后活全甩给你。

所以,光靠“嘴强”是不够的。我们需要一个能感知环境、自主决策、动手执行的智能体——这就是 AI Agent

简单来说,Agent = LLM + 工具 + 编排逻辑
你可以把它理解为:给大模型装上“手脚”(工具)和“小脑”(编排层),让它从“嘴强王者”变身“行动派打工人”!


二、Agent vs LLM:谁才是真·靠谱?

特性 LLM(比如 ChatGPT) AI Agent
核心能力 语言理解与生成 语言理解 + 推理规划 + 工具调用 + 自主行动
知识来源 训练数据(截止到某年某月) 训练数据 + 实时信息 + 外部数据库
能不能动手? ❌ 只能嘴上说说 ✅ 能查天气、发邮件、订机票
解决问题方式 被动回答 主动分析 → 规划 → 执行
举个栗子 “你可以试试携程” “已为你订好10月15日北京飞三亚的机票,经济舱,靠窗”

一句话总结:LLM 是顾问,Agent 是包工头


三、手搓Agent的“三剑客”

一个完整的Agent通常由三个核心组件构成:

  1. 大脑(LLM):负责理解用户意图、推理任务、决定下一步干啥。比如判断你是要注册、查询,还是删号跑路。
  2. 手脚(Tools):让Agent能和外部世界互动,比如查数据库、发邮件、调API。没有工具,Agent就是个“思想家”。
  3. 指挥中心(编排层):协调大脑和手脚,管理对话状态,确保任务一步步推进,不跑偏。

整个流程大概是这样的:

用户输入 → LLM理解意图 → 规划行动 → 调用工具 → 获取结果 → 返回用户(或继续下一步)


四、开发前的“吃饭家伙”

别急着写代码,先备好装备:

  • Python:AI界的“万能胶水”,库多、生态好、写起来爽。
  • PyCharm 或 Jupyter Notebook:一个适合工程开发,一个适合快速验证想法。
  • LLM选择:国内推荐通义千问(Qwen),免费额度够用(比如 qwen-max 送100万token),后面案例就用它。
  • 基础知识:懂点机器学习原理、会处理数据、能写Python函数——不用多深,但得会“缝合”。

💡小贴士:本文坚持“手搓”原则——不用 Dify、Coze 这类平台,直接写代码!只为让你知其然,更知其所以然


五、实战:从 Hello World 到油田问数

1. Hello World 级 Agent

最简单的Agent:你问它“你好”,它回你“你好呀!”。虽然没啥用,但仪式感不能少!

运行代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import os
from dotenv import load_dotenv
from openai import OpenAI
# 加载环境变量
load_dotenv()
# 设置API密钥,从千问里面去获取
api_key = "sk-c1f…………"
# 基础配置
base_url = "https://dashscope.aliyuncs.com/compatible-mode/v1"
# 设置使用的基础模型,在阿里模型超市可以看到model名称
chat_model = "deepseek-v3"
# 创建客户端
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},
],
extra_body={"enable_thinking": False},
)
return response.choices[0].message.content
# 测试调用
response = get_completion("你好,南威软件!")
print(response)

运行结果

1
2
3
4
5
6
7
8
9
10
你好!看来你对 **南威软件** 感兴趣。南威软件(Nanwei Software)是中国一家专注于 **政务信息化、公共安全、智慧城市** 等领域的高新技术企业,提供软件开发、系统集成和解决方案服务。  

如果你有具体问题,比如:
- 公司业务或产品
- 股票/上市信息(上交所代码:603636)
- 合作或招聘咨询

可以直接告诉我,我会尽力帮你整理相关信息! 😊

(注:作为AI,我无法访问实时数据,但可以提供公开资料或分析建议。)

2. 客服智能体

对于程序调用大模型API有了初步的概念之后,我们快马加鞭不下鞍,一路狂奔吧,少年!!接下去往复杂一点的需求去探索,做一个客服智能体,能够实现基础的意图识别及响应操作。

目标:能处理注册、查询、删除三类请求。

  • 注册功能:当用户输入注册相关信息时,智能体会提示用户提供必要的注册信息
  • 查询功能:当用户输入查询相关信息时,智能体会提示用户提供用户ID和密码。
  • 删除功能:当用户输入删除相关信息时,智能体会提示用户提供用户ID、密码和电子邮件。

背后逻辑?就是用LLM判断意图,再引导用户提供必要信息——典型的“状态机+工具调用”雏形。

运行代码——场景操作代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import time
class SmartAssistant:
def __init__(self, client):
self.client = client
# 定义不同场景的提示词
self.system_prompt = """你是一个聪明的客服。您将能够根据用户的问题将不同的任务分配给不同的人。您有以下业务线:
1.用户注册。如果用户想要执行这样的操作,您应该发送一个带有"registered workers"的特殊令牌。并告诉用户您正在调用它。
2.用户数据查询。如果用户想要执行这样的操作,您应该发送一个带有"query workers"的特殊令牌。并告诉用户您正在调用它。
3.删除用户数据。如果用户想执行这种类型的操作,您应该发送一个带有"delete workers"的特殊令牌。并告诉用户您正在调用它。
4.重置用户密码。如果用户想执行这种类型的操作,您应该发送一个带有"reset 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.reset_prompt = """
您的任务是重置用户密码。您需要从用户那里获得以下信息:
1.用户ID
2.用户原密码
3.用户需要设置的新密码
如果用户没有提供此信息,则需要提示用户提供该信息。
如果用户提供了这些信息,则需要查询数据库。如果用户ID和密码匹配,您需要将用户的密码修改,并告诉用户修改成功。
修改方法是使用SQL语句。您可以使用SQL编写更新语句。
如果用户没有新问题,您应该回复带有 "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}],
"reset": [{"role": "system", "content": self.reset_prompt}]
}
# 当前处理的任务
self.current_assignment = "system"

def get_response(self, user_input):
print(f'您的诉求是:{user_input}')
self.messages[self.current_assignment].append({"role": "user", "content": user_input})

while True:
response = self.client.chat.completions.create(
model="qwen-plus",
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 "reset workers" in ai_response:
self.current_assignment = "reset"
print("意图识别:", ai_response)
print("switch to <reset>")
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)
time.sleep(2)

运行代码——大模型调用代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from dotenv import load_dotenv
from openai import OpenAI
# 加载环境变量
load_dotenv()
api_key = "sk-8f…………"
# 基础配置
base_url = "https://dashscope.aliyuncs.com/compatible-mode/v1"
chat_model = "qwen-plus"
# 创建客户端
client = OpenAI(
api_key=api_key,
base_url=base_url
)
assistant = SmartAssistant(client)
assistant.start_conversation()

运行结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
智能客服助手已启动,请输入您的问题(输入 'exit' 或 'quit' 退出)
User: 我忘记密码了
您的诉求是:我忘记密码了
意图识别: 您正在调用重置用户密码的服务。reset workers
switch to <reset>
意图识别: 您好!为了帮助您重置密码,请提供以下信息:
1. 用户ID
2. 您想设置的新密码

请注意,我们不需要原密码来执行此操作。一旦您提供了这些信息,我将协助您完成密码重置。如果您有任何其他问题,请随时告诉我。customer service
switch to <customer service>
Assistant: 您好!为了帮助您重置密码,请提供以下信息:
1. 用户ID
2. 您想设置的新密码

请注意,我们不需要原密码来执行此操作。一旦您提供了这些信息,我将协助您完成密码重置。如果您有任何其他问题,请随时告诉我。customer service
User: 算了,我还是注册新用户吧
您的诉求是:算了,我还是注册新用户吧
意图识别: 好的,您想注册新用户。我正在调用带有 "registered workers" 的特殊令牌来帮助您完成注册。

在注册之前,我需要以下信息:
1. 您的用户名
2. 您的密码
3. 您的电子邮件地址

请提供这些信息,以便我们为您创建一个新账户。如果您有任何其他问题,请告诉我!
switch to <registered>
Assistant: 好的,让我们开始注册新用户的过程。请您提供以下信息:

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

请依次提供这些信息,我将帮助您完成注册!如果任何一项信息缺失,我会提示您补充。
User: 曾铭新、男、18岁
您的诉求是:曾铭新、男、18岁
Assistant: 感谢您提供的信息!接下来,请设置您的 **密码** 和提供您的 **电子邮件地址**,以便我们继续完成注册。

请告诉我:
- 您希望设置的密码是什么?
- 您的电子邮件地址是什么?

3. 油田问数智能体(高能预警!)

这才是重头戏:用户问“昨天A油田产了多少油?”,Agent自动查数据库并返回结果。

实现步骤:

  1. 建表:创建油田信息表、生产记录表、维护日志表,塞点模拟数据。
  2. 定义工具:
    • query_production():查产量
    • query_maintenance():查维修记录
    • analyze_stats():做统计分析
  3. 连接LLM:让Qwen理解用户问题,并自动选择调用哪个工具。
  4. 跑起来:启动一个简易GUI界面(比如用 qwen_agent[gui]),开始“问数”!

想象一下:老板问“上季度哪个油田效率最低?”,Agent秒回图表+分析——升职加薪指日可待!

此部分代码相对较长,为了阅读方便,代码就打包成附件提供了,这边放一些截图。

img

img

img


六、结语:你的“数字奴隶”,不要五险一金!

AI Agent 不是魔法,而是一种工程化的智能。它把大模型的能力“落地”到真实任务中,让AI从“聊天搭子”变成“生产力工具”。

虽然现在有很多低代码平台(比如 Dify、Coze)能快速搭Agent,但亲手写一遍,才能真正理解它怎么思考、怎么行动

所以,别光看热闹——
打开你的PyCharm,今天就手搓一个属于你的AI打工人吧!

P.S. 分享会上的代码案例,欢迎私信索取(头发还在,乐意分享)!