Update app.py
Browse files
app.py
CHANGED
|
@@ -51,6 +51,8 @@ class SpyAgent(BasicAgent):
|
|
| 51 |
self.memory.clear()
|
| 52 |
self.memory.set_variable("name", req.message.strip())
|
| 53 |
self.memory.set_variable('history', [])
|
|
|
|
|
|
|
| 54 |
self.memory.set_variable('sim_word', "") # 空字符串而非空列表
|
| 55 |
self.memory.set_variable('spy_word', "") # 新增:可能的卧底词
|
| 56 |
self.memory.set_variable("alive_agents", set([req.message.strip()]))
|
|
@@ -190,70 +192,73 @@ class SpyAgent(BasicAgent):
|
|
| 190 |
if name != self.memory.load_variable("name")
|
| 191 |
and name in self.memory.load_variable('alive_agents')])
|
| 192 |
def detect_spy_word(self):
|
| 193 |
-
"""分析历史发言,尝试识别卧底词(平民使用)"""
|
| 194 |
-
|
| 195 |
-
if self.identity_identify() <= 0 or self.get_prior_speaker_count() < 2: # 改为2个就可以尝试推测
|
| 196 |
return None
|
| 197 |
|
| 198 |
speak_history = self.memory.load_variable('speak_history')
|
| 199 |
if not speak_history:
|
| 200 |
return None
|
| 201 |
|
| 202 |
-
# 获取自己的词和可能的平民词
|
| 203 |
my_word = self.memory.load_variable("word")
|
| 204 |
|
| 205 |
-
# 构建更直接的推理提示
|
| 206 |
prompt = []
|
| 207 |
prompt.append(f'你正在玩《谁是卧底》游戏,你拿到的词是"{my_word}",你是平民。')
|
| 208 |
prompt.append('作为平民,你需要找出谁可能是卧底以及他们的卧底词是什么。')
|
| 209 |
prompt.append('游戏规则:6名玩家中,5人拿到相同的平民词,1人拿到与平民词相关但不同的卧底词。')
|
| 210 |
prompt.append(f'请分析以下玩家发言,判断谁可能拿到了与"{my_word}"相近但不同的词:\n')
|
| 211 |
|
| 212 |
-
# 添加玩家发言
|
| 213 |
for name, speaks in speak_history.items():
|
| 214 |
if name != self.memory.load_variable('name'):
|
| 215 |
for i, speak in enumerate(speaks):
|
| 216 |
prompt.append(f"[轮次{i+1}] {name}: {speak}\n")
|
| 217 |
|
| 218 |
-
prompt.append('\n请
|
| 219 |
-
prompt.append('
|
| 220 |
-
prompt.append('
|
| 221 |
-
prompt.append('
|
| 222 |
-
prompt.append('\n如果所有玩家都在描述同一个词,且你
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 223 |
|
| 224 |
-
|
| 225 |
-
|
| 226 |
|
| 227 |
-
#
|
| 228 |
-
|
| 229 |
-
|
| 230 |
-
|
| 231 |
-
|
| 232 |
-
|
| 233 |
-
|
| 234 |
-
|
| 235 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 236 |
break
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 237 |
|
| 238 |
-
|
| 239 |
-
cleaned_word = spy_word.strip().strip('"\'[]()()""「」『』').strip()
|
| 240 |
-
|
| 241 |
-
# 处理冒号
|
| 242 |
-
if ":" in cleaned_word or ":" in cleaned_word:
|
| 243 |
-
parts = re.split(r'[::]', cleaned_word)
|
| 244 |
-
cleaned_word = parts[-1].strip()
|
| 245 |
-
|
| 246 |
-
# 扩大拒绝词列表
|
| 247 |
-
reject_patterns = ["未知", "不清楚", "无法确定", "不确定", "无法判断", "无法推理",
|
| 248 |
-
"无法识别", "难以确定", "没有足够", "不能确定"]
|
| 249 |
-
|
| 250 |
-
# 更灵活的验证条件
|
| 251 |
if (not any(pattern in cleaned_word.lower() for pattern in reject_patterns) and
|
| 252 |
len(cleaned_word) < 25 and len(cleaned_word) > 1 and
|
| 253 |
cleaned_word != my_word):
|
| 254 |
|
| 255 |
-
|
| 256 |
-
|
|
|
|
| 257 |
|
| 258 |
return None
|
| 259 |
def detect_civilian_word(self):
|
|
@@ -368,7 +373,13 @@ class SpyAgent(BasicAgent):
|
|
| 368 |
# '2)你可以先根据自己拿到的词,以及其他玩家的发言跟自己的词是不是相关,来判断自己是多数的平民、还是少数的卧底;')
|
| 369 |
self.memory.append_history(
|
| 370 |
'2)尽可能简短、模糊描述自己的词汇,可以使用比喻等手法,隐晦模糊地描述自己的词汇。避免暴露太多特征,仅使用一小句;示例:【正方形】-这是一种形状,在生活中很常见')
|
| 371 |
-
self.memory.append_history('3)你应该根据自己拿到的词,通过猜测可能的对手词是什么
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 372 |
self.memory.append_history(
|
| 373 |
'4)如果你明确判断出自己是卧底,那你完全可以直接描述平民词来彻底伪装自己;否则,你应该模糊描述词汇,避免暴露太多特征;')
|
| 374 |
self.memory.append_history(
|
|
@@ -583,16 +594,22 @@ class SpyAgent(BasicAgent):
|
|
| 583 |
)
|
| 584 |
|
| 585 |
result = completion.choices[0].message.content.lstrip('\n\t\r')
|
|
|
|
| 586 |
|
| 587 |
-
|
|
|
|
| 588 |
|
|
|
|
| 589 |
session_data = [{'role': 'assistant', 'content': result}]
|
| 590 |
-
name_extract_prompt = '
|
| 591 |
-
|
| 592 |
-
|
| 593 |
completion = client.chat.completions.create(
|
| 594 |
model=self.model_name,
|
| 595 |
-
messages=
|
|
|
|
|
|
|
|
|
|
|
|
|
| 596 |
)
|
| 597 |
|
| 598 |
return completion.choices[0].message.content.lstrip('\n\t\r')
|
|
|
|
| 51 |
self.memory.clear()
|
| 52 |
self.memory.set_variable("name", req.message.strip())
|
| 53 |
self.memory.set_variable('history', [])
|
| 54 |
+
self.memory.set_variable('spy_player', "") # 可能的卧底玩家
|
| 55 |
+
self.memory.set_variable('spy_analysis', "") # 卧底分析详情
|
| 56 |
self.memory.set_variable('sim_word', "") # 空字符串而非空列表
|
| 57 |
self.memory.set_variable('spy_word', "") # 新增:可能的卧底词
|
| 58 |
self.memory.set_variable("alive_agents", set([req.message.strip()]))
|
|
|
|
| 192 |
if name != self.memory.load_variable("name")
|
| 193 |
and name in self.memory.load_variable('alive_agents')])
|
| 194 |
def detect_spy_word(self):
|
| 195 |
+
"""分析历史发言,尝试识别卧底词和卧底玩家(平民使用)"""
|
| 196 |
+
if self.identity_identify() <= 0 or self.get_prior_speaker_count() < 2:
|
|
|
|
| 197 |
return None
|
| 198 |
|
| 199 |
speak_history = self.memory.load_variable('speak_history')
|
| 200 |
if not speak_history:
|
| 201 |
return None
|
| 202 |
|
|
|
|
| 203 |
my_word = self.memory.load_variable("word")
|
| 204 |
|
|
|
|
| 205 |
prompt = []
|
| 206 |
prompt.append(f'你正在玩《谁是卧底》游戏,你拿到的词是"{my_word}",你是平民。')
|
| 207 |
prompt.append('作为平民,你需要找出谁可能是卧底以及他们的卧底词是什么。')
|
| 208 |
prompt.append('游戏规则:6名玩家中,5人拿到相同的平民词,1人拿到与平民词相关但不同的卧底词。')
|
| 209 |
prompt.append(f'请分析以下玩家发言,判断谁可能拿到了与"{my_word}"相近但不同的词:\n')
|
| 210 |
|
| 211 |
+
# 添加玩家发言
|
| 212 |
for name, speaks in speak_history.items():
|
| 213 |
if name != self.memory.load_variable('name'):
|
| 214 |
for i, speak in enumerate(speaks):
|
| 215 |
prompt.append(f"[轮次{i+1}] {name}: {speak}\n")
|
| 216 |
|
| 217 |
+
prompt.append('\n请按以下格式回答:')
|
| 218 |
+
prompt.append('可疑玩家:[玩家名字]')
|
| 219 |
+
prompt.append('可疑理由:[简短说明为什么这个玩家可疑]')
|
| 220 |
+
prompt.append('卧底词:[你推测的卧底词]')
|
| 221 |
+
prompt.append('\n如果所有玩家都在描述同一个词,且你无法判断,则回答:')
|
| 222 |
+
prompt.append('可疑玩家:未知')
|
| 223 |
+
prompt.append('可疑理由:信息不足')
|
| 224 |
+
prompt.append('卧底词:未知')
|
| 225 |
+
|
| 226 |
+
spy_detection = self.llm_caller(''.join(prompt))
|
| 227 |
+
logger.info(f"卧底识别原始返回: '{spy_detection}'")
|
| 228 |
|
| 229 |
+
# 存储完整分析结果
|
| 230 |
+
self.memory.set_variable('spy_analysis', spy_detection)
|
| 231 |
|
| 232 |
+
# 提取关键信息
|
| 233 |
+
spy_name = None
|
| 234 |
+
spy_word = None
|
| 235 |
+
|
| 236 |
+
# 提取可疑玩家
|
| 237 |
+
name_match = re.search(r'可疑玩家[::]\s*(.+?)(?:\n|$)', spy_detection)
|
| 238 |
+
if name_match:
|
| 239 |
+
suspect = name_match.group(1).strip()
|
| 240 |
+
if not any(word in suspect.lower() for word in ["未知", "不确定", "无法判断"]):
|
| 241 |
+
for player in speak_history.keys():
|
| 242 |
+
if player in suspect and player != self.memory.load_variable('name'):
|
| 243 |
+
spy_name = player
|
| 244 |
+
self.memory.set_variable('spy_player', player)
|
| 245 |
+
logger.info(f"成功识别可疑卧底: '{player}'")
|
| 246 |
break
|
| 247 |
+
|
| 248 |
+
# 提取卧底词
|
| 249 |
+
word_match = re.search(r'卧底词[::]\s*(.+?)(?:\n|$)', spy_detection)
|
| 250 |
+
if word_match:
|
| 251 |
+
word = word_match.group(1).strip()
|
| 252 |
+
cleaned_word = word.strip().strip('"\'[]()()""「」『』').strip()
|
| 253 |
|
| 254 |
+
reject_patterns = ["未知", "不清楚", "无法确定", "不确定", "无法判断"]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 255 |
if (not any(pattern in cleaned_word.lower() for pattern in reject_patterns) and
|
| 256 |
len(cleaned_word) < 25 and len(cleaned_word) > 1 and
|
| 257 |
cleaned_word != my_word):
|
| 258 |
|
| 259 |
+
spy_word = cleaned_word
|
| 260 |
+
logger.info(f"成功推理出卧底词: '{spy_word}'")
|
| 261 |
+
return spy_word
|
| 262 |
|
| 263 |
return None
|
| 264 |
def detect_civilian_word(self):
|
|
|
|
| 373 |
# '2)你可以先根据自己拿到的词,以及其他玩家的发言跟自己的词是不是相关,来判断自己是多数的平民、还是少数的卧底;')
|
| 374 |
self.memory.append_history(
|
| 375 |
'2)尽可能简短、模糊描述自己的词汇,可以使用比喻等手法,隐晦模糊地描述自己的词汇。避免暴露太多特征,仅使用一小句;示例:【正方形】-这是一种形状,在生活中很常见')
|
| 376 |
+
self.memory.append_history('3)你应该根据自己拿到的词,通过猜测可能的对手词是什么')
|
| 377 |
+
spy_player = self.memory.load_variable('spy_player')
|
| 378 |
+
spy_analysis = self.memory.load_variable('spy_analysis')
|
| 379 |
+
if spy_player and spy_player in choices:
|
| 380 |
+
self.memory.append_history(f'3)通过分析,你认为"{spy_player}"最可能是卧底,推测出的卧底词是"{self.memory.load_variable("spy_word")}"。')
|
| 381 |
+
else:
|
| 382 |
+
self.memory.append_history(f'3)在上一阶段,你推测出的卧底词是"{self.memory.load_variable("spy_word")}"。')
|
| 383 |
self.memory.append_history(
|
| 384 |
'4)如果你明确判断出自己是卧底,那你完全可以直接描述平民词来彻底伪装自己;否则,你应该模糊描述词汇,避免暴露太多特征;')
|
| 385 |
self.memory.append_history(
|
|
|
|
| 594 |
)
|
| 595 |
|
| 596 |
result = completion.choices[0].message.content.lstrip('\n\t\r')
|
| 597 |
+
logger.info("vote analysis result: {}".format(result))
|
| 598 |
|
| 599 |
+
# 保存投票分析结果
|
| 600 |
+
self.memory.set_variable('vote_analysis', result)
|
| 601 |
|
| 602 |
+
# 提取具体的投票对象
|
| 603 |
session_data = [{'role': 'assistant', 'content': result}]
|
| 604 |
+
name_extract_prompt = '请从你的分析中,明确指出你最终决定投票的玩家名字。请只回答玩家名字,不要有任何额外内容。'
|
| 605 |
+
|
|
|
|
| 606 |
completion = client.chat.completions.create(
|
| 607 |
model=self.model_name,
|
| 608 |
+
messages=[
|
| 609 |
+
{'role': 'user', 'content': prompt},
|
| 610 |
+
{'role': 'assistant', 'content': result},
|
| 611 |
+
{'role': 'user', 'content': name_extract_prompt}
|
| 612 |
+
]
|
| 613 |
)
|
| 614 |
|
| 615 |
return completion.choices[0].message.content.lstrip('\n\t\r')
|