🤖 前言:程序员的终结者?不,是你的替身使者
前段时间,Devin横空出世,号称“全球首个 AI 软件工程师”。它能自己领任务、自己修 Bug、甚至自己去 Upwork 接单赚钱。
很多兄弟慌了:“完了,这回真要送外卖了。”
但作为技术人,恐慌之后应该是好奇。
Devin 到底是什么?是魔法吗?是 AGI 吗?
都不是。剥去营销的外衣,Devin 本质上是一个运行在沙箱里的 ReAct 循环 Agent。
今天,我就带大家用 Python 复刻一个Mini-Devin。
我们将构建一个智能体,扔给它一个报错的 Python 项目,它能自己看日志、自己改代码、自己跑测试,直到 Bug 修复为止。
🧠 核心架构:Devin 的大脑是如何工作的?
要复刻 Devin,我们需要理解它的工作流。它不是简单的“问答”,而是**“思考-行动-观察”**的无限循环。
架构图解:
核心组件:
- Brain (大脑):GPT-4o 或 Claude 3.5 Sonnet(编程能力最强)。
- Tools (手脚):让 AI 能读写文件、执行 Shell 命令。
- Sandbox (工作台):为了安全,必须在 Docker 容器里运行,防止 AI 删库跑路。
🛠️ 实战开发:打造你的 AI 员工
我们将使用 Python 和 OpenAI 格式的 API 来实现。
第一步:给 AI 装备“手脚” (Tools)
AI 本身只能输出文本,我们需要定义Function Calling,把它的文本指令变成系统操作。
importsubprocessimportos# 工具 1:执行终端命令defrun_command(command):"""在沙箱中执行 Shell 命令"""print(f"🖥️ 执行命令:{command}")result=subprocess.run(command,shell=True,capture_output=True,text=True)ifresult.returncode!=0:returnf"Error:{result.stderr}"returnresult.stdout# 工具 2:读取文件代码defread_file(filepath):"""读取指定文件的内容"""ifnotos.path.exists(filepath):return"Error: File not found"withopen(filepath,"r")asf:returnf.read()# 工具 3:修改文件代码 (覆盖写)defwrite_file(filepath,content):"""将代码写入文件"""print(f"📝 修改文件:{filepath}")withopen(filepath,"w")asf:f.write(content)return"Success"第二步:定义系统提示词 (System Prompt)
这是给 AI 的“入职培训”。我们要告诉它:你不是聊天机器人,你是一个工程师。
SYSTEM_PROMPT=""" 你是一个全栈 AI 工程师。你的目标是修复用户提供的代码 Bug。 你有以下工具可以使用: 1. run_command: 执行测试或运行脚本 2. read_file: 查看代码内容 3. write_file: 修改代码 工作流程: 1. 先运行代码或测试,查看报错信息。 2. 读取相关文件,分析代码逻辑。 3. 修改代码以修复 Bug。 4. 再次运行测试,确认修复成功。 5. 如果失败,重复上述步骤。 """第三步:构建 ReAct 循环 (The Loop)
这是 Agent 的心脏。它不断地将环境的反馈投喂给 LLM,直到问题解决。
fromopenaiimportOpenAIimportjson client=OpenAI(api_key="sk-...")defai_programmer(bug_report):messages=[{"role":"system","content":SYSTEM_PROMPT},{"role":"user","content":f"帮我修这个 Bug:{bug_report}"}]# 最大尝试 10 轮,防止死循环foriinrange(10):# 1. 呼叫大模型response=client.chat.completions.create(model="gpt-4o",messages=messages,tools=tools_schema,# 这里填入上面定义的工具描述tool_choice="auto")msg=response.choices[0].message messages.append(msg)# 2. 判断是否想调用工具ifmsg.tool_calls:fortool_callinmsg.tool_calls:func_name=tool_call.function.name args=json.loads(tool_call.function.arguments)# 3. 执行工具 (Action)iffunc_name=="run_command":output=run_command(args["command"])eliffunc_name=="read_file":output=read_file(args["filepath"])eliffunc_name=="write_file":output=write_file(args["filepath"],args["content"])# 4. 将工具结果返回给 AI (Observation)messages.append({"role":"tool","tool_call_id":tool_call.id,"content":output})else:# AI 没调用工具,说明它认为修完了,或者是想说话print(f"🤖 AI 说:{msg.content}")if"修复成功"inmsg.content:break🧪 现场演示:AI 能修好这个 Bug 吗?
假设目录下有一个math_util.py,里面有个除零错误:
# math_util.pydefdivide(a,b):returna/b# 隐患:没处理 b=0我们启动 Agent:ai_programmer("math_util.py 运行时报错 ZeroDivisionError")
Agent 的内心戏(日志流):
- Thinking: “我需要先复现报错。”
- Action:
run_command("python3 -c 'from math_util import divide; print(divide(10, 0))'") - Observation:
ZeroDivisionError: division by zero - Thinking: “确实报错了。我需要看看源代码。”
- Action:
read_file("math_util.py") - Observation: (读取了代码内容)
- Thinking: “原来是没判断 b 是否为 0。我来修复它。”
- Action:
write_file("math_util.py", ...)(写入了包含if b == 0的新代码) - Thinking: “修好了,我得验证一下。”
- Action:
run_command(...)(再次运行除零测试) - Observation:
None(或者打印了错误提示,不再抛异常) - Output: “修复成功!我已经添加了除零保护。”
成功!全过程无需人类干预。
🚀 进阶:如何让它更像 Devin?
上面的代码只是一个玩具。要达到 Devin 的级别,还需要做这三件事:
- Docker 隔离:
不要直接在宿主机运行subprocess!一定要连接 Docker API,在容器内执行命令。否则 AI 可能会执行rm -rf /把你的电脑洗白。 - RAG 记忆:
如果项目很大,AI 读不下所有代码。需要引入向量数据库(RAG),让 AI 能够“按需检索”相关的代码片段。 - LSP 集成:
集成Language Server Protocol,让 AI 能看到代码高亮、语法错误提示,而不是只看纯文本。
📝 结语
构建一个 AI 程序员,技术上已经没有秘密。
Prompt Engineering + Function Calling + Sandbox = Devin
未来,程序员的能力将不再是“写代码的速度”,而是**“设计 Agent 的能力”**。
与其担心被 Devin 替代,不如现在动手,养一只属于你自己的“电子奴隶”!