Agent 认知+ReAct模式

视频教程:www.bilibili.com/video/BV1TS...

开源代码:github.com/MarkTechSta...

Agent定义

像这样吧一个大模型和一堆工具组装起来,变成一个能感知和改变外界环境得只能程序,我们就称他为agent Agent 更像是一个可决策的操作系统,像人。具体能干什么要看他的工具列表。

Agetn开发模式-ReAct模式(Reasoning and Acting 推理行动)

为什么模型拿到问题后会先思考,在行动,再观察 ?为什么不直接行动。

答案就是-系统提示词

github.com/MarkTechSta...

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>

主程序:

github.com/MarkTechSta...

我们知道,调用大模型是无记忆的,多轮对话他是怎么保存记忆的呢 ?

  1. 调用前设置message上下文

2. 调用大模型的结果

  1. 执行工具的结果

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字段通常有以下几种标准值:

  1. system (系统)
    • 作用: 用于设定模型的行为、角色、目标或提供指导。这些指令通常在对话开始时提供,且不直接作为对话的一部分呈现在用户面前。
    • 示例:
      • {"role": "system", "content": "你是一个乐于助人的AI助手,专门解答科学问题。"}
      • {"role": "system", "content": "请用简洁明了的语言回答所有问题。"}
      • {"role": "system", "content": "请根据以下JSON格式返回数据:{'item': '', 'quantity': ''}"}
    • 特点: 系统消息会影响模型在整个对话过程中的"个性"和输出格式,通常在会话的最初阶段设置。
  2. user (用户)
    • 作用: 代表用户的输入或请求。这是模型需要回应的主要内容。
    • 示例:
      • {"role": "user", "content": "你好!"}
      • {"role": "user", "content": "请解释一下光合作用的原理。"}
      • {"role": "user", "content": "我今天心情不太好,能给我讲个笑话吗?"}
    • 特点: 驱动对话进展,提出问题或发出指令。
  3. assistant (助手/模型)
    • 作用: 代表大语言模型自身的回复。这些是模型根据system和user消息生成的文本。
    • 示例:
      • {"role": "assistant", "content": "您好!有什么我可以帮助您的吗?"}
      • {"role": "assistant", "content": "光合作用是植物利用阳光将二氧化碳和水转化为能量的过程。"}
    • 特点: 维护对话的连贯性,让模型知道之前它自己说了什么。

2、如何影响Agent的规划

相关推荐
申阳4 小时前
Day 5:03. 基于Nuxt开发博客项目-页面结构组织
前端·后端·程序员
用户298698530144 小时前
C#: 高效移动与删除Excel工作表
后端·.net·excel
guchen664 小时前
记录一次Prism9隐式注册引发的事件聚合器失效问题
后端
一行•坚书4 小时前
kafka服务端与客户端如何协作?生产者发送消息分区策略是什么?消费者组分区策略?集群与ACK机制?
java·后端·kafka
天天摸鱼的java工程师4 小时前
干掉系统卡顿!Excel异步导出完整实战方案(百万数据也不慌)
java·后端
星释5 小时前
Rust 练习册 4:Deref trait 与智能指针
开发语言·后端·rust
Cache技术分享5 小时前
231. Java 集合 - 将集合元素转换为数组
前端·后端
小码编匠5 小时前
WPF 绘制图表合集-LiveCharts
后端·c#·.net
codervibe5 小时前
MySQL 命令行连接与企业级远程访问实践(含故障排查与安全策略)
数据库·后端