从提示到编写代码以找到游戏的平衡点
反馈回路在开发可靠的程序中至关重要。因此,我没有直接用LLM来生成代码,而是用带有LLM和Python解释器的Autogen代理来优化代码,以提升代码质量。
作者拍摄
搭建开发环境安装步骤:在Google Colab的笔记本里,我已经安装了pyautogen、openai和所需的库。
import tempfile
import autogen
from autogen import ConversableAgent
from autogen.coding import LocalCommandLineCodeExecutor
import openai
from openai import OpenAI
设置LLM:我用的是GPT-3.5-turbo,考虑到成本。
config_list = [
{
"模型名": "gpt-3.5-turbo",
"api_key": OPENAI_API_KEY,
}
]
# 配置列表用于存储模型和API密钥的设置信息
Python 环境配置:我需要临时文件目录和解释器。我配置了 Autogen 来使用本地的 Python 解释器运行代码。
# Temporary Directory
temp_dir = tempfile.TemporaryDirectory()
# 代码执行器实例
executor = LocalCommandLineCodeExecutor(timeout=10, work_dir=temp_dir.name)
我们只需要代理
我创建了以下这些可对话的代理(如图所示:https://claude.site/artifacts/6f159803-46f5-4352-bfdf-0fa3b7f7202d):
- 一个生成代码的代理来生成Python代码
- 一个执行代码的代理来与Python解释器交互以执行生成的代码
- 一个帮助解决任何问题的错误分析代理
- 一个模拟用户交互的代理
code_executor_agent = ConversableAgent(
name="CodeExecutorAgent",
llm_config=False,
code_execution_config={"executor": executor},
human_input_mode="ALWAYS"
)
error_analyzer_agent = ConversableAgent(
name="ErrorAnalyzerAgent",
llm_config={"config_list": config_list},
system_message="你分析Python代码中的错误并提出修复建议。提供清晰的解释和改进措施。确保代码能够处理边界情况和常见错误,例如无效输入和算术错误。"
)
user_proxy = ConversableAgent(
name="User",
code_execution_config=False,
human_input_mode="ALWAYS"
)
代码生成器代理特别之处在于,因为它接收到来自系统的消息和需求。它可能已经过载了,可以考虑进行重构。
在我们的案例中,我希望程序能找到一个2x2游戏的纯[Nash均衡点]。这个游戏的描述会在系统消息中给出。你现在不需要太了解博弈论。以后的文章中会更多地介绍博弈论。
code_generator_agent = ConversableAgent(
name="CodeGeneratorAgent",
llm_config={"config_list": config_list},
system_message="""你是一位精通Python编程的专家,并且对博弈论有深入了解。你的任务是开发一个Python脚本,用于找到2x2游戏中基于最佳回应策略的纯纳什均衡点。程序应该具有文本界面,并包含以下功能:
1. 使用嵌套列表表示一个2x2游戏的函数。
2. 计算每个玩家最佳回应的函数。
3. 基于最佳回应找到纯纳什均衡点的函数。
4. 供用户输入游戏收益和查看结果的文本界面。
5. 清晰地显示游戏、最佳回应和纳什均衡点。
6. 正确的错误处理和输入验证。
重要注意事项:
- 使用嵌套列表表示游戏:[[[a,b],[c,d]], [[e,f],[g,h]]],其中第一个子列表是玩家1的收益,第二个是玩家2的。
- 实现每个玩家策略的最佳回应计算,并考虑策略可能同样好的情况。
- 添加详细的注释来解释关键步骤,特别是最佳回应和纳什均衡点逻辑。
- 确保界面设计简单明了,并提供清晰的指令。
- 提供选项让用户分析多个游戏,或选择退出。
最佳回应计算:
- 对于每个玩家和对手的每个策略,确定哪种策略带来的收益最高。
- 如果两个策略带来的收益相同,则认为它们都是最佳回应。
- 返回最佳回应作为列表:[[p1_br1, p1_br2], [p2_br1, p2_br2]],其中每个br可以是1、2或'Both'。
纳什均衡寻找算法:
- 如果没有任何玩家单方面改变策略可以提高收益,则这种策略组合就是纳什均衡点。
- 实现以下步骤:
1. 遍历所有可能的策略组合:(1,1),(1,2),(2,1),(2,2)。
2. 对于每个组合(i,j):
- 检查策略i是否是玩家1相对于玩家2的策略j的最佳回应
- 并且,策略j是否是玩家2相对于玩家1的策略i的最佳回应
3. 如果两个条件都为真,则将(i,j)添加到nash_equilibria列表中。
- 处理策略可能同样好的情况(即,当best_responses包含'Both')。
- 确保函数可以正确处理有0、1或2个纳什均衡点的情况。
文本界面:
- 提示用户输入玩家1的收益(以负数表示):
- 以可读格式显示游戏。
- 显示每个玩家的最佳回应。
- 清晰地指出找到的纯纳什均衡点。
- 允许用户输入多个游戏,或选择退出。
示例输出格式(使用囚徒困境):
输入玩家1的收益(以负数表示):
策略1,1: -1
策略1,2: -3
策略2,1: 0
策略2,2: -2
输入玩家2的收益(以负数表示):
策略1,1: -1
策略1,2: 0
策略2,1: -3
策略2,2: -2
游戏:
玩家1的收益: 玩家2的收益:
[-1, -3] [-1, 0]
[0, -2] [-3, -2]
最佳回应:
玩家1:[2, 2]
玩家2:[2, 2]
纯纳什均衡点:[(2,2)]
```
确保你的实现准确、用户友好,并且能清晰地输出基于最佳回应策略的2x2游戏分析结果。
"""
)
工作流是在群聊中定义的。代码生成器代理生成的代码会传递给代码执行器,代码执行器会立即执行代码(请参见这个代理的上述配置)。
# 群聊初始化
group_chat = GroupChat(agents=[code_generator_agent, code_executor_agent, error_analyzer_agent, user_proxy], messages=[]) # 群聊对象初始化
# 管理器初始化
manager = GroupChatManager(groupchat=group_chat, llm_config={"config_list": config_list}) # 群聊管理器初始化
如果没有适当的错误处理机制,以上所有可能都无法正常运作。或者某些错误类别未得到妥善处理。如果没有错误分析代理,它负责这一部分。
# 错误处理
def handle_execution_error(message, e):
error_message = f"代码执行失败:\n```\n{message.content}\n```\n错误:\n```\n{e}\n```"
error_analyzer_agent.send(error_message, group_chat)
# 清除现有回复并注册错误处理
code_executor_agent._reply_func_list.clear()
code_executor_agent.register_reply([autogen.AssistantAgent, LocalCommandLineCodeExecutor], handle_execution_error)
# 增强型错误分析
def enhanced_error_analysis(message, error):
error_type = type(error).__name__
suggestions = {
'ValueError': "检查无效输入,确保所有值都在预期范围内。",
'ZeroDivisionError': "确保没有除以零的情况。添加检查以防止零作为分母。",
'TypeError': "验证所有操作是否都在兼容的数据类型上进行。",
'IndexError': "确保列表或数组索引在有效范围内。",
'KeyError': "检查字典键是否存在后再访问。",
'AttributeError': "验证对象是否有正在访问的属性或方法。",
'ImportError': "确保所有需要的模块已正确安装和导入。"
}
suggestion = suggestions.get(error_type, "查看代码以寻找可能的问题。")
error_message = f"代码执行失败:\n```\n{message.content}\n```\n错误:\n```\n{error}\n```\n建议修复:\n```\n{suggestion}\n```"
error_analyzer_agent.send(error_message, group_chat)
# 注册增强错误分析
code_executor_agent.register_reply([autogen.AssistantAgent, LocalCommandLineCodeExecutor], enhanced_error_analysis)
最终由用户代理程序启动对话。
# 开始对话
user_proxy发起对话(
manager, message="请生成Python代码,用于使用最佳响应策略在2x2游戏中寻找纯纳什均衡。实现一个基于文本的用户界面,包含游戏表示、最佳响应计算功能以及基于最佳响应的均衡查找功能。"
)
对话就这样开始了:
用户(对 chat_manager):
生成Python代码来使用最佳回应方法找到2x2游戏中的纯纳什均衡点。实现一个文本界面,用于用户输入和结果展示。包括游戏的表示、最佳回应的计算以及基于最佳回应的均衡查找算法等功能。
接下来是CodeGeneratorAgent发言
这是代理生成的程序。
def represent_game():
"""
使用嵌套列表来表示2x2游戏的功能。
"""
game = []
print("请输入玩家1的收益:")
p1_row1 = [int(input("策略1,1: ")), int(input("策略1,2: "))]
p1_row2 = [int(input("策略2,1: ")), int(input("策略2,2: "))]
game.append([p1_row1, p1_row2])
print("\n请输入玩家2的收益:")
p2_row1 = [int(input("策略1,1: ")), int(input("策略1,2: "))]
p2_row2 = [int(input("策略2,1: ")), int(input("策略2,2: "))]
game.append([p2_row1, p2_row2])
return game
def best_responses(game):
"""
计算游戏中每个玩家的最佳反应的功能。
"""
p1_best_responses = [[], []]
p2_best_responses = [[], []]
for i in range(2): # 遍历玩家1的策略
for j in range(2): # 遍历玩家2的策略
if game[0][i][j] == max(game[0][i]): # 检查策略是否为玩家1的最高回报
p1_best_responses[i].append(j + 1)
if game[1][j][i] == max([row[i] for row in game[1]]): # 检查策略是否为玩家2的最高回报
p2_best_responses[j].append(i + 1)
return p1_best_responses, p2_best_responses
def find_nash_equilibria(p1_best_responses, p2_best_responses):
"""
基于最佳反应查找纯纳什均衡的功能,用于识别稳定策略组合。
"""
nash_equilibria = []
for i in range(2):
for j in range(2):
if (i + 1) in p1_best_responses[j] and (j + 1) in p2_best_responses[i]:
nash_equilibria.append((i + 1, j + 1))
return nash_equilibria
def display_game(game):
"""
以清晰格式显示游戏的功能。
"""
print("\n游戏:")
print("玩家1的收益: 玩家2的收益:")
for i in range(2):
print(game[0][i], " ", game[1][i])
# 基于文本的交互界面
while True:
game = represent_game()
display_game(game)
p1_best_responses, p2_best_responses = best_responses(game)
print("\n最佳反应:")
print("玩家1:", p1_best_responses)
print("玩家2:", p2_best_responses)
nash_equilibria = find_nash_equilibria(p1_best_responses, p2_best_responses)
print("\n纯纳什均衡点:", nash_equilibria)
play_again = input("\n继续分析另一个游戏吗?(y/n): ")
if play_again.lower() != 'y':
break
我运行了生成的程序来寻找“性别之争”博弈中的纯策略纳什均衡。以下是程序找到的性别之争博弈的纯策略纳什均衡。
请输入玩家1的收益:
策略1,1: 3
策略1,2: 0
策略2,1: 0
策略2,2: 2
请输入玩家2的收益:
策略1,1: 2
策略1,2: 0
策略2,1: 0
策略2,2: 3
游戏情况:
玩家1的收益: 玩家2的收益:
[3, 0] [2, 0]
[0, 2] [0, 3]
最佳回应:
玩家1: [[1], [2]]
玩家2: [[1], [2]]
纯纳什均衡: [(1, 1), (2, 2)]
# 结论
随着大型语言模型不断进步,软件开发也越来越自动化了。
点击查看更多内容
为 TA 点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦