Update app.py
Browse files
app.py
CHANGED
|
@@ -45,9 +45,22 @@ class SpyAgent(BasicAgent):
|
|
| 45 |
super().__init__(name, model_name)
|
| 46 |
self.filtered_history = [] # 存储已过滤的历史记录
|
| 47 |
self.last_filtered_index = 0 # 记录上次过滤到的位置
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 48 |
def filter_new_messages(self):
|
| 49 |
"""只过滤新添加的消息,而不是整个历史记录"""
|
| 50 |
try:
|
|
|
|
|
|
|
|
|
|
|
|
|
| 51 |
raw_history = self.memory.load_history()
|
| 52 |
|
| 53 |
# 如果没有新消息,直接返回现有的过滤历史
|
|
@@ -57,27 +70,27 @@ class SpyAgent(BasicAgent):
|
|
| 57 |
# 获取新消息
|
| 58 |
new_messages = raw_history[self.last_filtered_index:]
|
| 59 |
|
| 60 |
-
# 如果新消息
|
| 61 |
-
if all(("##" in msg and "主持人:" in msg
|
| 62 |
self.filtered_history.extend(new_messages)
|
| 63 |
self.last_filtered_index = len(raw_history)
|
| 64 |
return "\n".join(self.filtered_history)
|
| 65 |
|
| 66 |
-
#
|
| 67 |
new_raw = "\n".join(new_messages)
|
| 68 |
prompt = format_prompt(HISTORY_FILTER_PROMPT, {"raw_history": new_raw})
|
| 69 |
filtered_new = self.llm_caller(prompt)
|
| 70 |
|
| 71 |
# 更新过滤历史和索引
|
| 72 |
-
if filtered_new:
|
| 73 |
self.filtered_history.extend(filtered_new.split("\n"))
|
| 74 |
self.last_filtered_index = len(raw_history)
|
| 75 |
|
| 76 |
-
# 返回完整的过滤历史
|
| 77 |
return "\n".join(self.filtered_history)
|
| 78 |
-
except
|
| 79 |
-
logger.error(f"
|
| 80 |
-
return ""
|
|
|
|
| 81 |
def clear_filtered_history(self):
|
| 82 |
"""清空过滤历史(在新游戏开始时调用)"""
|
| 83 |
self.filtered_history = []
|
|
@@ -97,78 +110,98 @@ class SpyAgent(BasicAgent):
|
|
| 97 |
return filtered_history
|
| 98 |
|
| 99 |
def perceive(self, req=AgentReq):
|
| 100 |
-
|
| 101 |
-
|
| 102 |
-
|
| 103 |
-
#
|
| 104 |
-
self.
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
|
| 114 |
-
|
| 115 |
-
|
| 116 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 117 |
self.memory.append_history(req.name + ': ' + req.message)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 118 |
else:
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
|
| 123 |
-
self.memory.append_history(req.name + ': ' + req.message)
|
| 124 |
-
elif req.status == STATUS_VOTE_RESULT: # 投票环节
|
| 125 |
-
out_player = req.name if req.name else req.message
|
| 126 |
-
if out_player:
|
| 127 |
-
self.memory.append_history('主持人: 投票结果是:{}。##'.format(out_player))
|
| 128 |
-
else:
|
| 129 |
-
self.memory.append_history('主持人: 无人出局。##')
|
| 130 |
-
elif req.status == STATUS_RESULT:
|
| 131 |
-
# 修复问题:确保message是字符串
|
| 132 |
-
result_message = str(req.message) if req.message else "游戏结束"
|
| 133 |
-
self.memory.append_history(f'主持人: {result_message}##')
|
| 134 |
-
else:
|
| 135 |
-
raise NotImplementedError
|
| 136 |
-
|
| 137 |
|
| 138 |
def interact(self, req=AgentReq) -> AgentResp:
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
|
| 150 |
-
|
| 151 |
-
|
| 152 |
-
|
| 153 |
-
|
| 154 |
-
|
| 155 |
-
|
| 156 |
-
|
| 157 |
-
|
| 158 |
-
|
| 159 |
-
|
| 160 |
-
|
| 161 |
-
|
| 162 |
-
|
| 163 |
-
|
| 164 |
-
|
| 165 |
-
|
| 166 |
-
|
| 167 |
-
|
| 168 |
-
|
| 169 |
-
|
| 170 |
-
|
| 171 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 172 |
|
| 173 |
def llm_caller(self, prompt):
|
| 174 |
client = OpenAI(
|
|
|
|
| 45 |
super().__init__(name, model_name)
|
| 46 |
self.filtered_history = [] # 存储已过滤的历史记录
|
| 47 |
self.last_filtered_index = 0 # 记录上次过滤到的位置
|
| 48 |
+
self._name = name
|
| 49 |
+
self._model_name = model_name
|
| 50 |
+
def _ensure_memory_valid(self):
|
| 51 |
+
"""确保memory对象有效,如果无效则尝试修复"""
|
| 52 |
+
if not hasattr(self, 'memory') or not isinstance(self.memory, object) or not hasattr(self.memory, 'append_history'):
|
| 53 |
+
logger.error("内存对象无效,尝试重新初始化")
|
| 54 |
+
super().__init__(self._name, self._model_name)
|
| 55 |
+
return False
|
| 56 |
+
return True
|
| 57 |
def filter_new_messages(self):
|
| 58 |
"""只过滤新添加的消息,而不是整个历史记录"""
|
| 59 |
try:
|
| 60 |
+
# 确认memory有效
|
| 61 |
+
if not self._ensure_memory_valid():
|
| 62 |
+
return "\n".join(self.filtered_history) if self.filtered_history else ""
|
| 63 |
+
|
| 64 |
raw_history = self.memory.load_history()
|
| 65 |
|
| 66 |
# 如果没有新消息,直接返回现有的过滤历史
|
|
|
|
| 70 |
# 获取新消息
|
| 71 |
new_messages = raw_history[self.last_filtered_index:]
|
| 72 |
|
| 73 |
+
# 如果新消息都是裁判消息,直接添加
|
| 74 |
+
if all(isinstance(msg, str) and "##" in msg and "主持人:" in msg for msg in new_messages):
|
| 75 |
self.filtered_history.extend(new_messages)
|
| 76 |
self.last_filtered_index = len(raw_history)
|
| 77 |
return "\n".join(self.filtered_history)
|
| 78 |
|
| 79 |
+
# 使用LLM过滤新消息
|
| 80 |
new_raw = "\n".join(new_messages)
|
| 81 |
prompt = format_prompt(HISTORY_FILTER_PROMPT, {"raw_history": new_raw})
|
| 82 |
filtered_new = self.llm_caller(prompt)
|
| 83 |
|
| 84 |
# 更新过滤历史和索引
|
| 85 |
+
if filtered_new and isinstance(filtered_new, str):
|
| 86 |
self.filtered_history.extend(filtered_new.split("\n"))
|
| 87 |
self.last_filtered_index = len(raw_history)
|
| 88 |
|
|
|
|
| 89 |
return "\n".join(self.filtered_history)
|
| 90 |
+
except Exception as e:
|
| 91 |
+
logger.error(f"过滤消息时发生错误: {str(e)}")
|
| 92 |
+
return "\n".join(self.filtered_history) if self.filtered_history else ""
|
| 93 |
+
|
| 94 |
def clear_filtered_history(self):
|
| 95 |
"""清空过滤历史(在新游戏开始时调用)"""
|
| 96 |
self.filtered_history = []
|
|
|
|
| 110 |
return filtered_history
|
| 111 |
|
| 112 |
def perceive(self, req=AgentReq):
|
| 113 |
+
try :
|
| 114 |
+
logger.info("spy perceive: " + str(req))
|
| 115 |
+
#logger.info("spy perceive: {}".format(req))
|
| 116 |
+
# 确认memory有效
|
| 117 |
+
if not self._ensure_memory_valid():
|
| 118 |
+
# 重新初始化完成后继续
|
| 119 |
+
pass
|
| 120 |
+
if req.status == STATUS_START: # 开始新的一局比赛
|
| 121 |
+
self.memory.clear()
|
| 122 |
+
# 清空过滤历史
|
| 123 |
+
self.clear_filtered_history()
|
| 124 |
+
|
| 125 |
+
self.memory.set_variable("name", req.message)
|
| 126 |
+
self.memory.append_history(
|
| 127 |
+
'主持人: 女士们先生们,欢迎来到《谁是卧底》游戏!我们有一个由6名玩家组成的小组,在其中有一名卧底。让我们开始吧!每个人都会收到一张纸。其中5人的纸上拥有相同的单词,而卧底则会收到含义上相似的单词。我们将大多数人拿到的单词称为"公共词",将卧底拿到的单词称为"卧底词"。一旦你拿到了你的单词,首先需要根据其他人的发言判断自己是否拿到了卧底词。如果判断自己拿到了卧底词,请猜测公共词是什么,然后描述公共词来混淆视听,避免被投票淘汰。如果判断自己拿到了公共词,请思考如何巧妙地描述它而不泄露它,不能让卧底察觉,也要给同伴暗示。每人每轮用一句话描述自己拿到的词语,每个人的描述禁止重复,话中不能出现所持词语。每轮描述完毕,所有在场的人投票选出怀疑是卧底的那个人,得票数最多的人出局。卧底出局则游戏结束,若卧底未出局,游戏继续。现在游戏开始。##')
|
| 128 |
+
|
| 129 |
+
elif req.status == STATUS_DISTRIBUTION: # 分配单词
|
| 130 |
+
self.memory.set_variable("word", req.word)
|
| 131 |
+
self.memory.append_history(
|
| 132 |
+
'主持人: 你好,{},你分配到的单词是:{}##'.format(self.memory.load_variable("name"), req.word))
|
| 133 |
+
elif req.status == STATUS_ROUND: # 发言环节
|
| 134 |
+
if req.name:
|
| 135 |
+
# 其他玩家发言
|
| 136 |
+
self.memory.append_history(req.name + ': ' + req.message)
|
| 137 |
+
else:
|
| 138 |
+
# 主持人发言
|
| 139 |
+
self.memory.append_history('主持人: 现在进入第{}轮。##'.format(str(req.round)))
|
| 140 |
+
self.memory.append_history('主持人: 每个玩家描述自己分配到的单词。##')
|
| 141 |
+
elif req.status == STATUS_VOTE: # 投票环节
|
| 142 |
self.memory.append_history(req.name + ': ' + req.message)
|
| 143 |
+
elif req.status == STATUS_VOTE_RESULT: # 投票环节
|
| 144 |
+
out_player = req.name if req.name else req.message
|
| 145 |
+
if out_player:
|
| 146 |
+
self.memory.append_history('主持人: 投票结果是:{}。##'.format(out_player))
|
| 147 |
+
else:
|
| 148 |
+
self.memory.append_history('主持人: 无人出局。##')
|
| 149 |
+
elif req.status == STATUS_RESULT:
|
| 150 |
+
# 安全处理结果消息
|
| 151 |
+
try:
|
| 152 |
+
result_message = str(req.message) if req.message else "游戏结束"
|
| 153 |
+
self.memory.append_history(f'主持人: {result_message}##')
|
| 154 |
+
except Exception as inner_e:
|
| 155 |
+
logger.error(f"处理游戏结果时出错: {str(inner_e)}")
|
| 156 |
else:
|
| 157 |
+
raise NotImplementedError
|
| 158 |
+
except Exception as e:
|
| 159 |
+
# 修正日志格式问题
|
| 160 |
+
logger.error("perceive错误: " + str(e))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 161 |
|
| 162 |
def interact(self, req=AgentReq) -> AgentResp:
|
| 163 |
+
try :
|
| 164 |
+
# 确认memory有效
|
| 165 |
+
if not self._ensure_memory_valid():
|
| 166 |
+
return AgentResp(success=False, result="系统错误", errMsg="内存对象无效")
|
| 167 |
+
|
| 168 |
+
logger.info("spy interact: " + str(req))
|
| 169 |
+
#logger.info("spy interact: {}".format(req))
|
| 170 |
+
if req.status == STATUS_ROUND:
|
| 171 |
+
# 使用增量过滤
|
| 172 |
+
filtered_history = self.filter_new_messages()
|
| 173 |
+
|
| 174 |
+
prompt = format_prompt(DESC_PROMPT,
|
| 175 |
+
{"name": self.memory.load_variable("name"),
|
| 176 |
+
"word": self.memory.load_variable("word"),
|
| 177 |
+
"history": filtered_history
|
| 178 |
+
})
|
| 179 |
+
logger.info("prompt:" + prompt)
|
| 180 |
+
result = self.llm_caller(prompt)
|
| 181 |
+
logger.info("spy interact result: {}".format(result))
|
| 182 |
+
return AgentResp(success=True, result=result, errMsg=None)
|
| 183 |
+
|
| 184 |
+
elif req.status == STATUS_VOTE:
|
| 185 |
+
self.memory.append_history('主持人: 到了投票的时候了。每个人,请指向你认为可能是卧底的人。##')
|
| 186 |
+
choices = [name for name in req.message.split(",") if name != self.memory.load_variable("name")] # 排除自己
|
| 187 |
+
self.memory.set_variable("choices", choices)
|
| 188 |
+
|
| 189 |
+
# 先过滤历史记录
|
| 190 |
+
filtered_history = self.filter_new_messages()
|
| 191 |
+
prompt = format_prompt(VOTE_PROMPT, {"name": self.memory.load_variable("name"),
|
| 192 |
+
"word": self.memory.load_variable("word"),
|
| 193 |
+
"choices": choices,
|
| 194 |
+
"history": filtered_history
|
| 195 |
+
})
|
| 196 |
+
logger.info("prompt:" + prompt)
|
| 197 |
+
result = self.llm_caller(prompt)
|
| 198 |
+
logger.info("spy interact result: {}".format(result))
|
| 199 |
+
return AgentResp(success=True, result=result, errMsg=None)
|
| 200 |
+
else:
|
| 201 |
+
raise NotImplementedError
|
| 202 |
+
except Exception as e:
|
| 203 |
+
logger.error("interact错误: " + str(e))
|
| 204 |
+
return AgentResp(success=False, result="处理错误", errMsg=str(e))
|
| 205 |
|
| 206 |
def llm_caller(self, prompt):
|
| 207 |
client = OpenAI(
|