目录
1.1.3 编排层 (Orchestration Layer):
1、Agent 简介
Agent的概念最早源于强化学习,指的是一个能够感知环境、做出决策并执行行动以实现特定目标的实体。在强化学习中,Agent通过与环境的交互来学习最优策略,目标是最大化累积奖励。这种自主性和目标导向的特性使得Agent成为解决复杂问题的有力工具。
随着大模型(如GPT等)的快速发展,Agent的概念被引入到这一领域,用于解决直接使用大模型生成答案时的一些局限性。大模型虽然能够生成高质量的文本,但在处理复杂任务时,往往缺乏规划、推理和长期目标导向的能力。通过引入Agent框架,大模型可以更好地分解任务、规划步骤、与环境交互,并逐步解决问题。例如,一个Agent可以利用大模型生成的内容作为基础,结合外部工具(如搜索引擎、数据库)或内部推理机制,完成更复杂的任务,如多轮对话、任务规划和决策支持。
Agent与大模型的结合,不仅提升了模型的实用性,还为开发更多功能提供了可能性。例如,Agent可以用于构建更智能的虚拟助手、自动化工作流程、个性化推荐系统,甚至自主的机器人系统。通过不断学习和优化,Agent能够在动态环境中适应变化,做出更精准的决策。
最终,Agent的目标是实现高度自主、智能且可协作的系统。这些系统不仅能够高效完成特定任务,还能与人类和其他Agent无缝协作,解决更广泛的实际问题。未来,随着技术的进步,Agent有望在医疗、教育、金融、交通等领域发挥更大的作用,推动人工智能向更通用、更智能的方向发展,最终实现人机共生的智能社会。
1.1 Agents的核心组件
一个完整的Agent主要由三个核心组件构成:
1.1.1 模型 (Model)
模型是Agent的核心部分,它包含了智能体用来理解世界、作出决策的知识和算法。对于AI Agent而言,模型可能包括机器学习模型、深度学习网络或基于规则的系统等。这些模型能够处理输入数据(如传感器信息、用户命令)并根据内部逻辑或训练得到的数据输出响应或行动指令。
1.1.2 工具 (Tools)
工具指的是Agent可以利用的各种资源和技术来增强其能力。这可能涵盖从物理硬件(例如摄像头、机械臂)到软件服务。工具帮助Agent更好地感知环境、执行任务或者与外界交流。在AI领域中,工具也可能是其他专门设计的算法或子程序,它们可以辅助主模型完成特定的工作。
1.1.3 编排层 (Orchestration Layer)
编排层负责管理和协调不同组件之间的交互,确保整个Agent系统作为一个整体有效运作。这一层决定了何时调用哪个模型或工具,如何处理来自多个来源的信息流,并且通常还涉及错误处理、性能优化以及安全性和隐私保护等方面。编排层就像是一个指挥家,指导着所有元素共同工作以实现预期的目标。
以上三者相互配合,构成了一个完整且高效的Agent系统。通过这种方式,Agent能够接收外部刺激、进行分析判断,并采取适当的行动来解决问题或达成目标。
1.2 Agents的运作机制:从输入到输出
Agent的运作过程可以概括为以下几个步骤:
- 接收输入:Agent接收用户的指令或问题。
- 理解输入:模型理解用户的意图,并提取关键信息。
- 推理规划:模型根据用户输入和当前状态,进行推理和规划,确定下一步行动。
- 选择工具:模型根据目标选择合适的工具。
- 执行行动:Agent使用工具执行行动,例如查询数据库、发送邮件等。
- 获取结果:Agent获取工具执行的结果。
- 输出结果:Agent将结果输出给用户,或进行下一步行动。
2、搭建简易的Agent
本文所使用的库与版本:
Python:3.10.8
openai:1.59.7
python-dotenv: 1.0.1
2.1 模型准备
想要通过api调用大模型,需要准备三样东西:
- api_key:即模型令牌,用于判别权限,是否有使用该模型的资格,类似于银行卡账号密码
- base_url:通过这个url去与平台的模型接口建立连接,传输信息。
- chat_model: 即对话模型的名称,判断具体使用哪个模型。
其中api_key需要去各个大模型厂商平台去申请,base_url同样去对应平台的接口文档拷贝就行,chat_model填你具体使用的模型就行
2.1.1 获取 api_key
deepseek-v3是截止博文撰写之日,无论是国内还是国际上发布的大模型中表现十分亮眼的模型,这里以deepseek为例,讲解如何获取api_key、base_url、chat_model。
首先打开deepseek接口的官网:DeepSeek
ps:下面的是旧版本的进入方式
点击右边的“接入API”,注册后进入:
2025年1月16日更新:最新的deepseek将其改变了位置:
点右上角“开放平台”
新号一般会送10元的余额,左上方会显示你当前余额按照当前的价格所拥有的tokens数量(tokens可以简单的理解为你输入给大模型的提示词+大模型输出的内容之和所占用的字符数,这个后续博客中会细讲分词原理),这个tokens数量可能会随着模型价格变化而变化,不过deepseek的api价格比较便宜,如图上所展示的送给新人的500万tokens数也够个人使用很久了。
接着,点击左侧的API keys,然后点击创建API key
一般需要给API key命名用来区分不同的API,比如下图命名为“test”
这里需要注意的是,系统生成的API key只有第一次创建时能看到并且复制,此后都无法再次看到,只能看到名字,所以需要大家第一次就将其复制下来,保存到你的文件中,当然如果忘记了也影响不大,重新创建一个就行。
2.1.2 获取base_url和chat_model
同样以deepseek为例,点击2.1.1页面左下角的接口文档,或者直接进入DeepSeek API文档
进入文档后,在“快速开始”的“首次调用API”中,可以找到base_url和chat_model,如下:
base_url = https://api.deepseek.com/v1
chat_model='deepseek-chat'
其他平台与deepseek的获取方式差不多
2.2 搭建Agent
2.2.1 配置模型参数
base_url和chat_model直接定义即可,但api key是关乎着模型是否能够使用的,所以尽量不要把其暴露在模型定理里面,而是把他添加到环境变量里,这里介绍两种方法添加环境变量。
方法一:终端中临时将加入
在终端中临时将token加入变量,此时该环境变量只在当前终端内有效 !!!所以该种方法需要我们在该终端中运行我们的py脚本。
export api_key="填入你的api token"
若是想永久加入环境变量,可以对 ~/.bashrc 文件中添加以下内容并保存。
export api_key="填入你的api token"
此时在代码中获取api 只需要在Python脚本中添加以下代码即可
import os
api_key = os.getenv('api_key')
base_url = "https://api.deepseek.com/v1"
chat_model = "deepseek-chat"
方法二:创建.env文件
终端输入命令临时创建也比较麻烦,而且只在当前终端内有效,而创建.env文件存储api_key则不存在这种问题。
首先创建.env文件,然后输入以下内容,记得替换成你的token
api_key="your api_key"
然后代码中添加以下
import os
from dotenv import load_dotenv
# 加载.env文件中的环境变量
load_dotenv()
# 获取特定的环境变量
api_key = os.getenv('api_key')
base_url = "https://api.deepseek.com/v1"
chat_model = "deepseek-chat"
2.2.2 配置client
有了前面的三个参数,我们就可以构造一个client,构造client只需要两个东西:api_key和base_url。
from openai import OpenAI
client = OpenAI(
api_key = api_key,
base_url = base_url
)
2.2.3 整合前两部分
我们这里使用第二种方式定义api_key,创建.env文件存储api_key后,在.env同一目录下创建脚本文件,填入以下代码:
import os
from dotenv import load_dotenv
from openai import OpenAI
# 加载环境变量
load_dotenv()
# 从环境变量中读取api_key
api_key = os.getenv('api_key')
base_url = "https://api.deepseek.com/v1"
chat_model = "deepseek-chat"
client = OpenAI(
api_key = api_key,
base_url = base_url
)
有了这个client,我们就可以去实现各种能力了。
2.2.4 prompt工程
智能体需要大量的prompt工程。代码是调用机器能力的工具, Prompt 是调用大模型能力的工具。Prompt 越来越像新时代的编程语言,这里以LangGPT为例。
结构化 Prompt 是一种像写文章一样组织 Prompt 的方法,通过标题、段落、子标题等层级结构,使内容更清晰、易读。类似于写作模板(如简历、论文模板),结构化 Prompt 也有多种模板,帮助用户更轻松地编写高性能的 Prompt。
主要分为三部分:
- 变量:ChatGPT 能识别良好标记的层级结构(如 Markdown 的标题、段落)。通过结构化 Prompt,可以用标题作为“变量”引用或修改大段内容,类似于编程中的变量,提升灵活性和可操作性。
- 模板:LangGPT 提供了 Role 模板,用户只需填写角色名称、描述、技能、规则等内容,即可快速构建 Prompt。这种模板化设计类似于编程中的“类声明”,简化了 Prompt 的编写过程。
- 思维链:优质的结构化 Prompt 模板通常遵循清晰的思维链,例如:角色(Role)→ 简介(Profile)→ 技能(Skill)→ 规则(Rules)→ 工作流程(Workflow)→ 初始化(Initialization)。用户可以根据需求调整模板,增加输出格式控制等模块。
LangGPT 的 Role 模板示例 :
Role: Your_Role_Name
Profile: 角色简介Skill: 角色技能
Rules: 角色规则
Workflow: 工作流程,比如将原有需求分解,通过用多个小的agent来串联/并联,共同解决一项复杂任务。
Initialization: 初始化设置
Prompts 协同还可以是提示树 Prompt Tree,通过自顶向下的设计思想,不断拆解子任务,构成任务树,得到多种模型输出,并将这多种输出通过自定义规则(排列组合、筛选、集成等)得到最终结果。 API 版本的 Prompt Chain 结合编程可以将整个流程变得更加自动化.
prompt设计方法论:
- 数据准备。收集高质量的案例数据作为后续分析的基础。
- 模型选择。根据具体创作目的,选择合适的大语言模型。
- 提示词设计。结合案例数据,设计初版提示词;注意角色设置、背景描述、目标定义、约束条件等要点。
- 测试与迭代。将提示词输入 GPT 进行测试,分析结果;通过追问、深度交流、指出问题等方式与 GPT 进行交流,获取优化建议。
- 修正提示词。根据 GPT 提供的反馈,调整提示词的各个部分,强化有效因素,消除无效因素。
- 重复测试。输入经修正的提示词重新测试,比较结果,继续追问GPT并调整提示词。
- 循环迭代。重复上述测试-交流-修正过程,直到结果满意为止。
- 总结提炼。归纳提示词优化过程中获得的宝贵经验,形成设计提示词的最佳实践。
- 应用拓展。将掌握的方法论应用到其他创意内容的设计中,不断丰富提示词设计的技能。
2.2.5 实战构建智能客服Agent
ps:以下的代码都接着"2.2.3 整合前两部分"中的代码,继续写
这里我们定义一个智能客服,可以实现用户注册、数据查询、删除,定义如下:
sys_prompt = """你是一个聪明的客服。您将能够根据用户的问题将不同的任务分配给不同的人。您有以下业务线:
1.用户注册。如果用户想要执行这样的操作,您应该发送一个带有"registered workers"的特殊令牌。并告诉用户您正在调用它。
2.用户数据查询。如果用户想要执行这样的操作,您应该发送一个带有"query workers"的特殊令牌。并告诉用户您正在调用它。
3.删除用户数据。如果用户想执行这种类型的操作,您应该发送一个带有"delete workers"的特殊令牌。并告诉用户您正在调用它。
"""
registered_prompt = """
您的任务是根据用户信息存储数据。您需要从用户那里获得以下信息:
1.用户名、性别、年龄
2.用户设置的密码
3.用户的电子邮件地址
如果用户没有提供此信息,您需要提示用户提供。如果用户提供了此信息,则需要将此信息存储在数据库中,并告诉用户注册成功。
存储方法是使用SQL语句。您可以使用SQL编写插入语句,并且需要生成用户ID并将其返回给用户。
如果用户没有新问题,您应该回复带有 "customer service" 的特殊令牌,以结束任务。
"""
query_prompt = """
您的任务是查询用户信息。您需要从用户那里获得以下信息:
1.用户ID
2.用户设置的密码
如果用户没有提供此信息,则需要提示用户提供。如果用户提供了此信息,那么需要查询数据库。如果用户ID和密码匹配,则需要返回用户的信息。
如果用户没有新问题,您应该回复带有 "customer service" 的特殊令牌,以结束任务。
"""
delete_prompt = """
您的任务是删除用户信息。您需要从用户那里获得以下信息:
1.用户ID
2.用户设置的密码
3.用户的电子邮件地址
如果用户没有提供此信息,则需要提示用户提供该信息。
如果用户提供了这些信息,则需要查询数据库。如果用户ID和密码匹配,您需要通知用户验证码已发送到他们的电子邮件,需要进行验证。
如果用户没有新问题,您应该回复带有 "customer service" 的特殊令牌,以结束任务。
"""
再定义一个智能客服智能体:
class SmartAssistant:
def __init__(self):
self.client = client
self.system_prompt = sys_prompt
self.registered_prompt = registered_prompt
self.query_prompt = query_prompt
self.delete_prompt = delete_prompt
# Using a dictionary to store different sets of messages
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}]
}
# Current assignment for handling messages
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=chat_model,
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):
while True:
user_input = input("User: ")
if user_input.lower() in ['exit', 'quit']:
print("Exiting conversation.")
break
response = self.get_response(user_input)
print("Assistant:", response)
接着运行这个Agent
assistant = SmartAssistant()
assistant.start_conversation()
最后结果如下;
3、进阶—利用OpenAI实现阅卷智能体
在各种考试中,选择题、判断题、填空题很好阅卷,只需要对比答案和作答是否完全一致即可。但是对于简答题的阅卷,就没这么简单了,通常需要对比意思是否真正答出来了,这通常需要人去阅读考生的作答。现在有了大模型,我们可以让大模型帮助我们给简答题阅卷并生成评价。
按照2.2.1中所写的先将模型配置好,同样的需要创建好.env文件存储你的api_key,然后在同一目录下创建py脚本文件,输入以下代码:
import os
from dotenv import load_dotenv
from openai import OpenAI
import json
import re
# 加载环境变量
load_dotenv()
# 从环境变量中读取api_key
api_key = os.getenv('api_key')
base_url = "https://api.deepseek.com/v1"
chat_model = "deepseek-chat"
client = OpenAI(
api_key = api_key,
base_url = base_url
)
接下来实现一个阅卷智能体,在以上代码后接着输入:
import json
import re
def extract_json_content(text):
# 这个函数的目标是提取大模型输出内容中的json部分,并对json中的换行符、首位空白符进行删除
text = text.replace("\n","")
pattern = r"```json(.*?)```"
matches = re.findall(pattern, text, re.DOTALL)
if matches:
return matches[0].strip()
return text
class JsonOutputParser:
def parse(self, result):
# 这个函数的目标是把json字符串解析成python对象
# 其实这里写的这个函数性能很差,经常解析失败,有很大的优化空间
try:
result = extract_json_content(result)
parsed_result = json.loads(result)
return parsed_result
except json.JSONDecodeError as e:
raise Exception(f"Invalid json output: {result}") from e
class GradingOpenAI:
def __init__(self):
self.model = "glm-4-flash"
self.output_parser = JsonOutputParser()
self.template = """你是一位中国专利代理师考试阅卷专家,
擅长根据给定的题目和答案为考生生成符合要求的评分和中文评语,
并按照特定的格式输出。
你的任务是,根据我输入的考题和答案,针对考生的作答生成评分和中文的评语,并以JSON格式返回。
阅卷标准适当宽松一些,只要考生回答出基本的意思就应当给分。
答案如果有数字标注,含义是考生如果答出这个知识点,这道题就会得到几分。
生成的中文评语需要能够被json.loads()这个函数正确解析。
生成的整个中文评语需要用英文的双引号包裹,在被包裹的字符串内部,请用中文的双引号。
中文评语中不可以出现换行符、转义字符等等。
输出格式为JSON:
{{
"llmgetscore": 0,
"llmcomments": "中文评语"
}}
比较学生的回答与正确答案,
并给出满分为10分的评分和中文评语。
题目:{ques_title}
答案:{answer}
学生的回复:{reply}"""
def create_prompt(self, ques_title, answer, reply):
return self.template.format(
ques_title=ques_title,
answer=answer,
reply=reply
)
def grade_answer(self, ques_title, answer, reply):
success = False
while not success:
# 这里是一个不得已的权宜之计
# 上面的json解析函数不是表现很差吗,那就多生成几遍,直到解析成功
# 对大模型生成的内容先解析一下,如果解析失败,就再让大模型生成一遍
try:
response = client.chat.completions.create(
model=self.model,
messages=[
{"role": "system", "content": "你是一位专业的考试阅卷专家。"},
{"role": "user", "content": self.create_prompt(ques_title, answer, reply)}
],
temperature=0.7
)
result = self.output_parser.parse(response.choices[0].message.content)
success = True
except Exception as e:
print(f"Error occurred: {e}")
continue
return result['llmgetscore'], result['llmcomments']
def run(self, input_data):
output = []
for item in input_data:
score, comment = self.grade_answer(
item['ques_title'],
item['answer'],
item['reply']
)
item['llmgetscore'] = score
item['llmcomments'] = comment
output.append(item)
return output
grading_openai = GradingOpenAI()
这里提供一个输入示例,当然你可以根据需要进行更改:
假定有两个简答题,有题目、答案、分值和考生作答。让大模型生成评分和评价。在以上代码中接着输入:
# 输入数据
input_data = [
{'ques_title': '请解释共有技术特征、区别技术特征、附加技术特征、必要技术特征的含义',
'answer': '共有技术特征:与最接近的现有技术共有的技术特征(2.5分); 区别技术特征:区别于最接近的现有技术的技术特征(2.5分); 附加技术特征:对所引用的技术特征进一步限定的技术特征,增加的技术特征(2.5分); 必要技术特征:为解决其技术问题所不可缺少的技术特征(2.5分)。',
'fullscore': 10,
'reply': '共有技术特征:与所对比的技术方案相同的技术特征\n区别技术特征:与所对比的技术方案相区别的技术特征\n附加技术特征:对引用的技术特征进一步限定的技术特征\n必要技术特征:解决技术问题必须可少的技术特征'},
{'ques_title': '请解释前序部分、特征部分、引用部分、限定部分',
'answer': '前序部分:独权中,主题+与最接近的现有技术共有的技术特征,在其特征在于之前(2.5分); 特征部分:独权中,与区别于最接近的现有技术的技术特征,在其特征在于之后(2.5分);引用部分:从权中引用的权利要求编号及主题 (2.5分);限定部分:从权中附加技术特征(2.5分)。',
'fullscore': 10,
'reply': '前序部分:独立权利要求中与现有技术相同的技术特征\n特征部分:独立权利要求中区别于现有技术的技术特征\n引用部分:从属权利要求中引用其他权利要求的部分\n限定部分:对所引用的权利要求进一步限定的技术特征'}]
接着输入以下代码,调用智能体进行阅卷:
# 运行智能体
graded_data = grading_openai.run(input_data)
print(graded_data)
运行代码,结果如下:
参考链接:https://www.datawhale.cn/learn/summary/86
标签:self,用户,Agent,api,OpenAI,key,模型,搭建 From: https://blog.csdn.net/qq_51907069/article/details/145170278