本文为《React Agent:从零开始构建 AI 智能体》专栏系列文章。 专栏地址:https://blog.csdn.net/suiyingy/category_12933485.html。项目地址:https://gitee.com/fgai/react-agent(含完整代码示例与实战源)。完整介绍:https://blog.csdn.net/suiyingy/article/details/146983582。
在当今数字化时代,代码编写和执行的自动化需求日益增长。对于开发人员和技术爱好者来说,一个能够快速生成和执行 Python 代码的工具可以极大地提高工作效率。本节代码执行智能体示例旨在满足以下需求,并且能够帮助用户快速实现 Python 代码的生成和执行,提升开发和学习的体验。
(1)代码生成:通过与大语言模型(LLM)集成,根据用户的自然语言描述生成符合要求的 Python 代码。
(2)代码执行:安全地执行生成的 Python 代码,并返回执行结果,包括控制台输出或错误信息。
(3)对话记忆:维护对话历史,以便大语言模型能够基于上下文生成更准确的响应,提高交互的连贯性。
(4)安全过滤:对用户输入和生成的代码进行安全检查,防止执行危险操作,如文件读写、系统命令执行等。
其基本流程如下图所示,步骤为:
(1)初始化:创建 CodeAgent 实例,该实例包含 LLM(大语言模型集成模块)、MemoryManager(记忆管理模块)和 CodeExecutor(代码执行模块)的实例。
(2)用户输入:用户提供自然语言描述的需求,例如 “写一个打印 Hello World 的程序”。
(3)记忆管理:将用户输入添加到对话历史中,以便后续对话能够基于上下文进行。
(4)构建对话上下文:将系统提示、对话历史和用户输入组合成一个完整的对话上下文,用于与大语言模型交互。
(5)生成响应:使用大语言模型根据对话上下文生成响应,期望得到包含 Python 代码的回复。
(6)提取代码:从大语言模型的响应中提取出 Python 代码部分。
(7)代码执行:将提取的代码传递给代码执行模块进行安全检查和执行,并获取执行结果。
(8)返回结果:将执行结果返回给用户,并将助手的回复添加到对话历史中,以便后续交互。
(9)循环交互:重复步骤 2 到 8,实现持续的用户与智能体之间的交互。
图1 代码执行智能体流程
大模型和记忆管理模块与上文基本保持一致,这里重点介绍代码执行模块(CodeExecutor)。其程序如下:
class CodeExecutor:
"""代码执行模块(带持久化环境)"""
def __init__(self):
self.locals = {}
self.blacklist = ['open(', 'os.', 'sys.', 'subprocess.'] # 基础安全过滤
def _safety_check(self, code):
for forbidden in self.blacklist:
if forbidden in code:
return False, f"安全检查失败:检测到禁用关键字 {forbidden}"
return True, ""
def execute(self, code):
# 执行安全检查
is_safe, msg = self._safety_check(code)
if not is_safe:
return msg
try:
# 准备执行环境
f = io.StringIO()
with redirect_stdout(f):
exec(code, self.locals, self.locals) # 执行代码
output = f.getvalue()
return output.strip() or "代码执行成功(无控制台输出)"
except Exception as e:
return f"执行错误:{str(e)}"
代码执行模块是保障 Python 代码安全运行的关键组件,其核心职责在于对输入代码进行安全性审查与执行,并将结果反馈给系统。在初始化阶段,该模块会创建一个空的本地命名空间 self.locals,用于存储代码执行时定义的变量和函数;同时构建黑名单 self.blacklist,将诸如 open(、os.、sys.、subprocess. 等可能触发危险操作的关键字纳入其中,为后续安全检查筑牢防线。
在执行具体代码时,模块首先调用 _safety_check 方法,逐一遍历黑名单中的禁用关键字,若代码中存在任何禁用内容,立即返回 False 与错误提示,终止执行;若检查通过,则进入 execute 方法。该方法通过 io.StringIO 对象与redirect_stdout 实现控制台输出的捕获,利用 exec 函数在本地命名空间内执行代码,最终将捕获的输出结果或“代码执行成功(无控制台输出)”信息返回,若执行期间出现异常,也会及时将异常信息反馈,确保代码执行过程的安全性与结果可追溯性。
代码执行智能体完整程序如下:
import openai
import re
from collections import deque
from contextlib import redirect_stdout
import io
class CodeExecutor:
'''代码执行模块(带持久化环境)'''
def __init__(self):
self.locals = {}
self.blacklist = ['open(', 'os.', 'sys.', 'subprocess.'] # 基础安全过滤
def _safety_check(self, code):
for forbidden in self.blacklist:
if forbidden in code:
return False, f'安全检查失败:检测到禁用关键字 {forbidden}'
return True, ''
def execute(self, code):
# 执行安全检查
is_safe, msg = self._safety_check(code)
if not is_safe:
return msg
try:
# 准备执行环境
f = io.StringIO()
with redirect_stdout(f):
exec(code, self.locals, self.locals) # 执行代码
output = f.getvalue()
return output.strip() or '代码执行成功(无控制台输出)'
except Exception as e:
return f'执行错误:{str(e)}'
class LLM:
'''大语言模型集成模块'''
def __init__(self):
api_key = '<用户的 API Key>'
base_url = 'https://dashscope.aliyuncs.com/compatible-mode/v1'
self.model = 'qwen-turbo-latest'
self.client = openai.OpenAI(
api_key=api_key,
base_url=base_url,
)
def generate_response(self, messages):
try:
response = self.client.chat.completions.create(
model=self.model,
messages=messages,
temperature=0.3, # 降低随机性保证代码准确性
max_tokens=2000
)
return response.choices[0].message.content.strip()
except Exception as e:
return f'生成响应时出错:{str(e)}'
class MemoryManager:
'''记忆管理模块'''
def __init__(self, max_history=5):
self.history = deque(maxlen=max_history)
def add_history(self, role, content):
self.history.append({'role': role, 'content': content})
def get_history(self):
return list(self.history)
class CodeAgent:
'''代码执行智能体'''
def __init__(self):
self.llm = LLM()
self.memory = MemoryManager()
self.executor = CodeExecutor()
self.system_prompt = {
'role': 'system',
'content': '''你是一个专业代码助手,请遵守以下规则:
1. 仅生成符合要求的Python代码
2. 代码必须用三个反引号包裹
3. 优先使用标准库
4. 保证代码简洁高效
5. 不要包含解释性文本'''
}
self.code_pattern = re.compile(r'```python\n(.*?)\n```', re.DOTALL)
def _build_messages(self, history, prompt):
messages = [self.system_prompt] + history
messages.append({'role': 'user', 'content': prompt})
return messages
def _extract_code(self, response):
match = self.code_pattern.search(response)
return match.group(1).strip() if match else None
def process_input(self, user_input):
# 维护对话历史
self.memory.add_history('user', user_input)
# 准备对话上下文
history = self.memory.get_history()
messages = self._build_messages(history, user_input)
# 获取LLM响应
response = self.llm.generate_response(messages)
# 处理代码执行
execution_result = ''
code = self._extract_code(response)
print(f'[code]\n{code}')
if code:
execution_result = self.executor.execute(code)
final_response = f'执行结果:\n{execution_result}'
else:
final_response = '未检测到有效代码,请确认是否满足以下要求:\n1. 使用python代码块\n2. 正确使用三个反引号包裹'
# 更新对话历史
self.memory.add_history('assistant', final_response)
return final_response
def main():
agent = CodeAgent()
examples = [
'写一个打印Hello World的程序',
'创建一个从1加到100的求和函数并调用',
'写一个计算斐波那契数列前n项的函数',
'帮我生成一个三维坐标点的类,包含距离计算方法',
'刚才的代码执行结果是什么?'
]
for query in examples:
print(f'[用户] {query}')
response = agent.process_input(query)
print(f'[助手] {response}\n{"-"*60}')
if __name__ == '__main__':
main()
完整运行结果如下:
(base) root@af9c70063d44:~/share/project/react-agent# /root/miniconda3/bin/python /root/share/project/react-agent/exp07-agent-basis/code_agent.py
[用户] 写一个打印Hello World的程序
[code]
print("Hello World")
[助手] 执行结果:
Hello World
------------------------------------------------------------
[用户] 创建一个从1加到100的求和函数并调用
[code]
def sum_1_to_100():
return sum(range(1, 101))
print(sum_1_to_100())
[助手] 执行结果:
5050
------------------------------------------------------------
[用户] 写一个计算斐波那契数列前n项的函数
[code]
None
[助手] 未检测到有效代码,请确认是否满足以下要求:
1. 使用python代码块
2. 正确使用三个反引号包裹
------------------------------------------------------------
[用户] 帮我生成一个三维坐标点的类,包含距离计算方法
[code]
import math
class Point3D:
def __init__(self, x=0, y=0, z=0):
self.x = x
self.y = y
self.z = z
def distance(self, other):
dx = self.x - other.x
dy = self.y - other.y
dz = self.z - other.z
return math.sqrt(dx**2 + dy**2 + dz**2)
# 示例使用
p1 = Point3D(1, 2, 3)
p2 = Point3D(4, 5, 6)
print(p1.distance(p2))
[助手] 执行结果:
5.196152422706632
------------------------------------------------------------
[用户] 刚才的代码执行结果是什么?
[code]
None
[助手] 未检测到有效代码,请确认是否满足以下要求:
1. 使用python代码块
2. 正确使用三个反引号包裹
------------------------------------------------------------
图2 代码执行智能体运行结果
点击订阅《React Agent 开发专栏》,每周获取智能体开发深度教程。项目代码持续更新至React Agent 开源仓库,欢迎 Star 获取实时更新通知!FGAI 人工智能平台:FGAI 人工智能平台 https://www.botaigc.cn/