利用ChatGPT与基于区块链的游戏互动

149 阅读5分钟

在这篇文章中,我们将指导你使用OpenAI的ChatGPT 3.5 API开发一个原型机器人,旨在参与Moonstream.to的基于区块链的文本游戏,Great Wyrm。完成的代码可以在kompotkot/gofp-chatgpt-bot资源库中找到。

Great Wyrm session

Great Wyrm作为一个平台,以 "游戏主人-玩家 "的形式主持游戏会话。由于游戏正在进行积极的测试,它的创造者独立地促进游戏会话。该平台在Calderawyrm.constellation 区块链网络上运行。要加入,请通过提供的Discord链接注册。

我们的代码将用Python编写。由于Great Wyrm建立在以太坊区块链上,我们将利用brownie库进行网络互动,并利用moonworm库从ABI中生成一个Python接口。

通常情况下,对于流行的游戏,ABI可以位于Etherscan的 "代码 "标签下,在项目的GitHub仓库内,或者使用brownie 等工具从.sol 文件独立生成。对于Great Wyrm游戏,合同可以通过GitHub链接访问,而准备好的ABI可以在Moonstream的文档中找到。

尽管如此,只有ABI需要我们重建brownie 结构以实现正确的功能。为了实现这一目标,请按照以下步骤创建必要的文件夹并复制ABI:

mkdir -p gcb/build/contracts/
cp abi/GOFP.json gcb/build/contracts/gofp.json

进入全屏模式 退出全屏模式

得到的文件,gcb/build/contracts/gofp.json ,应该显示如下:

{
  "abi": [
    ...
  ]
}

进入全屏模式 退出全屏模式

首先,在ABI地址生成一个接口,这将产生一个名为gcb/gofp.py 的Python文件,其中包含gofp类和概述智能合约功能的方法:

moonworm generate-brownie --name gofp -o gcb -p gcb

进入全屏模式 退出全屏模式

随后,wyrm 被添加到brownie'的本地网络列表中:

brownie networks add Constellation wyrm host=https://wyrm.0xconstellation.com/http chainid=322

进入全屏模式 退出全屏模式

第一部分完成后,我们现在可以通过简单地引入一个变量与智能合约进行通信:

export GOFP_CONTRACT_ADDRESS="0x42A8E82253CD19EF8274D48fC0bC89cdf1B4425b"

进入全屏模式 退出全屏模式

让我们查询智能合约以确定游戏会话的总数:

python -m gcb.gofp num-sessions --network wyrm --address "$GOFP_CONTRACT_ADDRESS"

进入全屏模式 退出全屏模式

接下来,我们将继续配置ChatGPT。这需要一个在OpenAI网站上生成的API密钥,它可以实现与平台的互动。使用变量将这个密钥添加到代码中:

export OPENAI_API_KEY="sk-..."

进入全屏模式 退出全屏模式

为了测试该功能,我们来查询一下可用的GPT模式的使用情况:

curl https://api.openai.com/v1/models -H "Authorization: Bearer $OPENAI_API_KEY" | jq .data[].id | grep gpt

进入全屏模式 退出全屏模式

最后,回到源代码,检查重要部分:

drwxrwxr-x build
-rw-rw-r-- cli.py
-rw-rw-r-- data.py
-rw-rw-r-- gofp.py
-rw-rw-r-- __init__.py
-rw-rw-r-- version.py
-rw-rw-r-- version.txt

进入全屏模式 退出全屏模式

data.py 文件中,我们将利用pydantic 库来定义关键结构,如SessionData,SessionDataStages, 等,以增加便利性。主要的代码可以在cli.py 中找到。

在用argparse 生成CLI时,有必要用预先生成的标志和参数来增强解析器,这些标志和参数的来源是gofp.py

add_default_arguments(parser=parser_play, transact=True)

进入全屏模式 退出全屏模式

接下来,我们需要两个主要参数:--session 来指定要参与的游戏会话,以及--token 来确定要操作的令牌。在主函数handle_play ,首先连接到brownie 网络并初始化合同实例:

network.connect(args.network)
contract = gofp(contract_address=args.address)

进入全屏模式 退出全屏模式

利用moonworm 库,我们通过方法与智能合约沟通,允许我们获得所需游戏会话的信息:

session_info_raw = contract.get_session(args.session)
...
current_stage_indexed = contract.get_current_stage(args.session)

进入全屏模式 退出全屏模式

剩下的就是根据data.py 中定义的结构来解析响应,并完成过滤非活动会话的逻辑,以及其他事项。

每个会话的功能是一个独特的标记,有自己的tokenURI ,包含游戏阶段描述、传说等等。我们将使用基本的requests 库获得这些信息,在requests_call 函数中实现,并根据我们预定义的结构进行解析:

session_data_raw = requests_call(method=data.Method.GET, url=session_info.uri)

进入全屏模式 退出全屏模式

现在,我们应该为ChatGPT准备文本。在这个例子中,我们将描述预期的任务并请求一个JSON格式的响应。在answer 键下,ChatGPT应该指出它在游戏中选择的路径,同时在description 键下提供选择的理由:

message_to_bot = f"""Let's play. I will provide you with a short lore containing 
different paths to choose from. Please respond in JSON format. You should select 
one correct path and place it under the key 'answer' and provide an explanation 
for your choice under the key 'description'.

The lore: {session_data.stages[current_stage].lore}
Paths:
{paths}
"""

进入全屏模式 退出全屏模式

向ChatGPT请求响应,确保指定一个高的timeout ,因为响应的时间有时会比预期的长:

openapi_headers = {
    "Authorization": f"Bearer {OPENAI_API_KEY}",
}
payload = {
    "model": "gpt-3.5-turbo",
    "messages": [{"role": "user", "content": message_to_bot}],
}

bot_resp_raw = requests_call(
    method=data.Method.POST,
    url=f"{OPENAPI_BASE_URL}/completions",
    headers=openapi_headers,
    json=payload,
    timeout=60,
)

进入全屏模式 退出全屏模式

为了与机器人进行更全面的互动,OpenAI提供了一系列详细的设置,可在端点文档中找到。

收到响应后,我们将对其进行处理并生成一个交易:

transaction_config = get_transaction_config(args)

tx_hash = contract.choose_current_stage_paths(
    session_id=args.session,
    token_ids=[args.token],
    paths=[bot_answer + 1],
    transaction_config=transaction_config
)

进入全屏模式 退出全屏模式

准备好后,使用你的密钥文件,用以下命令执行代码:

gcb play --address "$GOFP_CONTRACT_ADDRESS" \
  --network wyrm \
  --confirmations 0 \
  --sender "$DEV_KEYFILE" \
  --password "$DEV_KEYFILE_PASSOWRD" \
  --session 4 \
  --token 2

进入全屏模式 退出全屏模式

机器人将检索必要的数据,解析结果,并报告交易细节:

INFO:gcb.cli:Fetch session 4 with stages [4, 1] and uri https://s3.amazonaws.com/static.greatwyrm.xyz/act1/reda_games/khina_beast_contest.json
INFO:gcb.cli:Current stage of session 4 is 1
INFO:gcb.cli:Fetch session data with title Khina's Beast Contest and active stage title Pit bat
INFO:gcb.cli:Asking ChatGPT to choose path
INFO:gcb.cli:Bot answer is: 1 and description: I would back the Copper hound because it has a useful skill that people could benefit from by sniffing out copper deposits. Additionally, they seem to be domesticated dogs so they may be more manageable than some of the other creatures. The downside is that they are not the most pleasant smelling animals and can be quite loud.
Transaction sent: 0x32bdff6127fdb94f0199f5cc10565c82fffb26768a1029f469a4b205fc5ed9fd
  Gas price: 0.0 gwei   Gas limit: 156629   Nonce: 15
  gofp.chooseCurrentStagePaths confirmed   Block: 470   Gas used: 118554 (75.69%)

<Transaction '0x32bdff6127fdb94f0199f5cc10565c82fffb26768a1029f469a4b205fc5ed9fd'>

进入全屏模式 退出全屏模式

总之,我们已经成功地在ChatGPT和Web3之间建立了一个整合,为能够参与基于区块链的游戏的聊天机器人奠定了基础。这种组合为扩展功能和为各种任务和目标定制解决方案提供了许多可能性。

Claim your reward!