3d极速摩托苹果版
863.7M · 2025-09-12
从通义灵码、CodeBuddy等编程助手,到Cursor、Trae等AI编程IDE,再到Claude Code、Gemini Cli、Qwen Code等命令行工具,AI编程Agent这个赛道一直很热闹,那么这些AI Agent是如何实现的呢?这篇文章我来介绍一下我用Java实现出来的一个简单版的AI编程Agent,你可以理解为是一个简单版本的Qwen Code。
为什么用Java?其实我也用Python写了一版,也没别的原因,就想试试Java到底行不行...
首先介绍一下什么是ReAct,ReAct拆开就是Reason+Action,也就是思考+行动。为什么需要ReAct? 第一个原因是LLM只能输出文字,没有行动能力,比如不能创建文件、写文件、读文件,因此我们需要给LLM提供工具,让它有行动能力。 第二个原因是LLM不管是解决简单问题还是复杂问题,都是一次性给出答案,但实际情况是,对于复杂问题往往需要分阶段思考、分阶段行动会更好。
ReAct核心就是一个循环:
这个“思考-行动-观察”的循环不断重复,直到任务完成,有点抽象,我们来看具体代码。
首先看看配置,配置DASHSCOPE平台的API_KEY、BASE_URL和我们要使用的LLM。
/**
* 需要完整代码可以联系我,微信号:it_zhouyu
*/
public class ModelConfig {
public static final String API_KEY = System.getenv("DASHSCOPE_API_KEY");
public static final String BASE_URL = "<https://dashscope.aliyuncs.com/compatible-mode/v1>";
public static final String LLM_NAME = "qwen-plus";
}
然后定义Agent需要的工具,在AgentTools中可以定义多个工具,@Tool和@ToolParam都是我自己定义的,并没有用Spring AI。
/**
* 需要完整代码可以联系我,微信号:it_zhouyu
*/
public class AgentTools {
@Tool(description = "将指定内容写入本地文件。")
public String writeFile(@ToolParam(description = "包含 'file_path' 和 'content' 的 JSON 字符串。") String jsonInput) {
try {
JsonNode rootNode = objectMapper.readTree(jsonInput);
String filePath = rootNode.get("file_path").asText();
String content = rootNode.get("content").asText();
try (FileWriter writer = new FileWriter(filePath)) {
writer.write(content);
return String.format("成功将内容写入文件 '%s'。", filePath);
} catch (IOException e) {...}
} catch (Exception e) {...}
}
}
这里的关键是注解@Tool
和@ToolParam
:
ReAct中最核心的就是提示词,因为我们需要LLM能够按照我们需要的格式返回,然后我们再通过Java代码来按格式进行解析,比如解析出该调用哪个工具,也就是该调用AgentTools中的哪个方法,传什么参数,以下是我的提示词:
/**
* 需要完整代码可以联系我,微信号:it_zhouyu
*/
private static final String REACT_PROMPT_TEMPLATE = """
你是一个强大的 AI 助手,通过思考和使用工具来解决用户的问题。
你的任务是尽你所能回答以下问题。你可以使用以下工具:
{tools}
请严格遵循以下规则和格式:
1. 你的行动必须基于一个清晰的“Thought”过程。
2. 你必须按顺序使用 "Thought:", "Action:", "Action Input:"。
3. 在每次回复中,你只能生成 **一个** Thought/Action/Action Input 组合。
4. **绝对不要** 自己编造 "Observation:"。系统会在你执行动作后,将真实的结果作为 Observation 提供给你。
5. 当你拥有足够的信息来直接回答用户的问题时,请使用 "Final Answer:" 来输出最终答案。
6. 在每次回复中,"Thought:", "Action:", "Action Input:"和"Final Answer:"不能同时出现。
下面是你的思考和行动格式:
Thought: 我需要做什么来解决问题?下一步是什么?
Action: 我应该使用哪个工具?必须是 [{tool_names}] 中的一个。
Action Input: 我应该给这个工具提供什么输入?这必须是一个 JSON 对象。
--- 开始 ---
Question: {input}
{agent_scratchpad}
""";
其中:
这里重点讲一下第4点和第6点:
这块代码比较多,贴在文章里也不方便阅读,这里就只给出实现思路,大家想要完整代码可以加我微信领取,微信在文末。
最后将Agent组装起来就可以用了:
/**
* 需要完整代码可以联系我,微信号:it_zhouyu
*/
public class Main {
public static void main(String[] args) {
// 1. 初始化 API 客户端
OpenAIClient apiClient = ...;
// 2. 创建 AgentTools 实例
AgentTools agentTools = new AgentTools();
// 3. 创建 ReActAgent 实例
ReActAgent agent = new ReActAgent(apiClient, agentTools);
// 4. 定义问题并运行 Agent
String question = "请帮我用HTML、CSS、JS创建一个简单的贪吃蛇游戏,分成三个文件,分别是snake.html、snake.css、snake.js";
String finalResult = agent.run(question, 10);
// 5. 打印最终结果
System.out.println("AGENT 执行结束,最终结果为:");
System.out.println(finalResult);
}
}
以上就是我手写的简单版的Qwen Code Agent的核心思路,虽然还不能投入生产使用,但对于大家理解AI Agent核心原理、什么是ReAct、如何开发一个Agent应该都有帮助,希望能得到大家的点赞、分享、关注,最后给出我的联系方式,需要完整代码的可以加我微信号:it_zhouyu。