从零开始的ReAct Agent尝试
背景
“你听说过agent吗?”同学如此说道,“好像现在挺火的,我们一起做一辈子Agent开发吧!”
概念
在人工智能领域,Agent(智能体) 是一个能够感知环境、进行决策并执行行动的自主实体。想象一下,Agent就像是一个具备思考能力的数字化"代理人",它能够代表用户或系统完成特定任务。
对于现在的小H来说,智能体应该就是一个软件中嵌入了大模型,由大模型来进行任务分配、调度、完成,还可以形成一个个循环进行学习归纳。
目前小H的能力基础是勉强能看懂python代码,马上开始学习!
环境配置
由于只会看python,所以选择了的是langgraph这个框架(当然也可以是langchain,俩者的区别主要是在结构上吧,前者是一个图的结构,langchain是一个链式的结构,前者听起来比较有逼格,所以这样选用),本节应该还不会用上,注重实现流程先。
新建一个chatbot.py 文件,同时小H选用了UV来进行虚拟环境的管理:
// 激活环境
.venv/Scripts/Activate.ps1
// 增加依赖
uv add langgraph
uv add openai
暂时先用到openai来进行环境测试,比如我们的大模型是否已经就位,需要去获取对应的api,这里小H选用的是阿里巴巴旗下的通义千问,api的获取可以在这里:首页 · 魔搭社区
给出一份测试文件:
from openai import OpenAIclient = OpenAI(api_key = 'xxxx',base_url = 'xxxx' //由于使用的不是openai,所以需要提供供应商对应的地址
)response = client.chat.completions.create(model = "Qwen/Qwen3-Coder-480B-A35B-Instruct",messages = [{'role':'user','content':'你是谁'}]
)print(response.choices[0].message.content)
这样就可以简单测试是否正确连接上了,create这是一个用于调用大语言模型进行对话生成的核心方法,主要用于与AI模型进行聊天式交互。
其中还有各种方法来设定这次聊天,例如上下文长度、流式传输等,可以自行探索。
看到正确打印结果说明连接正确了,才算开始我们的学习之路。
ReAct Agent
ReAct(Reasoning + Acting) 是一种结合推理(Reasoning)和行动(Acting)的AI代理框架,由普林斯顿大学和谷歌在2022年提出。它模拟人类解决问题的方式,通过思考和行动的循环来完成复杂任务。
对于这样一个东西我们需要以下组件:
- 大脑:大模型,例如本文选用的通义千文,利用大模型的思考能力,而我们开发者只需要将其当作一个黑盒使用。
- 记忆:数据库或者内存,用来保存对话的上下文,对于大模型,我们提供的信息越多,也就越能分析出东西。
- 工具:模型是没有像我们这样的运行环境的,所以我们可以提供一些方法,类似计算器(计算函数)给他们使用,得到计算结果等
- Prompt:提示词,小H的理解就是给大模型的一些设定或者是规则
Agent类
首先,我们来完成数据结构上的实现,仿照刚才的调用方法进行封装而已,然后目前的message我们简单采用拼接方式。
class Agent:"""A class representing an agentsystem : 设定messages : 上下文"""def __init__(self, system=""):"""Initialize the Agent with the system."""self.system = systemself.messages = []if self.system:self.messages.append({"role": "system", "content": system})def __call__(self , message):"""Call the agent with a message and return the response."""self.messages.append({"role": "user", "content": message})result = self.execute()self.messages.append({"role": "assistant", "content": result})return resultdef execute(self):"""Execute the agent's logic to generate a response."""response = client.chat.completions.create(model = 'Qwen/Qwen3-Coder-480B-A35B-Instruct',messages=self.messages)return response.choices[0].message.content
运行方法:
agent = Agent("你是正义的伙伴")
print(agent("你好"))
过程就是我们创建了一个agent,一开始给了他一份设定,同时这份设定也作为上下文保存在里面,role共有system、user、assistant三种角色,每次我们完成一次对话就将“谁发出的内容”保存到message中,这样大模型就可以看到我们每次留下的聊天记录了。
工具
接下来我们要为这个Agent提供一个可以调用的工具,这里仅用一个小的计算函数作为示例:
def calculate(what):try:return str(eval(what))except Exception as e:return f"计算错误: {str(e)}"tools_list = {"calculate": calculate
}
提示词
下一步要为这个Agent提供一段开头的提示词,也就是用来作为State的,内容应该包括Agent的设定、希望的工作流程、可用的工具、交互示例等内容,提示词对于大模型还是非常重要的,一段好的提示词可以让交互体验更加良好,以下给出一段粗糙的示例:
prompt = """
You are an intelligent assistant that follows the ReAct framework. You think, act, and observe in cycles.Follow this format strictly:Thought: Your reasoning about the problem
Action: calculate["expression"] # or other available tools
Observation: Result of the action
Result: Final answer to the user's questionAvailable tools:
- calculate: Evaluates mathematical expressionsExample:
User Question: What is 4*7+3?
Thought: I need to calculate 4*7+3
Action: calculate["4*7+3"]
Observation: 31
Result: The result of 4*7+3 is 31.
""".strip()
测试
之后我们给出一段代码进行测试:
action_re = re.compile(r'^Action:\s*(\w+)\["(.*)"\]$')def query(question, max_turns=5):i = 0bot = Agent(prompt)next_prompt = questionwhile i < max_turns:i += 1result = bot(next_prompt)print(f"=== Turn {i} ===")print(f"Response:\n{result}\n")# 解析Action行lines = result.split('\n')action_match = Nonefor line in lines:action_match = action_re.match(line.strip())if action_match:breakif action_match:# 有action需要执行action_name, action_input = action_match.groups()if action_name not in tools_list:raise Exception(f"Unknown action: {action_name}")print(f"Executing: {action_name}[\"{action_input}\"]")observation = tools_list[action_name](action_input)print(f"Observation: {observation}\n")next_prompt = f"Observation: {observation}"else:# 没有更多action,返回最终结果return resulttest_question = """
User Question: The result of expression 4*7+3
""".strip()query(test_question)
上面这一段的作用大致就是进入一个询问,然后得到结果,解析结果,判断是否需要重新到下一个循环之中,我们预定的流程是Thought、Action、Obeserve,如果Obeserve之后没有response,说明大模型已经得出了结果,不用再次调用,直接输出。
具体输出如下:
结语
本次我们尝试了只是用纯python语法和调用API完成了一个简易的ReAct Agent,实际上就是根据我们预先设定的各种提示进行行动的一个类似流水线的系统。