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

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +60 -43
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('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):
@@ -368,7 +373,13 @@ class SpyAgent(BasicAgent):
368
  # '2)你可以先根据自己拿到的词,以及其他玩家的发言跟自己的词是不是相关,来判断自己是多数的平民、还是少数的卧底;')
369
  self.memory.append_history(
370
  '2)尽可能简短、模糊描述自己的词汇,可以使用比喻等手法,隐晦模糊地描述自己的词汇。避免暴露太多特征,仅使用一小句;示例:【正方形】-这是一种形状,在生活中很常见')
371
- self.memory.append_history('3)你应该根据自己拿到的词,通过猜测可能的对手词是什么,来印证自己的猜测;在上一阶段推测出的卧底词是"{}"。'.format(self.memory.load_variable('spy_word')))
 
 
 
 
 
 
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
- logger.info("analysis result: {}".format(result))
 
588
 
 
589
  session_data = [{'role': 'assistant', 'content': result}]
590
- name_extract_prompt = '好的,请从你上述分析中,明确最终需要投票玩家名字。请直接输出名字,不要输出任何其他内容。'
591
- session_data.append({'role': 'user', 'content': name_extract_prompt})
592
-
593
  completion = client.chat.completions.create(
594
  model=self.model_name,
595
- messages=session_data
 
 
 
 
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')