
Who am AI – 用10个问题揭秘AI角色扮演的技术实现在AI技术快速发展的今天角色扮演已成为大模型应用的重要场景之一。无论是游戏NPC、虚拟助手还是创意写作让AI扮演特定角色并保持角色一致性是开发者面临的关键挑战。本文将深入探讨如何通过精心设计的提示词工程让AI在10个问题的限制内准确扮演秘密角色并分享完整的技术实现方案。1. AI角色扮演的核心概念与技术原理1.1 什么是AI角色扮演AI角色扮演是指让大型语言模型模拟特定人物、角色或实体的思维模式、语言风格和行为特征。与普通的问答对话不同角色扮演要求AI在整段对话中保持角色的一致性包括知识范围、语言习惯、价值观等各个方面。在实际应用中角色扮演可以分为几个层次基础角色扮演模拟基本的人物特征和说话方式深度角色扮演保持角色的知识边界和认知局限性高级角色扮演模拟角色的情感变化和成长轨迹1.2 技术实现原理现代大语言模型通过注意力机制和上下文学习来实现角色扮演。当模型接收到包含角色设定的提示词时它会解析角色描述中的关键特征建立临时的角色记忆在生成回复时优先使用符合角色设定的词汇和表达方式通过上下文窗口维持角色一致性# 基础的角色扮演提示词结构示例 role_play_prompt 你正在扮演一个[角色描述]。 你的性格特点[性格特征] 你的知识范围[知识边界] 你的说话风格[语言习惯] 你的秘密身份[隐藏信息] 请在整个对话中保持角色一致性不要打破第四面墙。 用户将通过最多10个问题来猜测你的真实身份。 1.3 10个问题限制的挑战与意义限制问题数量增加了游戏的挑战性也考验着提示词设计的精准度。在技术层面这要求提示词必须包含足够的信息让AI理解角色同时要避免信息过于直白而失去趣味性AI需要具备引导对话和适当误导的能力模型要能在有限轮次内维持角色一致性2. 环境准备与开发工具2.1 主流AI模型选择目前支持角色扮演的主流模型包括OpenAI GPT系列GPT-3.5-turbo性价比高响应速度快GPT-4理解能力更强角色一致性更好GPT-4 Turbo上下文窗口更大适合长对话开源替代方案Llama 2/3Meta开源模型可本地部署ChatGLM中英双语优势明显Vicuna基于Llama的优化版本2.2 开发环境配置# 所需Python库 requirements openai1.0.0 langchain0.1.0 python-dotenv1.0.0 fastapi0.100.0 # 可选用于Web接口 uvicorn0.20.0 # 可选用于Web服务 # 环境变量配置 import os from dotenv import load_dotenv load_dotenv() OPENAI_API_KEY os.getenv(OPENAI_API_KEY)2.3 基础项目结构ai_role_play/ ├── src/ │ ├── __init__.py │ ├── models/ │ │ ├── role_manager.py # 角色管理 │ │ └── game_engine.py # 游戏引擎 │ ├── prompts/ │ │ ├── role_templates.py # 角色模板 │ │ └── system_prompts.py # 系统提示词 │ └── utils/ │ ├── validator.py # 输入验证 │ └── logger.py # 日志记录 ├── tests/ ├── requirements.txt └── main.py3. 核心提示词设计与优化策略3.1 角色描述的最佳实践有效的角色描述应该包含以下要素# 完整的角色描述模板 ideal_role_description { basic_info: { name: 角色名称可选隐藏, age: 大致年龄范围, occupation: 职业或身份 }, personality: { traits: [特质1, 特质2, 特质3], values: 核心价值观, quirks: 独特习惯或口头禅 }, knowledge: { expertise: [擅长领域1, 擅长领域2], limitations: [知识盲区1, 知识盲区2], perspective: 看待世界的独特角度 }, behavior: { speech_style: 语言风格描述, reaction_pattern: 应对问题的典型方式, tells: 无意中暴露身份的线索 } }3.2 系统提示词工程系统提示词是控制AI行为的关键需要精心设计system_prompt 你是一个专业的角色扮演AI。在本次对话中你将扮演一个秘密角色。 核心规则 1. 你绝对不能直接透露你的真实身份 2. 用户最多只能问10个问题 3. 你要根据角色的知识范围和认知水平来回答问题 4. 可以适当给出误导性信息但要符合角色设定 5. 如果用户猜中身份你要承认但不要过早暴露 角色设定 {role_description} 对话记录 {conversation_history} 当前状态 - 已用问题数{question_count}/10 - 用户最新问题{latest_question} 请生成符合角色设定的回复同时维持游戏的趣味性。 3.3 上下文管理策略由于大模型有上下文长度限制需要智能管理对话历史class ConversationManager: def __init__(self, max_turns10, max_tokens4000): self.max_turns max_turns self.max_tokens max_tokens self.conversation_history [] def add_exchange(self, question, answer): 添加一轮问答到历史记录 self.conversation_history.append({ question: question, answer: answer, turn: len(self.conversation_history) 1 }) # 智能修剪历史保留重要信息 self._trim_history() def _trim_history(self): 当历史记录过长时进行智能修剪 if self._calculate_tokens() self.max_tokens: # 保留开头和最近的对话删除中间部分 keep_indices [0] # 保留系统提示词 keep_indices.extend(range(len(self.conversation_history) - 3, len(self.conversation_history))) trimmed_history [self.conversation_history[i] for i in keep_indices if i 0] self.conversation_history trimmed_history4. 完整实现AI角色猜测游戏引擎4.1 游戏状态管理class RolePlayGame: def __init__(self, role_description, modelgpt-3.5-turbo): self.role_description role_description self.model model self.conversation_manager ConversationManager() self.current_turn 0 self.max_turns 10 self.game_state playing # playing, won, lost self.actual_identity self._extract_identity(role_description) def _extract_identity(self, description): 从角色描述中提取真实身份用于验证猜测 # 这里可以使用更复杂的NLP技术 # 简化的关键词提取 identity_keywords [是, 名为, 身份是, 扮演] # 实际实现中会使用更精确的身份提取逻辑 return description.split(。)[0] # 简化处理 def process_question(self, question): 处理用户问题并返回AI回复 if self.game_state ! playing: return 游戏已结束请重新开始新游戏 if self.current_turn self.max_turns: self.game_state lost return f问题次数已用尽我的真实身份是{self.actual_identity} self.current_turn 1 # 构建完整的提示词 prompt self._build_prompt(question) # 调用AI模型生成回复 response self._call_ai_model(prompt) # 检查是否猜中身份 if self._check_guess(question, response): self.game_state won response f\n\n恭喜你猜对了我就是{self.actual_identity} # 记录对话历史 self.conversation_manager.add_exchange(question, response) return response4.2 AI模型调用实现import openai from openai import OpenAI class AIClient: def __init__(self, api_key, modelgpt-3.5-turbo): self.client OpenAI(api_keyapi_key) self.model model def generate_response(self, messages, temperature0.7, max_tokens500): 调用OpenAI API生成回复 try: response self.client.chat.completions.create( modelself.model, messagesmessages, temperaturetemperature, max_tokensmax_tokens, stopNone ) return response.choices[0].message.content except Exception as e: return fAI服务暂时不可用{str(e)} # 在游戏引擎中的调用示例 def _call_ai_model(self, prompt): messages [ {role: system, content: prompt}, {role: user, content: 开始游戏} ] ai_client AIClient(api_keyOPENAI_API_KEY, modelself.model) return ai_client.generate_response(messages)4.3 身份猜测检测逻辑def _check_guess(self, question, response): 检测用户是否猜中了身份 question_lower question.lower() response_lower response.lower() identity_lower self.actual_identity.lower() # 检测直接猜测 direct_guess_patterns [ f你是{identity_lower}, f你的身份是{identity_lower}, f我猜你是{identity_lower}, f你是不是{identity_lower} ] for pattern in direct_guess_patterns: if pattern in question_lower: return True # 检测AI回复中是否无意确认了猜测 confirmation_phrases [ 猜对了, 正确, 是的, 没错, bingo ] for phrase in confirmation_phrases: if phrase in response_lower and identity_lower in question_lower: return True return False5. 高级功能与优化技巧5.1 角色一致性保持技术保持角色一致性是技术难点以下是几种有效方法def enhance_role_consistency(role_description): 增强角色一致性的提示词优化 enhanced_prompt f {role_description} 重要提醒 1. 时刻记住你的角色设定不要以AI的身份思考 2. 如果你的角色有知识局限要真实地表现出这种局限 3. 使用角色特有的词汇和表达方式 4. 保持情感反应的一致性 5. 如果被问及现代技术或AI相关话题要基于角色的认知水平回答 记忆锚点每隔几次回复 subtly reinforce your characters key traits. return enhanced_prompt5.2 难度调节机制class DifficultyManager: def __init__(self, difficultymedium): self.difficulty_levels { easy: { hint_frequency: 0.3, # 提示频率 misleading_level: 0.2, # 误导程度 knowledge_boundary: loose # 知识边界严格程度 }, medium: { hint_frequency: 0.15, misleading_level: 0.5, knowledge_boundary: moderate }, hard: { hint_frequency: 0.05, misleading_level: 0.8, knowledge_boundary: strict } } self.current_difficulty self.difficulty_levels[difficulty] def should_give_hint(self, turn_number): 根据当前轮次决定是否给出提示 if turn_number 8: # 最后几轮增加提示概率 base_prob self.current_difficulty[hint_frequency] * 2 else: base_prob self.current_difficulty[hint_frequency] return random.random() base_prob def generate_hint(self, role_description, turn_number): 生成适当难度的提示 hint_intensity min(1.0, turn_number / 5) # 随轮次增加提示强度 if hint_intensity 0.3: return 这个提示很隐晦我的职业与创造有关。 elif hint_intensity 0.6: return 中等提示我生活在19世纪。 else: return 强烈提示我是一位著名的科学家。5.3 多角色支持系统class RoleLibrary: def __init__(self): self.roles { historical_figure: { name: 历史人物, templates: self._load_historical_templates() }, fictional_character: { name: 虚构角色, templates: self._load_fictional_templates() }, professional: { name: 职业人士, templates: self._load_professional_templates() } } def get_random_role(self, categoryNone): 获取随机角色 if category and category in self.roles: templates self.roles[category][templates] else: # 合并所有类别的模板 templates [] for cat in self.roles.values(): templates.extend(cat[templates]) return random.choice(templates) def _load_historical_templates(self): return [ 你是一位文艺复兴时期的艺术家擅长绘画和雕塑对解剖学有深入研究但不知道现代科技。, 你是一位古代哲学家习惯用寓言和比喻回答问题对现代科学概念感到困惑。, 你是一位中世纪骑士重视荣誉和忠诚对现代政治制度不理解。 ]6. 完整示例演示6.1 游戏初始化与运行def main(): # 初始化游戏 role_description 你是一位19世纪的发明家对机械装置有着深厚的热情。 你发明了许多改变世界的机器但你的某些理念在当时被认为过于超前。 你相信电力将改变人类生活但还没有见过计算机或互联网。 你的说话方式正式而富有激情经常使用技术术语。 game RolePlayGame(role_description, modelgpt-3.5-turbo) print( Who am AI 游戏开始 ) print(你有10个问题来猜测我的身份。开始提问吧) print(输入退出结束游戏输入提示获取帮助\n) # 游戏主循环 while game.game_state playing: try: question input(f问题 {game.current_turn 1}/10: ) if question.lower() in [退出, exit, quit]: print(游戏结束) break elif question.lower() in [提示, hint, help]: print(试试问关于职业、时代背景、成就等方面的问题) continue response game.process_question(question) print(fAI: {response}\n) except KeyboardInterrupt: print(\n游戏被用户中断) break except Exception as e: print(f发生错误{e}) # 游戏结束处理 if game.game_state won: print( 恭喜你获胜) elif game.game_state lost: print( 下次再接再厉) print(f正确答案{game.actual_identity}) if __name__ __main__: main()6.2 示例对话流程问题 1/10: 你是现代人吗 AI: 现代我生活在一个人人都为工业进步而兴奋的时代。蒸汽机的声音是我最熟悉的音乐。 问题 2/10: 你的工作和科技有关吗 AI: 确实如此我整天都在工作室里摆弄各种机械装置。最近我在研究一种能稳定传输电力的系统。 问题 3/10: 你听说过计算机吗 AI: 计算机这个词让我想到那些负责计算的职员。我的装置都是机械的靠齿轮和连杆工作。 问题 8/10: 我猜你是尼古拉·特斯拉 AI: 猜对了正是在下。我一直在研究交流电系统相信这将是未来的能源传输方式。7. 常见问题与解决方案7.1 角色一致性失效问题问题现象AI在对话中突然打破角色用现代语言或承认自己是AI解决方案# 加强系统提示词中的角色约束 enhanced_system_prompt 重要你正在进行的是一场严肃的角色扮演。你必须完全沉浸在角色中。 绝对禁止 - 提及AI、语言模型、计算机等现代概念 - 承认自己不是真实人物 - 使用角色认知范围外的知识 如果被问及身份相关的问题可以用以下方式回应 - 我只是一个普通的[角色职业] - 这个问题很有趣但我不太明白你在问什么 - 将话题引导回角色熟悉的领域 7.2 上下文长度限制问题问题现象长对话后AI忘记早期设定的角色特征解决方案def create_summary_prompt(conversation_history, role_description): 创建对话摘要以节省上下文空间 summary f 当前角色{role_description} 对话摘要 - 用户已经问了关于[主题1]、[主题2]的问题 - 角色保持了[特征1]、[特征2]的一致性 - 尚未暴露的关键信息[关键信息1]、[关键信息2] 最新几轮对话详情 {conversation_history[-3:]} # 只保留最近3轮完整对话 return summary7.3 身份过早暴露问题问题现象AI在前期对话中无意给出太多提示解决方案class HintController: def __init__(self): self.reveal_progression [ (1, 3, 只能给出极其模糊的提示), (4, 6, 可以给出中等提示), (7, 9, 可以给出较强提示), (10, 10, 可以确认正确猜测) ] def get_allowed_hint_level(self, current_turn): 根据当前轮次返回允许的提示强度 for start, end, level in self.reveal_progression: if start current_turn end: return level return 无提示8. 性能优化与最佳实践8.1 响应时间优化import asyncio import aiohttp class AsyncAIClient: def __init__(self, api_key, modelgpt-3.5-turbo): self.api_key api_key self.model model self.session None async def __aenter__(self): self.session aiohttp.ClientSession() return self async def __aexit__(self, exc_type, exc_val, exc_tb): await self.session.close() async def generate_response_async(self, messages): 异步生成AI回复 headers { Authorization: fBearer {self.api_key}, Content-Type: application/json } data { model: self.model, messages: messages, max_tokens: 500, temperature: 0.7 } async with self.session.post( https://api.openai.com/v1/chat/completions, headersheaders, jsondata ) as response: result await response.json() return result[choices][0][message][content]8.2 成本控制策略class CostOptimizer: def __init__(self, budget_per_game0.10): # 每游戏最高花费$0.10 self.budget budget_per_game self.cost_so_far 0.0 def estimate_cost(self, prompt_tokens, completion_tokens, model): 估算API调用成本 # 根据OpenAI定价估算 pricing { gpt-3.5-turbo: (0.0015, 0.002), # 输入/输出每1K tokens价格 gpt-4: (0.03, 0.06) } input_cost, output_cost pricing.get(model, (0.0015, 0.002)) cost (prompt_tokens / 1000 * input_cost completion_tokens / 1000 * output_cost) return cost def can_make_request(self, estimated_cost): 检查是否在预算范围内 return self.cost_so_far estimated_cost self.budget8.3 缓存优化import hashlib import pickle from functools import lru_cache class ResponseCache: def __init__(self, max_size1000): self.cache {} self.max_size max_size def _generate_key(self, prompt, parameters): 生成缓存键 content prompt str(parameters) return hashlib.md5(content.encode()).hexdigest() lru_cache(maxsize1000) def get_cached_response(self, prompt, temperature0.7, max_tokens500): 获取缓存响应 key self._generate_key(prompt, (temperature, max_tokens)) return self.cache.get(key) def cache_response(self, prompt, response, parameters): 缓存响应 if len(self.cache) self.max_size: # 移除最旧的缓存项 oldest_key next(iter(self.cache)) del self.cache[oldest_key] key self._generate_key(prompt, parameters) self.cache[key] response通过以上完整的技术实现我们构建了一个功能丰富的AI角色猜测游戏系统。这个系统不仅展示了提示词工程的高级技巧还提供了可扩展的架构设计为更复杂的AI交互应用奠定了基础。