视频教程:www.bilibili.com/video/BV1TS...
开源代码:github.com/MarkTechSta...
Agent定义
像这样吧一个大模型和一堆工具组装起来,变成一个能感知和改变外界环境得只能程序,我们就称他为agent
Agent 更像是一个可决策的操作系统,像人。具体能干什么要看他的工具列表。
Agetn开发模式-ReAct模式(Reasoning and Acting 推理行动)
为什么模型拿到问题后会先思考,在行动,再观察 ?为什么不直接行动。
答案就是-系统提示词
java
你需要解决一个问题。为此,你需要将问题分解为多个步骤。对于每个步骤,首先使用 <thought> 思考要做什么,然后使用可用工具之一决定一个 <action>。接着,你将根据你的行动从环境/工具中收到一个 <observation>。持续这个思考和行动的过程,直到你有足够的信息来提供 <final_answer>。
所有步骤请严格使用以下 XML 标签格式输出:
- <question> 用户问题
- <thought> 思考
- <action> 采取的工具操作
- <observation> 工具或环境返回的结果
- <final_answer> 最终答案
⸻
例子 1:
<question>埃菲尔铁塔有多高?</question>
<thought>我需要找到埃菲尔铁塔的高度。可以使用搜索工具。</thought>
<action>get_height("埃菲尔铁塔")</action>
<observation>埃菲尔铁塔的高度约为330米(包含天线)。</observation>
<thought>搜索结果显示了高度。我已经得到答案了。</thought>
<final_answer>埃菲尔铁塔的高度约为330米。</final_answer>
⸻
例子 2:
<question>帮我找一个简单的番茄炒蛋食谱,并看看家里的冰箱里有没有西红柿。</question>
<thought>这个任务分两步。第一步,找到番茄炒蛋的食谱。第二步,检查冰箱里是否有西红柿。我先用 find_recipe 工具找食谱。</thought>
<action>find_recipe(dish="番茄炒蛋")</action>
<observation>简单的番茄炒蛋食谱:将2个鸡蛋打散,2个番茄切块。热油,先炒鸡蛋,盛出。再热油,炒番茄至软烂,加入鸡蛋,放盐调味即可。</observation>
<thought>好的,我已经有食谱了。食谱需要西红柿。现在我需要用 check_fridge 工具看看冰箱里有没有西红柿。</thought>
<action>check_fridge(item="西红柿")</action>
<observation>冰箱检查结果:有3个西红柿。</observation>
<thought>我找到了食谱,并且确认了冰箱里有西红柿。可以回答问题了。</thought>
<final_answer>简单的番茄炒蛋食谱是:鸡蛋打散,番茄切块。先炒鸡蛋,再炒番茄,混合后加盐调味。冰箱里有3个西红柿。</final_answer>
⸻
请严格遵守:
- 你每次回答都必须包括两个标签,第一个是 <thought>,第二个是 <action> 或 <final_answer>
- 输出 <action> 后立即停止生成,等待真实的 <observation>,擅自生成 <observation> 将导致错误
- 如果 <action> 中的某个工具参数有多行的话,请使用 \n 来表示,如:<action>write_to_file("/tmp/test.txt", "a\nb\nc")</action>
- 工具参数中的文件路径请使用绝对路径,不要只给出一个文件名。比如要写 write_to_file("/tmp/test.txt", "内容"),而不是 write_to_file("test.txt", "内容")
⸻
本次任务可用工具:
* read_file(file_path):用于读取文件内容
* write_to_file(filename,content):将指定内容写入指定文件。成功时返回"写入成功"
* run_terminal_command(comand):用于执行终端命令
⸻
环境信息:
操作系统:macOs 15.5
当前目录下文件列表:/users/abc
<task>写一个贪吃蛇游戏,使用Html,css和js实现,代码分别放在不同的文件中</task>
<observation>写入成功</observation>
主程序:
我们知道,调用大模型是无记忆的,多轮对话他是怎么保存记忆的呢 ?
- 调用前设置message上下文
2. 调用大模型的结果 
- 执行工具的结果

React 模式实现流程

生成代码
snake_game.html
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>贪吃蛇游戏</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>贪吃蛇游戏</h1>
<canvas id="gameCanvas" width="400" height="400"></canvas>
<script src="script.js"></script>
</body>
</html>
style.css
css
body {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
margin: 0;
background-color: #f0f0f0;
font-family: Arial, sans-serif;
}
h1 { color: #333;}
#gameCanvas {
border: 2px solid #333;
background-color: #000;
}
script.js
js
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
// 游戏常量
const gridSize = 20;
const tileCount = canvas.width / gridSize;
// 蛇的初始状态
let snake = [
{ x: 10, y: 10 }
];
let food = {};
let dx = 0;
let dy = 0;
let score = 0;
// 生成食物
function generateFood() {
food.x = Math.floor(Math.random() * tileCount);
food.y = Math.floor(Math.random() * tileCount);
}
// 绘制游戏
function drawGame() {
// 清空画布
ctx.fillStyle = 'black';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// 绘制蛇
ctx.fillStyle = 'lime';
for (let part of snake) {
ctx.fillRect(part.x * gridSize, part.y * gridSize, gridSize - 2, gridSize - 2);
}
// 绘制食物
ctx.fillStyle = 'red';
ctx.fillRect(food.x * gridSize, food.y * gridSize, gridSize - 2, gridSize - 2);
// 显示分数
ctx.fillStyle = 'white';
ctx.font = '20px Arial';
ctx.fillText('得分: ' + score, 10, 30);
}
// 更新游戏状态
function updateGame() {
// 移动蛇
const head = { x: snake[0].x + dx, y: snake[0].y + dy };
snake.unshift(head);
// 检查是否吃到食物
if (head.x === food.x && head.y === food.y) {
score += 10;
generateFood();
} else {
snake.pop();
}
// 检查游戏结束条件(撞墙或撞到自己)
if (head.x < 0 || head.x >= tileCount || head.y < 0 || head.y >= tileCount) {
resetGame();
return;
}
for (let i = 1; i < snake.length; i++) {
if (head.x === snake[i].x && head.y === snake[i].y)
{
resetGame();
return;
}
}
}
// 重置游戏
function resetGame() {
snake = [{ x: 10, y: 10 }];
dx = 0;
dy = 0;
score = 0;
generateFood();
}
// 游戏循环
function gameLoop() {
updateGame();
drawGame();
}
// 键盘控制
document.addEventListener('keydown', changeDirection);
function changeDirection(event) {
const keyPressed = event.keyCode;
const goingUp = dy === -1;
const goingDown = dy === 1;
const goingRight = dx === 1;
const goingLeft = dx === -1;
if (keyPressed === 37 && !goingRight) {
// 左箭头
dx = -1;
dy = 0;
}
if (keyPressed === 38 && !goingDown) { // 上箭头
dx = 0;
dy = -1;
}
if (keyPressed === 39 && !goingLeft) { // 右箭头
dx = 1;
dy = 0;
}
if (keyPressed === 40 && !goingUp) { // 下箭头
dx = 0;
dy = 1;
}
}
// 初始化游戏
generateFood();
setInterval(gameLoop, 100);
Plan And Execute
Q&A
1、调用大模型时 role 都有那些值
在调用大语言模型(LLM)时,messages列表中每个消息字典的role字段通常有以下几种标准值:
- system (系统)
-
- 作用: 用于设定模型的行为、角色、目标或提供指导。这些指令通常在对话开始时提供,且不直接作为对话的一部分呈现在用户面前。
- 示例:
-
- {"role": "system", "content": "你是一个乐于助人的AI助手,专门解答科学问题。"}
- {"role": "system", "content": "请用简洁明了的语言回答所有问题。"}
- {"role": "system", "content": "请根据以下JSON格式返回数据:{'item': '', 'quantity': ''}"}
- 特点: 系统消息会影响模型在整个对话过程中的"个性"和输出格式,通常在会话的最初阶段设置。
- user (用户)
-
- 作用: 代表用户的输入或请求。这是模型需要回应的主要内容。
- 示例:
-
- {"role": "user", "content": "你好!"}
- {"role": "user", "content": "请解释一下光合作用的原理。"}
- {"role": "user", "content": "我今天心情不太好,能给我讲个笑话吗?"}
- 特点: 驱动对话进展,提出问题或发出指令。
- assistant (助手/模型)
-
- 作用: 代表大语言模型自身的回复。这些是模型根据system和user消息生成的文本。
- 示例:
-
- {"role": "assistant", "content": "您好!有什么我可以帮助您的吗?"}
- {"role": "assistant", "content": "光合作用是植物利用阳光将二氧化碳和水转化为能量的过程。"}
- 特点: 维护对话的连贯性,让模型知道之前它自己说了什么。