2026山东大学软件学院创新项目实训博客(三)
【智绘博弈】Prompt Engineering —— 让 AI 按难度猜词
项目:智绘博弈 —— 人机对抗绘画猜词与心理解读系统
角色:AI 识别 & 心理解读模块负责人
日期:2026.4.13 - 2026.4.19
一、本周目标
上周完成了智谱 API 的基本调用,AI 已经能识别简笔画了。但有个问题:
AI 太聪明了,基本都能猜对,玩家根本赢不了!
这周的任务是设计 Prompt 策略,让 AI 在不同难度下表现不同:
-
简单模式:AI “装傻”,给人类更多赢的机会
-
中等模式:AI 正常发挥
-
困难模式:AI 全力以赴,人类很难赢
核心思路:不是改 AI 模型,而是改我们给 AI 的提示词。
二、Prompt Engineering 是什么?
Prompt Engineering(提示词工程)就是通过设计输入的提示词,来控制 AI 的输出行为。
同一个模型,给不同的 prompt,效果可以完全不同:
| Prompt | AI 表现 |
|---|---|
| 「这是什么?」 | 随便猜,可能猜错 |
| 「这是一个物品,猜猜是什么?」 | 范围缩小,准确率提高 |
| 「这是一个物品,可能是:苹果、香蕉、橙子。选一个」 | 几乎不会错 |
我们的三档难度,本质上就是给 AI 不同程度的“作弊信息”。
三、三档难度的 Prompt 设计
3.1 设计思路
| 难度 | 给 AI 的信息 | 预期效果 |
|---|---|---|
| easy | 几乎不给提示,让 AI 裸猜 | AI 容易猜错 → 人类容易赢 |
| medium | 告诉分类(物品/动作/概念) | 中等难度 |
| hard | 告诉分类 + 给候选词列表 | AI 基本猜对 → 人类难赢 |
3.2 代码实现
def _build_prompt(difficulty, category, word_list=None):
"""
根据难度构建不同强度的 prompt
"""
# 获取难度配置
difficulty_config = config.AI_DIFFICULTY_LEVELS.get(difficulty)
hint_level = difficulty_config['prompt_hint_level']
# 分类名称映射
category_names = {
'object': '物品/事物',
'action': '动作/行为',
'concept': '抽象概念',
}
cat_name = category_names.get(category, '未知类别')
# 基础角色设定(所有难度通用)
prompt = (
"你是一个绘画猜词游戏中的AI选手。"
"玩家在网页画板上画了一幅简笔画,你需要猜测画的是什么。\n"
"注意:这是手绘简笔画,线条可能不太精确,请发挥联想能力。\n"
)
# 根据难度添加不同程度的提示
if hint_level >= 0.8:
# 困难模式:给 AI 充分的提示和候选范围
prompt += f"\n提示信息:这幅画属于「{cat_name}」类别。"
if word_list:
prompt += f"\n候选答案范围:{', '.join(word_list[:15])}。"
prompt += "\n请仔细分析画面中的每一个细节,给出你最有信心的猜测。"
elif hint_level >= 0.5:
# 中等模式:给一点分类提示
prompt += f"\n提示:这幅画大致属于「{cat_name}」类别。"
prompt += "\n请根据画面特征给出你的猜测。"
else:
# 简单模式:几乎不给提示,让 AI 裸猜
prompt += "\n请猜测这幅画画的是什么。"
# 输出格式要求(所有难度通用)
prompt += (
"\n\n【重要】请严格按照以下JSON格式返回:\n"
'{"guess": "你的猜测", "confidence": 0.85, "reasoning": "简要推理过程"}\n'
)
return prompt
3.3 三档 Prompt 对比
简单模式(easy)的 prompt:
你是一个绘画猜词游戏中的AI选手。玩家在网页画板上画了一幅简笔画,你需要猜测画的是什么。 注意:这是手绘简笔画,线条可能不太精确,请发挥联想能力。 请猜测这幅画画的是什么。 【重要】请严格按照以下JSON格式返回...
中等模式(medium)的 prompt:
你是一个绘画猜词游戏中的AI选手。玩家在网页画板上画了一幅简笔画,你需要猜测画的是什么。 注意:这是手绘简笔画,线条可能不太精确,请发挥联想能力。 提示:这幅画大致属于「物品/事物」类别。 请根据画面特征给出你的猜测。 【重要】请严格按照以下JSON格式返回...
困难模式(hard)的 prompt:
你是一个绘画猜词游戏中的AI选手。玩家在网页画板上画了一幅简笔画,你需要猜测画的是什么。 注意:这是手绘简笔画,线条可能不太精确,请发挥联想能力。 提示信息:这幅画属于「物品/事物」类别。 候选答案范围:苹果、香蕉、西瓜、葡萄、橙子、草莓、樱桃、梨、桃子、芒果。 请仔细分析画面中的每一个细节,给出你最有信心的猜测。 【重要】请严格按照以下JSON格式返回...
可以看到,从 easy 到 hard,AI 拿到的“作弊信息”越来越多。
四、JSON 输出格式约束
4.1 为什么需要格式约束?
如果不约束格式,AI 可能返回各种奇怪的东西:
我觉得这幅画画的应该是一个苹果吧,因为它是圆形的,上面还有一个小柄...
这样我们很难用程序解析出「苹果」这个答案。
4.2 约束 prompt 的写法
prompt += (
"\n\n【重要】请严格按照以下JSON格式返回,不要返回任何其他内容:\n"
'{"guess": "你的猜测", "confidence": 0.85, "reasoning": "简要推理过程"}\n'
"\n要求:\n"
'- guess:2-4个中文字,是你认为画的内容\n'
'- confidence:0到1之间的小数,表示你的确信程度\n'
'- reasoning:一句话说明你的判断依据\n'
'- 只返回JSON,不要加任何前缀、后缀、markdown标记'
)
关键技巧:
-
给示例:直接给一个 JSON 样例,AI 会模仿格式
-
强调“严格” “只返回” :减少 AI 自由发挥
-
明确每个字段的要求:长度、类型、含义都说清楚
4.3 实际效果
加了格式约束后,AI 的返回基本都是标准 JSON 了:
{
"guess": "蘑菇",
"confidence": 0.9,
"reasoning": "图中有一个伞状物体和一个细长的茎,这通常代表一个蘑菇"
}
五、难度配置参数
在 config.py 里,我们定义了三档难度的具体参数:
AI_DIFFICULTY_LEVELS = {
'easy': {
'description': '简单 - AI 较容易被骗',
'prompt_hint_level': 0.3, # 提示程度低
'confidence_threshold': 0.8, # 需要高置信度才算猜对
},
'medium': {
'description': '中等 - AI 正常发挥',
'prompt_hint_level': 0.6,
'confidence_threshold': 0.5,
},
'hard': {
'description': '困难 - AI 全力以赴',
'prompt_hint_level': 1.0, # 给充分提示
'confidence_threshold': 0.3, # 低置信度也算猜对
},
}
注意有两个维度在控制难度:
| 参数 | 作用 |
|---|---|
prompt_hint_level |
控制给 AI 多少提示信息 |
confidence_threshold |
AI 需要多高置信度才「算猜对」 |
也就是说,简单模式下,不仅给 AI 的提示少,而且要求 AI 置信度 ≥0.8 才算它猜对。双重削弱,让人类更容易赢。
六、实测对比
我在服务器上编写了自动化测试脚本,用 Python PIL 库生成简笔画,分别测试三档难度下 AI 的表现。
测试 1:特征明显的简笔画(蘑菇)
| 难度 | AI 猜测 | 置信度 | 推理 | 响应时间 | 判定 |
|---|---|---|---|---|---|
| easy | 蘑菇 | 0.9 | 半圆形+矩形+小圆点 | 4048ms | 猜对 ✓ |
| medium | 蘑菇 | 0.9 | 半圆帽子+长方形柄+斑点 | 1324ms | 猜对 ✓ |
| hard | 蘑菇 | 0.9 | 半圆顶部+长方形底部+圆点 | 1830ms | 猜对 ✓ |
结论:特征明显的画,三档难度差异不大,AI 都能轻松识别。
测试 2:模糊手绘风格的简笔画(苹果)
为了模拟真人画画的不精确感,我用随机噪声生成了一个歪歪扭扭的圆形,带一根短柄和一片叶子:
| 难度 | AI 猜测 | 置信度 | 推理 | 判定 |
|---|---|---|---|---|
| easy | 钥匙 | 0.9 | 上部有钩子形状 | 未猜对 ✗ |
| medium | 圣诞树 | 0.8 | 类似挂饰的钩子 | 未猜对 ✗ |
| hard | 气球 | 0.9 | 不规则边缘+顶部小环 | 未猜对 ✗ |
结论:画得模糊时,AI 在不同难度下猜测方向不同。hard 模式虽然有候选词列表,但画太潦草时仍然会误判。 这说明 prompt 策略不是万能的,真正影响游戏体验的是"画的质量"和"prompt提示"的组合效果。
实测心得
这组测试让我理解了一个重要的事情:三档难度不是为了让AI "变笨",而是为了在中等质量的画作上拉开区分度。画得很好→谁都能猜对;画得很烂→谁都猜不对;只有画得"还行但有歧义"的时候,prompt 提示的多少才 真正决定胜负。这也是游戏设计中"心流"区间的体现。
七、遇到的问题
问题 1:AI 有时候不听话,返回的不是纯 JSON
上周提到过这个问题,这周通过格式约束 prompt 已经大幅改善,但偶尔还是会出现,即使 prompt 里强调了“只返回json”,AI 偶尔还是会加点废话:
好的,我来分析这幅画:
{"guess": "苹果", "confidence": 0.8, "reasoning": "..."}
这个问题下周会专门写一篇来讲怎么做“健壮的响应解析”。
问题 2:候选词列表太长会影响效果
困难模式下如果给 AI 50 个候选词,反而可能让它困惑。测试后发现 10-15 个候选词效果最好。
if word_list:
prompt += f"\n候选答案范围:{', '.join(word_list[:15])}。" # 最多取15个
八、下周计划
-
响应解析:处理 AI “不听话” 的各种情况,写一个健壮的 JSON 解析函数
-
通义千问备份:实现自动降级机制
-
更多测试:用不同类型的简笔画(物品/动作/概念)测试准确率
九、本周总结
这周完成了 Prompt Engineering 的核心设计:
-
理解了“通过 prompt 控制 AI 行为”的思路
-
设计了三档难度的 prompt 策略:信息量递增
-
学会了用示例和强调语约束 AI 的输出格式
-
配合
confidence_threshold实现双重难度控制
现在游戏的难度系统已经可以工作了,简单模式下人类确实更容易赢!
(本文代码在 AI 辅助下完成。开发方式为 SPEC 协作:我根据 “三档难度控制 AI 猜词准确率” 的需求,与 AI 讨论了 prompt 设计策略,AI 提供了代码实现,我进行了测试和参数调优。)
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐
所有评论(0)