ChoCoFly commited on
Commit
69d308e
·
verified ·
1 Parent(s): 00cce77

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +83 -55
app.py CHANGED
@@ -192,104 +192,132 @@ class SpyAgent(BasicAgent):
192
  def detect_spy_word(self):
193
  """分析历史发言,尝试识别卧底词(平民使用)"""
194
  # 如果自己是卧底或者没有足够发言,跳过
195
- if self.identity_identify() <= 0 or self.get_prior_speaker_count() < 3:
196
  return None
197
-
198
  speak_history = self.memory.load_variable('speak_history')
199
  if not speak_history:
200
  return None
201
 
202
- # 构建推理提示
 
 
 
203
  prompt = []
204
- prompt.append('你《谁是卧底》游戏的平民玩家需要找出谁卧底。')
205
- prompt.append(f'你拿到的平民词是"{self.memory.load_variable("word")}"。')
206
  prompt.append('游戏规则:6名玩家中,5人拿到相同的平民词,1人拿到与平民词相关但不同的卧底词。')
207
- prompt.append('你需要分析其他玩家发言,找出谁可能是卧底,以及他们可能拿到的卧底是什么。')
208
- prompt.append('请仔细分析以下玩家发言,寻找与平民词描述不一致的地方:\n')
209
 
210
- # 添加玩家发言
211
  for name, speaks in speak_history.items():
212
  if name != self.memory.load_variable('name'):
213
- for speak in speaks:
214
- prompt.append(f"{name}: {speak}\n")
215
 
216
- prompt.append('\n你需要:')
217
- prompt.append('1. 分析每个玩家发言是否与平民词一致')
218
- prompt.append('2. 找出可能的不一致描述')
219
- prompt.append('3. 推测可能的卧底词')
220
- prompt.append('\n请直接回答推测的卧底词(单词)不要有任何其他内容。如果无法确定,只回答"未知"。')
221
 
222
  spy_word = self.llm_caller(''.join(prompt))
223
  logger.info(f"卧底词推理原始返回: '{spy_word}'")
224
 
225
- # 处理返回结果(与处理平民词类似的清理逻辑)
226
  if spy_word:
 
 
 
 
 
 
 
 
 
 
227
  cleaned_word = spy_word.strip().strip('"\'[]()()""「」『』').strip()
228
 
229
- # 验证结果是否有效
230
- reject_words = ["未知", "不清楚", "无法确定"]
231
- if (not any(reject in cleaned_word for reject in reject_words) and
232
- len(cleaned_word) < 20 and cleaned_word != self.memory.load_variable("word")):
 
 
 
 
 
 
 
 
 
233
 
234
  logger.info(f"成功推理出卧底词: '{cleaned_word}'")
235
  return cleaned_word
236
 
237
  return None
238
  def detect_civilian_word(self):
239
- """分析历史发言,尝试识别平民词"""
240
  speak_history = self.memory.load_variable('speak_history')
241
  if not speak_history:
242
  return None
243
 
244
- # 构建推理提示
 
245
  prompt = []
246
- prompt.append('你是《谁是卧底》游戏的评审,需要推出玩家们描述的词语。')
247
- prompt.append(f'已知一名玩家的词是"{self.memory.load_variable("word")}",有理由相信大多数其他玩家在描述另一个相关但不同的词。')
248
- prompt.append('《谁是卧底》游戏规则:5名玩家拿到相同的平民词,1名玩家拿到不同的卧底词。')
249
- prompt.append('请仔细分析以下玩家发言,推理出大多数玩家可能在描述的词:\n')
250
-
 
251
  for name, speaks in speak_history.items():
252
  if name != self.memory.load_variable('name'):
253
- for speak in speaks:
254
- prompt.append(f"{name}: {speak}\n")
 
 
 
 
 
 
 
255
 
256
- prompt.append('\n推理步骤:')
257
- prompt.append('1. 分析每个玩家发言中描述的特征')
258
- prompt.append('2. 找出发言中的共同特征')
259
- prompt.append('3. 根据这些特征,推测最可能的词语')
260
- prompt.append('4. 考虑这个词与已知词"'+self.memory.load_variable("word")+'"的关系,两者应该相似但有明显区别')
261
- prompt.append('\n请直接回答你推理出的词语(单词)。如果实在无法推理,只回答"未知"。')
262
- # 调用LLM进行推理
263
  civilian_word = self.llm_caller(''.join(prompt))
264
  logger.info(f"平民词推理原始返回: '{civilian_word}'")
265
 
266
- # 处理返回结果
267
  if civilian_word:
268
- # 清理结果,移除常见格式标记和说明文本
269
- cleaned_word = civilian_word
 
 
 
 
 
 
 
 
 
 
 
 
 
270
 
271
- # 如果包含多行,尝试提取最后一行作为答案
272
- if "\n" in cleaned_word:
273
- lines = cleaned_word.strip().split("\n")
274
- for line in reversed(lines):
275
- if line.strip() and len(line.strip()) < 30: # 找到最后一个非空且较短的行
276
- cleaned_word = line.strip()
277
- break
278
-
279
- # 清理常见的格式符号和修饰语
280
- cleaned_word = cleaned_word.strip().strip('"\'[]()()""「」『』').strip()
281
 
282
- # 如果结果包含冒号,取冒号后面的部分
283
  if ":" in cleaned_word or ":" in cleaned_word:
284
  parts = re.split(r'[::]', cleaned_word)
285
  cleaned_word = parts[-1].strip()
286
-
287
  logger.info(f"清理后的平民词推理结果: '{cleaned_word}'")
288
 
289
- # 验证结果是否有效
290
- reject_words = ["未知", "不清楚", "无法确定", "不确定", "无法判断", "无法推理"]
291
- if (not any(reject in cleaned_word for reject in reject_words) and
292
- len(cleaned_word) < 20 and len(cleaned_word) > 0 and
293
  cleaned_word != self.memory.load_variable("word")):
294
 
295
  logger.info(f"成功推理出平民词: '{cleaned_word}'")
 
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('1. 列出可疑描述特征')
220
+ prompt.append('2. 考虑与你的词"' + my_word + '"最相近但有关键区别的可能卧底词')
221
+ prompt.append('3. 最后直接回答你认为的卧底词(单词或短词)')
222
+ prompt.append('\n如果所有玩家都在描述同一个词,且确定无法判断卧底词,只回答"未知"。')
223
 
224
  spy_word = self.llm_caller(''.join(prompt))
225
  logger.info(f"卧底词推理原始返回: '{spy_word}'")
226
 
227
+ # 处理返回结果
228
  if spy_word:
229
+ # 先检查是否包含长分析,提取最后一段或冒号后内容
230
+ if len(spy_word) > 50 and "\n" in spy_word:
231
+ # 尝试从最后几行提取答案
232
+ lines = spy_word.strip().split("\n")
233
+ for line in reversed(lines):
234
+ if len(line.strip()) < 30 and line.strip() and not line.strip().startswith("1.") and not line.strip().startswith("2."):
235
+ spy_word = line.strip()
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
  logger.info(f"成功推理出卧底词: '{cleaned_word}'")
256
  return cleaned_word
257
 
258
  return None
259
  def detect_civilian_word(self):
260
+ """分析历史发言,尝试识别平民词(卧底使用)"""
261
  speak_history = self.memory.load_variable('speak_history')
262
  if not speak_history:
263
  return None
264
 
265
+
266
+ # 构建更清晰的提示
267
  prompt = []
268
+ prompt.append('你是《谁是卧底》游戏卧底,需要推大多数玩家拿到的词语。')
269
+ prompt.append(f'你拿到卧底词是"{self.memory.load_variable("word")}"。')
270
+ prompt.append('游戏规则:6名玩家中,5人拿到相同的平民词,1人(你)拿到不同的卧底词。')
271
+ prompt.append('请分析以下玩家发言,出大多数玩家可能在描述的共同:\n')
272
+
273
+ # 添加玩家发言
274
  for name, speaks in speak_history.items():
275
  if name != self.memory.load_variable('name'):
276
+ for i, speak in enumerate(speaks):
277
+ if speak.strip():
278
+ prompt.append(f"[轮次{i+1}] {name}: {speak}\n")
279
+
280
+ prompt.append('\n请分析步骤:')
281
+ prompt.append('1. 找出发言中的共同主题和特征')
282
+ prompt.append('2. 考虑这些特征最可能对应的词语')
283
+ prompt.append('3. 考虑这个词与你的词"'+self.memory.load_variable("word")+'"的关系')
284
+ prompt.append('\n请直接输出你认为大多数玩家在描述的词语(单个词)。不要输出分析过程。')
285
 
 
 
 
 
 
 
 
286
  civilian_word = self.llm_caller(''.join(prompt))
287
  logger.info(f"平民词推理原始返回: '{civilian_word}'")
288
 
289
+ # 增强的结果处理
290
  if civilian_word:
291
+ # 是长回答尝试提取最后一句或最简短句子
292
+ if len(civilian_word) > 30:
293
+ if "\n" in civilian_word:
294
+ lines = [line for line in civilian_word.strip().split("\n") if line.strip()]
295
+ for line in reversed(lines):
296
+ if 1 < len(line.strip()) < 30:
297
+ civilian_word = line.strip()
298
+ break
299
+ # 如果包含句号,尝试提取最后一句
300
+ elif "。" in civilian_word:
301
+ sentences = civilian_word.split("。")
302
+ for sentence in reversed(sentences):
303
+ if 1 < len(sentence.strip()) < 30:
304
+ civilian_word = sentence.strip()
305
+ break
306
 
307
+ # 清理格式标记
308
+ cleaned_word = civilian_word.strip().strip('"\'[]()()""「」『』').strip()
 
 
 
 
 
 
 
 
309
 
310
+ # 处理冒号
311
  if ":" in cleaned_word or ":" in cleaned_word:
312
  parts = re.split(r'[::]', cleaned_word)
313
  cleaned_word = parts[-1].strip()
314
+
315
  logger.info(f"清理后的平民词推理结果: '{cleaned_word}'")
316
 
317
+ # 更宽松的验证条件
318
+ reject_words = ["未知", "不清楚", "无法", "不确定", "难以"]
319
+ if (not any(reject in cleaned_word.lower() for reject in reject_words) and
320
+ len(cleaned_word) > 1 and len(cleaned_word) < 25 and
321
  cleaned_word != self.memory.load_variable("word")):
322
 
323
  logger.info(f"成功推理出平民词: '{cleaned_word}'")