实现一个简易的代码AI Agent

从零实现AI Agent

Agent的核心是ReAct循环:思考(Thought)→ 行动(Action)→ 观察(Observation)→ 思考...

1.系统提示模板

js 复制代码
export const react_system_prompt_template = `
你需要解决一个问题。为此,你需要将问题分解为多个步骤。对于每个步骤,首先使用 <thought> 思考要做什么,然后使用可用工具之一决定一个 <action>。接着,你将根据你的行动从环境/工具中收到一个 <observation>。持续这个思考和行动的过程,直到你有足够的信息来提供 <final_answer>。

所有步骤请严格使用以下 XML 标签格式输出:
- <question> 用户问题
- <thought> 思考
- <action> 采取的工具操作
- <observation> 工具或环境返回的结果
- <final_answer> 最终答案

请严格遵守:
- 你每次回答都必须包括两个标签,第一个是 <thought>,第二个是 <action> 或 <final_answer>
- 输出 <action> 后立即停止生成,等待真实的 <observation>
- 工具参数中的文件路径请使用绝对路径

本次任务可用工具:
\${tool_list}

环境信息:
操作系统:\${operating_system}
当前目录下文件列表:\${file_list}
`;

2.定义工具(tools)和agent对象

js 复制代码
const tools = [readFile, writeToFile];
const agent = new ReActAgent(tools, "Qwen/Qwen3-Coder-480B-A35B-Instruct", projectDir);
//调用方法返回结果
agent.run('问题xxxxxx');

// 读取工具实现
async function readFile(filePath) {
        const content = await fs.promises.readFile(filePath, 'utf8');
        return content;
}

async function writeToFile(filePath, content) {
        await fs.promises.writeFile(filePath, content.replace(/\\n/g, '\n'), 'utf8');
        return "写入成功";
}

3.实现agent对象核心方法

js 复制代码
//实现run方法
 async run(userInput) {
        const messages = [
            { role: "system", content: this.renderSystemPrompt(react_system_prompt_template) },
            { role: "user", content: `<question>${userInput}</question>` }
        ];
     
		//循环逻辑
        while (true) {
            const content = await this.callModel(messages);

            const thoughtMatch = content.match(/<thought>(.*?)<\/thought>/s);
            
            //最终退出返回结果逻辑
            if (content.includes("<final_answer>")) {
                const finalAnswer = content.match(/<final_answer>(.*?)<\/final_answer>/s);
                return finalAnswer[1];
            }
         
            const actionMatch = content.match(/<action>(.*?)<\/action>/s);
            
            //调用工具逻辑
            const action = actionMatch[1];
            //通过解析返回内容得到工具名和参数
            const [toolName, args] = this.parseAction(action);
            
			//tools方法调用
            try {
                const observation = await this.tools[toolName](...args);
                messages.push({ role: "user", content: `<observation>${observation}</observation>` });
            } catch (error) {
                const observation = `工具执行错误:${error.message}`;
                messages.push({ role: "user", content: `<observation>${observation}</observation>` });
            }
        }
    }

代码地址:github.com/chengqy0106...

相关推荐
答案answer12 小时前
three.js着色器(Shader)实现数字孪生项目中常见的特效
前端·three.js
城管不管12 小时前
SpringBoot与反射
java·开发语言·前端
JackJiang12 小时前
即时通讯安全篇(三):一文读懂常用加解密算法与网络通讯安全
前端
一直_在路上12 小时前
Go架构师实战:玩转缓存,击破医疗IT百万QPS与“三大天灾
前端·面试
早八睡不醒午觉睡不够的程序猿13 小时前
Vue DevTools 调试提示
前端·javascript·vue.js
恋猫de小郭13 小时前
基于 Dart 的 Terminal UI ,pixel_prompt 这个 TUI 库了解下
android·前端·flutter
天天向上102413 小时前
vue el-form 自定义校验, 校验用户名调接口查重
前端·javascript·vue.js
忧郁的蛋~13 小时前
前端实现网页水印防移除的实战方案
前端
喝奶茶的Blair13 小时前
PHP应用-组件框架&前端模版渲染&三方插件&富文本编辑器&CVE审计(2024小迪安全DAY30笔记)
前端·安全·php
浪潮行舟13 小时前
WebGIS:在 Vue 2 项目中使用 Mapbox 时,如果需要加载的 GIS 数据量过大,怎么让接口一次性获取的geojson数据分批加载
前端·javascript·vue.js