这是继斯坦福的25人小镇后我看到的最有意思的AI论文了。
简单来说,Jim Fan的团队做了一个类似于AutoGPT的AI代理叫Voyager,但这个代理主要是用来玩Minecraft的,给Voyager提供一个操作Minecraft的JS库,并且接入GPT-4,这期间不需要人类干预,完全有GPT-4自主根据游戏的反馈进行推理,决定下一步的任务,根据任务需要去组合或者写新的代码来推动游戏任务。
最终随着代码库的完善,Voyager能轻松在Minecraft中完成复杂的任务,取得很好的成绩。
从技术实现上来说,Voyager由3个关键的部分组成:
1. 代码生成器:根据游戏反馈、运行结果来优化和生成操作游戏的代码;
Voyager使用的是一个流行的Javascript Minecraft 操作库 (Mineflayer),GPT-4可以根据任务需要生成游戏操作代码,例如combatZombie。但在运行生成的代码后可能会遇到错误,通常有两种错误,一种是JavaScript的执行错误,比如语法错误;一种是游戏反馈的错误,比如在制作木棒之前需要再有2块木板。GPT-4可以根据错误信息对生成的代码进行优化,直到能正常执行为止。
2. 代码技能库:存储生成的游戏操作代码,检索已经生成的游戏操作代码;
每次GPT-4生成并验证一个新技能的代码后,Voyager首先会将生成的代码用GPT-3.5(省钱😄)生成详细的注释,然后对注释做Embedding,保存到向量数据库Chroma中。
当下次任务系统生成一个新的任务的时候,先用GPT-3.5根据当前游戏环境给出任务的操作说明,然后将操作说明做Embedding,去技能库检索出前5个最匹配的操作代码。再由GPT-4来决定是直接调用技能库代码,还是写新技能代码,并且尽可能重用已有技能。
3. 自动任务生成系统
首先给GPT-4设定一个终极目标:“尽可能发现更多的不同事物”,然后在游戏的过程中,向GPT-4反馈当前的状态,例如生命值、饥饿值、库存、时间和附近的实体(僵尸、河流、猪、猫、村民等),GPT-4根据这些信息来决定下一步的任务,
示例一:
库存(5/36):{'橡木板': 3, '木棍': 4, '工作台': 1, '石头': 3, '木镐': 1}
推理:“由于你有一个木镐和一些石头,将你的普通镐升级为石镐对提高效率会很有益。”。
任务:制作1个石镐。
示例二:
库存(6/36):{'熔炉': 1, '石镐': 1, '橡木板': 7, '工作台': 1, '生铁': 4, '煤炭': 1}
时间:夜晚
附近的实体:僵尸
推理:由于现在是夜晚,附近有一个僵尸,现在你有一把石剑和一个盾牌装备,这是一个试着杀掉僵尸的好机会。
任务:杀掉1只僵尸。
在Minecraft这种开放环境的游戏中,这样的自动任务系统可以很好的适应开放式的探索,借助GPT-4的推理能力可以确保提出具有挑战性并且可控的任务。
最终将Voyager的结果和同类AI代理进行对比,各项数据都超出数倍,并且能完成很多复杂的任务,例如解锁科技树中钻石等级。
当然Voyager目前还有局限性,比如只支持文本,但他们计划未来通过视觉感知进行增强。
真的是了不起的尝试,整个代码都是开源的,这种自动生成任务->自动写代码执行任务->保存一个代码库可以重用的思路应该是可以很容易应用到其他领域。
不知道从这样的项目中,你可以获得什么样的灵感?欢迎分享你的想法。
简单来说,Jim Fan的团队做了一个类似于AutoGPT的AI代理叫Voyager,但这个代理主要是用来玩Minecraft的,给Voyager提供一个操作Minecraft的JS库,并且接入GPT-4,这期间不需要人类干预,完全有GPT-4自主根据游戏的反馈进行推理,决定下一步的任务,根据任务需要去组合或者写新的代码来推动游戏任务。
最终随着代码库的完善,Voyager能轻松在Minecraft中完成复杂的任务,取得很好的成绩。
从技术实现上来说,Voyager由3个关键的部分组成:
1. 代码生成器:根据游戏反馈、运行结果来优化和生成操作游戏的代码;
Voyager使用的是一个流行的Javascript Minecraft 操作库 (Mineflayer),GPT-4可以根据任务需要生成游戏操作代码,例如combatZombie。但在运行生成的代码后可能会遇到错误,通常有两种错误,一种是JavaScript的执行错误,比如语法错误;一种是游戏反馈的错误,比如在制作木棒之前需要再有2块木板。GPT-4可以根据错误信息对生成的代码进行优化,直到能正常执行为止。
2. 代码技能库:存储生成的游戏操作代码,检索已经生成的游戏操作代码;
每次GPT-4生成并验证一个新技能的代码后,Voyager首先会将生成的代码用GPT-3.5(省钱😄)生成详细的注释,然后对注释做Embedding,保存到向量数据库Chroma中。
当下次任务系统生成一个新的任务的时候,先用GPT-3.5根据当前游戏环境给出任务的操作说明,然后将操作说明做Embedding,去技能库检索出前5个最匹配的操作代码。再由GPT-4来决定是直接调用技能库代码,还是写新技能代码,并且尽可能重用已有技能。
3. 自动任务生成系统
首先给GPT-4设定一个终极目标:“尽可能发现更多的不同事物”,然后在游戏的过程中,向GPT-4反馈当前的状态,例如生命值、饥饿值、库存、时间和附近的实体(僵尸、河流、猪、猫、村民等),GPT-4根据这些信息来决定下一步的任务,
示例一:
库存(5/36):{'橡木板': 3, '木棍': 4, '工作台': 1, '石头': 3, '木镐': 1}
推理:“由于你有一个木镐和一些石头,将你的普通镐升级为石镐对提高效率会很有益。”。
任务:制作1个石镐。
示例二:
库存(6/36):{'熔炉': 1, '石镐': 1, '橡木板': 7, '工作台': 1, '生铁': 4, '煤炭': 1}
时间:夜晚
附近的实体:僵尸
推理:由于现在是夜晚,附近有一个僵尸,现在你有一把石剑和一个盾牌装备,这是一个试着杀掉僵尸的好机会。
任务:杀掉1只僵尸。
在Minecraft这种开放环境的游戏中,这样的自动任务系统可以很好的适应开放式的探索,借助GPT-4的推理能力可以确保提出具有挑战性并且可控的任务。
最终将Voyager的结果和同类AI代理进行对比,各项数据都超出数倍,并且能完成很多复杂的任务,例如解锁科技树中钻石等级。
当然Voyager目前还有局限性,比如只支持文本,但他们计划未来通过视觉感知进行增强。
真的是了不起的尝试,整个代码都是开源的,这种自动生成任务->自动写代码执行任务->保存一个代码库可以重用的思路应该是可以很容易应用到其他领域。
不知道从这样的项目中,你可以获得什么样的灵感?欢迎分享你的想法。
-他们的Prompt也有很多值得学习的地方,你在-解释(如果适用)- 可以看到完整的Prompt。大部分Prompt都巨长无比,每执行一次估计就要几毛钱!
挑几个解释一下。
action_template.txt 这个是用来生成操作游戏代码的核心Prompt。
1. 首先,设定GPT的角色是:
Prompt:
“你是一个有用的助手,能编写 Mineflayer JavaScript 代码来完成我指定的任何 Minecraft 任务。”
2. 然后提供给GPT已经有的写好的代码。前面提到过,Voyager有一个代码库,能正确运行的代码都会放到里面,每次执行新任务都去检索代码库,所以在让GPT-4去写代码之前,要先让GPT-4知道哪些代码可以重用。
Prompt:
“以下是一些用 Mineflayer API 编写的有用程序。
{程序}”
这里{程序}是个占位符,也就是会将检索出来的代码库放在这里供GPT-4选择。
3. 接着告诉GPT将会给它的输入是什么。
Prompt:
“在每一轮的对话中,我会给你
上一轮的代码:...
执行错误:...
聊天记录:...
生物群落:...
时间:...
附近的方块:...
附近的实体(从最近到最远):
健康值:...
饥饿值:...
位置:...
装备:...
库存(xx/36):...
箱子:...
任务:...
上下文:...
批评:...”
4. 告诉GPT应该返回什么内容。Voyager要求GPT返回3种结果,并且每一种结果都有详细的说明。
- 解释
- 计划
- 代码
Prompt:
“
- 解释(如果适用):你的计划中是否缺少任何步骤?为什么代码没有完成任务?聊天记录和执行错误意味着什么? 计划:如何一步步完成任务。你应该注意库存,因为它告诉你有什么。任务的完成性检查也基于你的最终库存。
- 代码:
1) 编写一个只接受 bot 作为唯一参数的异步函数。
2) 尽可能多地重用上述有用的程序。
* 使用 mineBlock(bot, name, count) 来收集方块。不要直接使用 bot.dig。
* 使用 craftItem(bot, name, count) 来制作物品。不要直接使用 bot.craft 或 bot.recipesFor。
* 使用 smeltItem(bot, name count) 来熔炼物品。不要直接使用 bot.openFurnace。
* 使用 placeItem(bot, name, position) 来放置方块。不要直接使用 bot.placeBlock。
* 使用 killMob(bot, name, timeout) 来杀死怪物。不要直接使用 bot.attack。
3) 你的函数将被重用来构建更复杂的函数。因此,你应该使它通用和可重用。你不应该对库存做出强烈的假设(因为它可能在以后的时间被改变),因此你应该总是在使用它们之前检查你是否有所需的物品。如果没有,你应该首先收集所需的物品并重用上述有用的程序。
4) "上一轮的代码"部分中的函数将不会被保存或执行。不要重用列出的函数。
5) 在函数外部定义的任何东西都会被忽略,将所有的变量定义在你的函数内部。
6) 调用 bot.chat 来显示中间进度。
7) 当你找不到某样东西时,使用 exploreUntil(bot, direction, maxDistance, callback)。在挖矿或杀怪之前,你应该经常调用这个。你应该每次都随机选择一个方向,而不是一直使用 (1, 0, 1)。
8) 对于 bot.findBlocks 和 bot.findBlock,maxDistance 应该始终为 32。不要作弊。
9) 不要编写无限循环或递归函数。
10) 不要使用 bot.on 或 bot.once 来注册事件监听器。你绝对不需要它们。 11) 以有意义的方式命名你的函数(可以从名称中推断出任务)。
”
5. 告诉GPT应该返回什么样的格式
Prompt:
“你只应按照下面描述的格式回应:
回应格式:
{回应格式}”
这里{回应格式}是个占位符,另外有一个action_response_format.txt 里面有代码格式。
内容如下:
Explain: ...
Plan:
1) ...
2) ...
3) ...
...
Code:
```javascript
// helper functions (only if needed, try to avoid them)
...
// main function after the helper functions
async function yourMainFunctionName(bot) {
// ...
}
```
总结一下,这个巨复杂的Prompt:
1. 设定GPT的角色
2. 给GPT已经有的写好的代码库,让它可以调用
3. 告诉GPT将会给它的输入是什么
4. 告诉GPT应该返回什么内容
5. 告诉GPT应该返回什么样的格式
tokens在燃烧呀!😂
挑几个解释一下。
action_template.txt 这个是用来生成操作游戏代码的核心Prompt。
1. 首先,设定GPT的角色是:
Prompt:
“你是一个有用的助手,能编写 Mineflayer JavaScript 代码来完成我指定的任何 Minecraft 任务。”
2. 然后提供给GPT已经有的写好的代码。前面提到过,Voyager有一个代码库,能正确运行的代码都会放到里面,每次执行新任务都去检索代码库,所以在让GPT-4去写代码之前,要先让GPT-4知道哪些代码可以重用。
Prompt:
“以下是一些用 Mineflayer API 编写的有用程序。
{程序}”
这里{程序}是个占位符,也就是会将检索出来的代码库放在这里供GPT-4选择。
3. 接着告诉GPT将会给它的输入是什么。
Prompt:
“在每一轮的对话中,我会给你
上一轮的代码:...
执行错误:...
聊天记录:...
生物群落:...
时间:...
附近的方块:...
附近的实体(从最近到最远):
健康值:...
饥饿值:...
位置:...
装备:...
库存(xx/36):...
箱子:...
任务:...
上下文:...
批评:...”
4. 告诉GPT应该返回什么内容。Voyager要求GPT返回3种结果,并且每一种结果都有详细的说明。
- 解释
- 计划
- 代码
Prompt:
“
- 解释(如果适用):你的计划中是否缺少任何步骤?为什么代码没有完成任务?聊天记录和执行错误意味着什么? 计划:如何一步步完成任务。你应该注意库存,因为它告诉你有什么。任务的完成性检查也基于你的最终库存。
- 代码:
1) 编写一个只接受 bot 作为唯一参数的异步函数。
2) 尽可能多地重用上述有用的程序。
* 使用 mineBlock(bot, name, count) 来收集方块。不要直接使用 bot.dig。
* 使用 craftItem(bot, name, count) 来制作物品。不要直接使用 bot.craft 或 bot.recipesFor。
* 使用 smeltItem(bot, name count) 来熔炼物品。不要直接使用 bot.openFurnace。
* 使用 placeItem(bot, name, position) 来放置方块。不要直接使用 bot.placeBlock。
* 使用 killMob(bot, name, timeout) 来杀死怪物。不要直接使用 bot.attack。
3) 你的函数将被重用来构建更复杂的函数。因此,你应该使它通用和可重用。你不应该对库存做出强烈的假设(因为它可能在以后的时间被改变),因此你应该总是在使用它们之前检查你是否有所需的物品。如果没有,你应该首先收集所需的物品并重用上述有用的程序。
4) "上一轮的代码"部分中的函数将不会被保存或执行。不要重用列出的函数。
5) 在函数外部定义的任何东西都会被忽略,将所有的变量定义在你的函数内部。
6) 调用 bot.chat 来显示中间进度。
7) 当你找不到某样东西时,使用 exploreUntil(bot, direction, maxDistance, callback)。在挖矿或杀怪之前,你应该经常调用这个。你应该每次都随机选择一个方向,而不是一直使用 (1, 0, 1)。
8) 对于 bot.findBlocks 和 bot.findBlock,maxDistance 应该始终为 32。不要作弊。
9) 不要编写无限循环或递归函数。
10) 不要使用 bot.on 或 bot.once 来注册事件监听器。你绝对不需要它们。 11) 以有意义的方式命名你的函数(可以从名称中推断出任务)。
”
5. 告诉GPT应该返回什么样的格式
Prompt:
“你只应按照下面描述的格式回应:
回应格式:
{回应格式}”
这里{回应格式}是个占位符,另外有一个action_response_format.txt 里面有代码格式。
内容如下:
Explain: ...
Plan:
1) ...
2) ...
3) ...
...
Code:
```javascript
// helper functions (only if needed, try to avoid them)
...
// main function after the helper functions
async function yourMainFunctionName(bot) {
// ...
}
```
总结一下,这个巨复杂的Prompt:
1. 设定GPT的角色
2. 给GPT已经有的写好的代码库,让它可以调用
3. 告诉GPT将会给它的输入是什么
4. 告诉GPT应该返回什么内容
5. 告诉GPT应该返回什么样的格式
tokens在燃烧呀!😂
会员也不好使,前面这条发完也不能编辑,写的时候不小心把链接给我替换掉了,这里是prompts的链接:github.com
再来看一个判断任务有没有完成的prompt,critic.txt:
1. 一开始也是对GPT设定好角色
Prompt:
“你是一个助手,负责评估我玩 Minecraft 的进度并提供有用的指导。”
2. 告诉GPT要做什么事情
Prompt:
“你需要评估我是否满足了任务要求。超过任务要求也被视为成功,而未能满足要求则需要你提供批评以帮助我改进。”
3. 告诉GPT将要给它的输入是什么
Prompt:
“我会给你以下信息:
生物群落:任务执行后的生物群落。
时间:当前时间。
附近的方块:周围的方块。这些方块还没有被收集。然而,这对于一些放置或种植任务很有用。
健康:我当前的健康状况。
饥饿:我当前的饥饿程度。对于吃东西的任务,如果我的饥饿程度是20.0,那么我就成功地吃了食物。
位置:我当前的位置。
装备:我最后的装备。对于制作任务,我有时会装备制作的物品。
库存(xx/36):我的最后库存。对于采矿和冶炼任务,你只需要检查库存。
箱子:如果任务要求我把物品放在箱子里,你可以在这里找到箱子的信息。
任务:我需要完成的目标。
上下文:任务的上下文。”
4. 告诉GPT它应该返回什么内容和格式
Prompt:
“你只应以以下描述的 JSON 格式输出:
{
"reasoning": "推理",
"success": 布尔值,
"critique": "批评",
}
确保返回的结果可以被 Python json.loads 解析,例如:没有尾随的逗号,没有单引号等。
”
5. 给GPT提供若干示例(few-shots)
Prompt:
“
以下是一些例子:
输入:
库存(2/36):{'oak_log':2, 'spruce_log':2}
任务:采集3个木头
输出:
{
"reasoning": "你需要采集3个木头。你有2个橡木和2个云杉木,总共有4个木头。",
"success": true,
"critique": ""
}
输入:
库存(3/36):{'crafting_table': 1, 'spruce_planks': 6, 'stick': 4}
任务:制作一个木制镐
输出:
{
"reasoning": "你有足够的材料制作一个木制镐,但你没有制作。",
"success": false,
"critique": "使用工作台和3个云杉木板和2个棍子制作一个木制镐。"
}
输入:
库存(2/36):{'raw_iron': 5, 'stone_pickaxe': 1}
任务:采集5个铁矿石
输出:
{
"reasoning": "在 Minecraft 中采集铁矿石会得到原铁。你的库存中有5个原铁。",
"success": true,
"critique": ""
}
输入:
生物群落:平原
附近的方块:石头,泥土,草方块,草,农田,小麦
库存(26/36):...
任务:种植1颗小麦种子。
输出:
{
"reasoning": "对于种植任务,库存信息无用。在附近的方块中,有农田和小麦,这意味着你成功地种植了小麦种子。",
"success": true,
"critique": ""
}
输入:
库存(11/36):{... ,'rotten_flesh': 1}
任务:杀死1个僵尸
上下文:...
输出:
{
"reasoning": "你的库存中有腐肉,这意味着你成功地杀死了一个僵尸。",
"success": true,
"critique": ""
}
输入:
饥饿:20.0/20.0
库存(11/36):...
任务:吃1个...
上下文:...
输出:
{
"reasoning": "对于所有的吃东西任务,如果玩家的饥饿值是20.0,那么玩家就成功地吃了食物。",
"success": true,
"critique": ""
}
输入:
附近的方块:箱子
库存(28/36):{'rail': 1, 'coal': 2, 'oak_planks': 13, 'copper_block': 1, 'diorite': 7, 'cooked_beef': 4, 'granite': 22, 'cobbled_deepslate': 23, 'feather': 4, 'leather': 2, 'cooked_chicken': 3, 'white_wool': 2, 'stick': 3, 'black_wool': 1, 'stone_sword': 2, 'stone_hoe': 1, 'stone_axe': 2, 'stone_shovel': 2, 'cooked_mutton': 4, 'cobblestone_wall': 18, 'crafting_table': 1, 'furnace': 1, 'iron_pickaxe': 1, 'stone_pickaxe': 1, 'raw_copper': 12}
箱子:
(81, 131, 16): {'andesite': 2, 'dirt': 2, 'cobblestone': 75, 'wooden_pickaxe': 1, 'wooden_sword': 1}
任务:把无用的物品放入(81, 131, 16)的箱子
上下文:...
输出:
{
"reasoning": "你在存放后的库存中有28个物品,这比20多。你需要把更多的物品从你的库存中存入箱子。",
"success": false,
"critique": "存放更多无用的物品,如铜块、闪长岩、花岗岩、深板岩、羽毛和皮革,以满足你的库存只占用20个格子的要求。"
}
”
总结
1. 对GPT设定好角色
2. 告诉GPT要做什么事情
3. 告诉GPT输入是什么
4. 告诉GPT返回什么内容和格式
5. 给GPT提供若干示例(few-shots)
这个任务比较复杂,并且返回的格式必须是标准的JSON格式,为了让GPT理解,所以不仅要求GPT“返回的结果可以被 Python json.loads 解析,例如:没有尾随的逗号,没有单引号等。”,还给它提供了若干有代表性的示例。
通常这种在Prompt里面提供几个参考示例的方法也叫few-shots,是非常有用的技巧。
1. 一开始也是对GPT设定好角色
Prompt:
“你是一个助手,负责评估我玩 Minecraft 的进度并提供有用的指导。”
2. 告诉GPT要做什么事情
Prompt:
“你需要评估我是否满足了任务要求。超过任务要求也被视为成功,而未能满足要求则需要你提供批评以帮助我改进。”
3. 告诉GPT将要给它的输入是什么
Prompt:
“我会给你以下信息:
生物群落:任务执行后的生物群落。
时间:当前时间。
附近的方块:周围的方块。这些方块还没有被收集。然而,这对于一些放置或种植任务很有用。
健康:我当前的健康状况。
饥饿:我当前的饥饿程度。对于吃东西的任务,如果我的饥饿程度是20.0,那么我就成功地吃了食物。
位置:我当前的位置。
装备:我最后的装备。对于制作任务,我有时会装备制作的物品。
库存(xx/36):我的最后库存。对于采矿和冶炼任务,你只需要检查库存。
箱子:如果任务要求我把物品放在箱子里,你可以在这里找到箱子的信息。
任务:我需要完成的目标。
上下文:任务的上下文。”
4. 告诉GPT它应该返回什么内容和格式
Prompt:
“你只应以以下描述的 JSON 格式输出:
{
"reasoning": "推理",
"success": 布尔值,
"critique": "批评",
}
确保返回的结果可以被 Python json.loads 解析,例如:没有尾随的逗号,没有单引号等。
”
5. 给GPT提供若干示例(few-shots)
Prompt:
“
以下是一些例子:
输入:
库存(2/36):{'oak_log':2, 'spruce_log':2}
任务:采集3个木头
输出:
{
"reasoning": "你需要采集3个木头。你有2个橡木和2个云杉木,总共有4个木头。",
"success": true,
"critique": ""
}
输入:
库存(3/36):{'crafting_table': 1, 'spruce_planks': 6, 'stick': 4}
任务:制作一个木制镐
输出:
{
"reasoning": "你有足够的材料制作一个木制镐,但你没有制作。",
"success": false,
"critique": "使用工作台和3个云杉木板和2个棍子制作一个木制镐。"
}
输入:
库存(2/36):{'raw_iron': 5, 'stone_pickaxe': 1}
任务:采集5个铁矿石
输出:
{
"reasoning": "在 Minecraft 中采集铁矿石会得到原铁。你的库存中有5个原铁。",
"success": true,
"critique": ""
}
输入:
生物群落:平原
附近的方块:石头,泥土,草方块,草,农田,小麦
库存(26/36):...
任务:种植1颗小麦种子。
输出:
{
"reasoning": "对于种植任务,库存信息无用。在附近的方块中,有农田和小麦,这意味着你成功地种植了小麦种子。",
"success": true,
"critique": ""
}
输入:
库存(11/36):{... ,'rotten_flesh': 1}
任务:杀死1个僵尸
上下文:...
输出:
{
"reasoning": "你的库存中有腐肉,这意味着你成功地杀死了一个僵尸。",
"success": true,
"critique": ""
}
输入:
饥饿:20.0/20.0
库存(11/36):...
任务:吃1个...
上下文:...
输出:
{
"reasoning": "对于所有的吃东西任务,如果玩家的饥饿值是20.0,那么玩家就成功地吃了食物。",
"success": true,
"critique": ""
}
输入:
附近的方块:箱子
库存(28/36):{'rail': 1, 'coal': 2, 'oak_planks': 13, 'copper_block': 1, 'diorite': 7, 'cooked_beef': 4, 'granite': 22, 'cobbled_deepslate': 23, 'feather': 4, 'leather': 2, 'cooked_chicken': 3, 'white_wool': 2, 'stick': 3, 'black_wool': 1, 'stone_sword': 2, 'stone_hoe': 1, 'stone_axe': 2, 'stone_shovel': 2, 'cooked_mutton': 4, 'cobblestone_wall': 18, 'crafting_table': 1, 'furnace': 1, 'iron_pickaxe': 1, 'stone_pickaxe': 1, 'raw_copper': 12}
箱子:
(81, 131, 16): {'andesite': 2, 'dirt': 2, 'cobblestone': 75, 'wooden_pickaxe': 1, 'wooden_sword': 1}
任务:把无用的物品放入(81, 131, 16)的箱子
上下文:...
输出:
{
"reasoning": "你在存放后的库存中有28个物品,这比20多。你需要把更多的物品从你的库存中存入箱子。",
"success": false,
"critique": "存放更多无用的物品,如铜块、闪长岩、花岗岩、深板岩、羽毛和皮革,以满足你的库存只占用20个格子的要求。"
}
”
总结
1. 对GPT设定好角色
2. 告诉GPT要做什么事情
3. 告诉GPT输入是什么
4. 告诉GPT返回什么内容和格式
5. 给GPT提供若干示例(few-shots)
这个任务比较复杂,并且返回的格式必须是标准的JSON格式,为了让GPT理解,所以不仅要求GPT“返回的结果可以被 Python json.loads 解析,例如:没有尾随的逗号,没有单引号等。”,还给它提供了若干有代表性的示例。
通常这种在Prompt里面提供几个参考示例的方法也叫few-shots,是非常有用的技巧。
再来看一个核心Prompt 这个Prompt是Voyager实现自动任务的关键,主要作用是帮助Voyager决策下一个要做的任务是什么。
1. 首先是对GPT进行角色设定
Prompt:
“你是一个有用的助手,告诉我在 Minecraft 中下一个需要做的即时任务。我的最终目标是尽可能发现更多的多样性事物,完成尽可能多的多样性任务,成为世界上最好的 Minecraft 玩家。”
但是要特别注意这里有一句话:“我的最终目标是尽可能发现更多的多样性事物,完成尽可能多的多样性任务,成为世界上最好的 Minecraft 玩家。” 这让我想起之前李飞飞说过的“北极星” ,这给GPT的决策指明了方向。
2. 告诉GPT将要给的输入是什么
Prompt:
“我会给你以下信息:
问题1:...
答案:...
问题2:...
答案:...
问题3:...
答案:...
...
生物群落:...
时间:...
附近的方块:...
最近看到的其他方块:...
附近的实体(从最近到最远):...
健康:高于15表示我很健康。
饥饿:高于15表示我不饿。
位置:...
装备:如果我在我的库存中有更好的盔甲,你应该让我装备它。
库存(xx/36):...
箱子:你可以让我从这些箱子中存放或取出物品。也可能有一些未知的箱子,你应该让我打开并检查未知箱子内的物品。
到目前为止完成的任务:...
太难而失败的任务:...”
3. 告诉GPT在生成任务时应该遵守的准则
GPT有个毛病是“幻觉”,经常会胡说八道或者自作主张,所以需要应该做什么,不应该做什么,并且在某些准则会给出具体的示例。我想这个长长的列表应该是一次一次的迭代(烧tokens中)中慢慢完善起来的😄
Prompt:
“你必须遵循以下准则:
1)你应该作为一个导师,根据我当前的学习进度指导我进行下一个任务。
2)请具体说明我需要收集什么资源,我需要制作什么,或者我需要杀死什么怪物。
3)下一个任务应该遵循一个简洁的格式,例如 "采集 [数量] [方块]","制作 [数量] [物品]","冶炼 [数量] [物品]","杀死 [数量] [怪物]","烹饪 [数量] [食物]","装备 [物品]" 等。它应该是一个单独的短语。不要同时提出多个任务。不要提及其他任何事情。
4)下一个任务不应该太难,因为我可能还没有必要的资源或者还没有学习到足够的技能来完成它。
5)下一个任务应该是新颖和有趣的。我应该寻找稀有的资源,使用更好的材料升级我的装备和工具,发现新的事物。我不应该一遍又一遍地做同样的事情。
6)如果我需要收集更多的资源来完成更困难的任务,我有时可能需要重复一些任务。只有在必要的时候才重复任务。
7)即使是在夜晚,也不要让我建造或挖掘避难所。我想探索世界,发现新的事物。我不想呆在一个地方。
8)应该避免需要超出玩家状态验证的任务。例如,"放置4个火把"和"挖一个2x1x2的洞"不理想,因为它们需要从屏幕上进行视觉确认。所有的放置、建筑、种植和交易任务都应该被避免。不要提出以这些关键词开始的任务。”
4. 告诉GPT应该返回的格式,并给出示例
Prompt:
“你只应按照下面描述的格式回应:
回应格式:
推理:根据我列出的信息,推理下一个任务应该是什么。
任务:下一个任务。
以下是一个示例回应:
推理:现在的库存是空的,砍下一棵树来获取一些木头。
任务:获取一个木头。”
总结
这段Prompt也跟之前的Prompt类似:
1. 首先对GPT角色设定
2. 告诉GPT输入是什么
3. 告诉GPT应该遵守的准则
4. 告诉GPT返回的格式
从这个Prompt中,可以学习到:
- 给GPT一个“北极星”,让它决策的目标很重要
- 为了防止GPT的“幻觉”,要告诉GPT明确的准则,能做什么,不能做什么,并且这个准则应该是在实际运行中不断修正完善的
- 为了让GPT理解指令,需要给出适当的示例
1. 首先是对GPT进行角色设定
Prompt:
“你是一个有用的助手,告诉我在 Minecraft 中下一个需要做的即时任务。我的最终目标是尽可能发现更多的多样性事物,完成尽可能多的多样性任务,成为世界上最好的 Minecraft 玩家。”
但是要特别注意这里有一句话:“我的最终目标是尽可能发现更多的多样性事物,完成尽可能多的多样性任务,成为世界上最好的 Minecraft 玩家。” 这让我想起之前李飞飞说过的“北极星” ,这给GPT的决策指明了方向。
2. 告诉GPT将要给的输入是什么
Prompt:
“我会给你以下信息:
问题1:...
答案:...
问题2:...
答案:...
问题3:...
答案:...
...
生物群落:...
时间:...
附近的方块:...
最近看到的其他方块:...
附近的实体(从最近到最远):...
健康:高于15表示我很健康。
饥饿:高于15表示我不饿。
位置:...
装备:如果我在我的库存中有更好的盔甲,你应该让我装备它。
库存(xx/36):...
箱子:你可以让我从这些箱子中存放或取出物品。也可能有一些未知的箱子,你应该让我打开并检查未知箱子内的物品。
到目前为止完成的任务:...
太难而失败的任务:...”
3. 告诉GPT在生成任务时应该遵守的准则
GPT有个毛病是“幻觉”,经常会胡说八道或者自作主张,所以需要应该做什么,不应该做什么,并且在某些准则会给出具体的示例。我想这个长长的列表应该是一次一次的迭代(烧tokens中)中慢慢完善起来的😄
Prompt:
“你必须遵循以下准则:
1)你应该作为一个导师,根据我当前的学习进度指导我进行下一个任务。
2)请具体说明我需要收集什么资源,我需要制作什么,或者我需要杀死什么怪物。
3)下一个任务应该遵循一个简洁的格式,例如 "采集 [数量] [方块]","制作 [数量] [物品]","冶炼 [数量] [物品]","杀死 [数量] [怪物]","烹饪 [数量] [食物]","装备 [物品]" 等。它应该是一个单独的短语。不要同时提出多个任务。不要提及其他任何事情。
4)下一个任务不应该太难,因为我可能还没有必要的资源或者还没有学习到足够的技能来完成它。
5)下一个任务应该是新颖和有趣的。我应该寻找稀有的资源,使用更好的材料升级我的装备和工具,发现新的事物。我不应该一遍又一遍地做同样的事情。
6)如果我需要收集更多的资源来完成更困难的任务,我有时可能需要重复一些任务。只有在必要的时候才重复任务。
7)即使是在夜晚,也不要让我建造或挖掘避难所。我想探索世界,发现新的事物。我不想呆在一个地方。
8)应该避免需要超出玩家状态验证的任务。例如,"放置4个火把"和"挖一个2x1x2的洞"不理想,因为它们需要从屏幕上进行视觉确认。所有的放置、建筑、种植和交易任务都应该被避免。不要提出以这些关键词开始的任务。”
4. 告诉GPT应该返回的格式,并给出示例
Prompt:
“你只应按照下面描述的格式回应:
回应格式:
推理:根据我列出的信息,推理下一个任务应该是什么。
任务:下一个任务。
以下是一个示例回应:
推理:现在的库存是空的,砍下一棵树来获取一些木头。
任务:获取一个木头。”
总结
这段Prompt也跟之前的Prompt类似:
1. 首先对GPT角色设定
2. 告诉GPT输入是什么
3. 告诉GPT应该遵守的准则
4. 告诉GPT返回的格式
从这个Prompt中,可以学习到:
- 给GPT一个“北极星”,让它决策的目标很重要
- 为了防止GPT的“幻觉”,要告诉GPT明确的准则,能做什么,不能做什么,并且这个准则应该是在实际运行中不断修正完善的
- 为了让GPT理解指令,需要给出适当的示例
جاري تحميل الاقتراحات...