feat(chat): 增强prompt构建功能并优化回复逻辑
- 为HfcContext和ChatStream添加focus_energy配置支持 - 修复默认回复生成器中识别自身消息的逻辑 - 完整实现prompt构建中的表达习惯、记忆、工具信息和知识模块 - 优化错误处理,使用原生异常链式传递 - 确保数据库操作中focus_energy字段的持久化 这些改进提升了聊天系统的上下文感知能力和回复质量,同时增强了模块的健壮性和可维护性。
This commit is contained in:
@@ -5,6 +5,7 @@ from src.person_info.relationship_builder_manager import RelationshipBuilder
|
||||
from src.chat.express.expression_learner import ExpressionLearner
|
||||
from src.chat.planner_actions.action_manager import ActionManager
|
||||
from src.chat.chat_loop.hfc_utils import CycleDetail
|
||||
from src.config.config import global_config
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .sleep_manager.wakeup_manager import WakeUpManager
|
||||
@@ -64,7 +65,8 @@ class HfcContext:
|
||||
self.energy_manager: Optional["EnergyManager"] = None
|
||||
self.sleep_manager: Optional["SleepManager"] = None
|
||||
|
||||
self.focus_energy = 1
|
||||
# 从聊天流获取focus_energy,如果没有则使用配置文件中的值
|
||||
self.focus_energy = getattr(self.chat_stream, "focus_energy", global_config.chat.focus_value)
|
||||
self.no_reply_consecutive = 0
|
||||
self.total_interest = 0.0
|
||||
# breaking形式下的累积兴趣值
|
||||
|
||||
@@ -83,7 +83,8 @@ class ChatStream:
|
||||
self.sleep_pressure = data.get("sleep_pressure", 0.0) if data else 0.0
|
||||
self.saved = False
|
||||
self.context: ChatMessageContext = None # type: ignore # 用于存储该聊天的上下文信息
|
||||
self.focus_energy = 1
|
||||
# 从配置文件中读取focus_value,如果没有则使用默认值1.0
|
||||
self.focus_energy = data.get("focus_energy", global_config.chat.focus_value) if data else global_config.chat.focus_value
|
||||
self.no_reply_consecutive = 0
|
||||
self.breaking_accumulated_interest = 0.0
|
||||
|
||||
@@ -98,6 +99,7 @@ class ChatStream:
|
||||
"last_active_time": self.last_active_time,
|
||||
"energy_value": self.energy_value,
|
||||
"sleep_pressure": self.sleep_pressure,
|
||||
"focus_energy": self.focus_energy,
|
||||
"breaking_accumulated_interest": self.breaking_accumulated_interest,
|
||||
}
|
||||
|
||||
@@ -360,6 +362,7 @@ class ChatManager:
|
||||
"group_name": group_info_d["group_name"] if group_info_d else "",
|
||||
"energy_value": s_data_dict.get("energy_value", 5.0),
|
||||
"sleep_pressure": s_data_dict.get("sleep_pressure", 0.0),
|
||||
"focus_energy": s_data_dict.get("focus_energy", global_config.chat.focus_value),
|
||||
}
|
||||
|
||||
# 根据数据库类型选择插入语句
|
||||
@@ -421,6 +424,7 @@ class ChatManager:
|
||||
"last_active_time": model_instance.last_active_time,
|
||||
"energy_value": model_instance.energy_value,
|
||||
"sleep_pressure": model_instance.sleep_pressure,
|
||||
"focus_energy": getattr(model_instance, "focus_energy", global_config.chat.focus_value),
|
||||
}
|
||||
loaded_streams_data.append(data_for_from_dict)
|
||||
session.commit()
|
||||
|
||||
@@ -139,8 +139,6 @@ def init_prompt():
|
||||
--------------------------------
|
||||
{time_block}
|
||||
|
||||
{reply_target_block}
|
||||
|
||||
注意不要复读你前面发过的内容,意思相近也不行。
|
||||
|
||||
请注意不要输出多余内容(包括前后缀,冒号和引号,at或 @等 )。只输出回复内容。
|
||||
@@ -832,16 +830,22 @@ class DefaultReplyer:
|
||||
reply_message.get("user_id"), # type: ignore
|
||||
)
|
||||
person_name = await person_info_manager.get_value(person_id, "person_name")
|
||||
sender = person_name
|
||||
|
||||
# 检查是否是bot自己的名字,如果是则替换为"(你)"
|
||||
bot_user_id = str(global_config.bot.qq_account)
|
||||
current_user_id = person_info_manager.get_value_sync(person_id, "user_id")
|
||||
current_platform = reply_message.get("chat_info_platform")
|
||||
|
||||
if current_user_id == bot_user_id and current_platform == global_config.bot.platform:
|
||||
sender = f"{person_name}(你)"
|
||||
else:
|
||||
# 如果不是bot自己,直接使用person_name
|
||||
sender = person_name
|
||||
target = reply_message.get("processed_plain_text")
|
||||
|
||||
person_info_manager = get_person_info_manager()
|
||||
person_id = person_info_manager.get_person_id_by_person_name(sender)
|
||||
user_id = person_info_manager.get_value_sync(person_id, "user_id")
|
||||
platform = chat_stream.platform
|
||||
if user_id == global_config.bot.qq_account and platform == global_config.bot.platform:
|
||||
logger.warning("选取了自身作为回复对象,跳过构建prompt")
|
||||
return ""
|
||||
|
||||
target = replace_user_references_sync(target, chat_stream.platform, replace_bot_name=True)
|
||||
|
||||
|
||||
@@ -312,16 +312,15 @@ class Prompt:
|
||||
|
||||
except asyncio.TimeoutError as e:
|
||||
logger.error(f"构建Prompt超时: {e}")
|
||||
raise TimeoutError(f"构建Prompt超时: {e}")
|
||||
raise TimeoutError(f"构建Prompt超时: {e}") from e
|
||||
except Exception as e:
|
||||
logger.error(f"构建Prompt失败: {e}")
|
||||
raise RuntimeError(f"构建Prompt失败: {e}")
|
||||
raise RuntimeError(f"构建Prompt失败: {e}") from e
|
||||
|
||||
async def _build_context_data(self) -> Dict[str, Any]:
|
||||
"""构建智能上下文数据"""
|
||||
# 并行执行所有构建任务
|
||||
start_time = time.time()
|
||||
timing_logs = {}
|
||||
|
||||
try:
|
||||
# 准备构建任务
|
||||
@@ -381,7 +380,6 @@ class Prompt:
|
||||
results = []
|
||||
for i in range(0, len(tasks), max_concurrent_tasks):
|
||||
batch_tasks = tasks[i : i + max_concurrent_tasks]
|
||||
batch_names = task_names[i : i + max_concurrent_tasks]
|
||||
|
||||
batch_results = await asyncio.wait_for(
|
||||
asyncio.gather(*batch_tasks, return_exceptions=True), timeout=timeout_seconds
|
||||
@@ -520,13 +518,99 @@ class Prompt:
|
||||
|
||||
async def _build_expression_habits(self) -> Dict[str, Any]:
|
||||
"""构建表达习惯"""
|
||||
# 简化的实现,完整实现需要导入相关模块
|
||||
return {"expression_habits_block": ""}
|
||||
if not global_config.expression.enable_expression:
|
||||
return {"expression_habits_block": ""}
|
||||
|
||||
try:
|
||||
from src.chat.express.expression_selector import ExpressionSelector
|
||||
|
||||
# 获取聊天历史用于表情选择
|
||||
chat_history = ""
|
||||
if self.parameters.message_list_before_now_long:
|
||||
recent_messages = self.parameters.message_list_before_now_long[-10:]
|
||||
chat_history = build_readable_messages(
|
||||
recent_messages,
|
||||
replace_bot_name=True,
|
||||
timestamp_mode="normal",
|
||||
truncate=True
|
||||
)
|
||||
|
||||
# 创建表情选择器
|
||||
expression_selector = ExpressionSelector(self.parameters.chat_id)
|
||||
|
||||
# 选择合适的表情
|
||||
selected_expressions = await expression_selector.select_suitable_expressions_llm(
|
||||
chat_history=chat_history,
|
||||
current_message=self.parameters.target,
|
||||
emotional_tone="neutral",
|
||||
topic_type="general"
|
||||
)
|
||||
|
||||
# 构建表达习惯块
|
||||
if selected_expressions:
|
||||
style_habits_str = "\n".join([f"- {expr}" for expr in selected_expressions])
|
||||
expression_habits_block = f"你可以参考以下的语言习惯,当情景合适就使用,但不要生硬使用,以合理的方式结合到你的回复中:\n{style_habits_str}"
|
||||
else:
|
||||
expression_habits_block = ""
|
||||
|
||||
return {"expression_habits_block": expression_habits_block}
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"构建表达习惯失败: {e}")
|
||||
return {"expression_habits_block": ""}
|
||||
|
||||
async def _build_memory_block(self) -> Dict[str, Any]:
|
||||
"""构建记忆块"""
|
||||
# 简化的实现
|
||||
return {"memory_block": ""}
|
||||
if not global_config.memory.enable_memory:
|
||||
return {"memory_block": ""}
|
||||
|
||||
try:
|
||||
from src.chat.memory_system.memory_activator import MemoryActivator
|
||||
from src.chat.memory_system.async_instant_memory_wrapper import async_memory
|
||||
|
||||
# 获取聊天历史
|
||||
chat_history = ""
|
||||
if self.parameters.message_list_before_now_long:
|
||||
recent_messages = self.parameters.message_list_before_now_long[-20:]
|
||||
chat_history = build_readable_messages(
|
||||
recent_messages,
|
||||
replace_bot_name=True,
|
||||
timestamp_mode="normal",
|
||||
truncate=True
|
||||
)
|
||||
|
||||
# 激活长期记忆
|
||||
memory_activator = MemoryActivator()
|
||||
running_memories = await memory_activator.activate_memory_with_chat_history(
|
||||
chat_history=chat_history,
|
||||
target_user=self.parameters.sender,
|
||||
chat_id=self.parameters.chat_id
|
||||
)
|
||||
|
||||
# 获取即时记忆
|
||||
instant_memory = await async_memory.get_memory_with_fallback(
|
||||
chat_id=self.parameters.chat_id,
|
||||
target_user=self.parameters.sender
|
||||
)
|
||||
|
||||
# 构建记忆块
|
||||
memory_parts = []
|
||||
|
||||
if running_memories:
|
||||
memory_parts.append("以下是当前在聊天中,你回忆起的记忆:")
|
||||
for memory in running_memories:
|
||||
memory_parts.append(f"- {memory['content']}")
|
||||
|
||||
if instant_memory:
|
||||
memory_parts.append(f"- {instant_memory}")
|
||||
|
||||
memory_block = "\n".join(memory_parts) if memory_parts else ""
|
||||
|
||||
return {"memory_block": memory_block}
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"构建记忆块失败: {e}")
|
||||
return {"memory_block": ""}
|
||||
|
||||
async def _build_relation_info(self) -> Dict[str, Any]:
|
||||
"""构建关系信息"""
|
||||
@@ -539,13 +623,106 @@ class Prompt:
|
||||
|
||||
async def _build_tool_info(self) -> Dict[str, Any]:
|
||||
"""构建工具信息"""
|
||||
# 简化的实现
|
||||
return {"tool_info_block": ""}
|
||||
if not global_config.tool.enable_tool:
|
||||
return {"tool_info_block": ""}
|
||||
|
||||
try:
|
||||
from src.plugin_system.core.tool_use import ToolExecutor
|
||||
|
||||
# 获取聊天历史
|
||||
chat_history = ""
|
||||
if self.parameters.message_list_before_now_long:
|
||||
recent_messages = self.parameters.message_list_before_now_long[-15:]
|
||||
chat_history = build_readable_messages(
|
||||
recent_messages,
|
||||
replace_bot_name=True,
|
||||
timestamp_mode="normal",
|
||||
truncate=True
|
||||
)
|
||||
|
||||
# 创建工具执行器
|
||||
tool_executor = ToolExecutor()
|
||||
|
||||
# 执行工具获取信息
|
||||
tool_results, _, _ = await tool_executor.execute_from_chat_message(
|
||||
sender=self.parameters.sender,
|
||||
target_message=self.parameters.target,
|
||||
chat_history=chat_history,
|
||||
return_details=False
|
||||
)
|
||||
|
||||
# 构建工具信息块
|
||||
if tool_results:
|
||||
tool_info_parts = ["以下是你通过工具获取到的实时信息:"]
|
||||
for tool_result in tool_results:
|
||||
tool_name = tool_result.get("tool_name", "unknown")
|
||||
content = tool_result.get("content", "")
|
||||
result_type = tool_result.get("type", "tool_result")
|
||||
|
||||
tool_info_parts.append(f"- 【{tool_name}】{result_type}: {content}")
|
||||
|
||||
tool_info_parts.append("以上是你获取到的实时信息,请在回复时参考这些信息。")
|
||||
tool_info_block = "\n".join(tool_info_parts)
|
||||
else:
|
||||
tool_info_block = ""
|
||||
|
||||
return {"tool_info_block": tool_info_block}
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"构建工具信息失败: {e}")
|
||||
return {"tool_info_block": ""}
|
||||
|
||||
async def _build_knowledge_info(self) -> Dict[str, Any]:
|
||||
"""构建知识信息"""
|
||||
# 简化的实现
|
||||
return {"knowledge_prompt": ""}
|
||||
if not global_config.lpmm_knowledge.enable:
|
||||
return {"knowledge_prompt": ""}
|
||||
|
||||
try:
|
||||
from src.chat.knowledge.knowledge_lib import QAManager
|
||||
|
||||
# 获取问题文本(当前消息)
|
||||
question = self.parameters.target or ""
|
||||
if not question:
|
||||
return {"knowledge_prompt": ""}
|
||||
|
||||
# 创建QA管理器
|
||||
qa_manager = QAManager()
|
||||
|
||||
# 搜索相关知识
|
||||
knowledge_results = await qa_manager.get_knowledge(
|
||||
question=question,
|
||||
chat_id=self.parameters.chat_id,
|
||||
max_results=5,
|
||||
min_similarity=0.5
|
||||
)
|
||||
|
||||
# 构建知识块
|
||||
if knowledge_results and knowledge_results.get("knowledge_items"):
|
||||
knowledge_parts = ["以下是与你当前对话相关的知识信息:"]
|
||||
|
||||
for item in knowledge_results["knowledge_items"]:
|
||||
content = item.get("content", "")
|
||||
source = item.get("source", "")
|
||||
relevance = item.get("relevance", 0.0)
|
||||
|
||||
if content:
|
||||
if source:
|
||||
knowledge_parts.append(f"- [{relevance:.2f}] {content} (来源: {source})")
|
||||
else:
|
||||
knowledge_parts.append(f"- [{relevance:.2f}] {content}")
|
||||
|
||||
if knowledge_results.get("summary"):
|
||||
knowledge_parts.append(f"\n知识总结: {knowledge_results['summary']}")
|
||||
|
||||
knowledge_prompt = "\n".join(knowledge_parts)
|
||||
else:
|
||||
knowledge_prompt = ""
|
||||
|
||||
return {"knowledge_prompt": knowledge_prompt}
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"构建知识信息失败: {e}")
|
||||
return {"knowledge_prompt": ""}
|
||||
|
||||
async def _build_cross_context(self) -> Dict[str, Any]:
|
||||
"""构建跨群上下文"""
|
||||
|
||||
Reference in New Issue
Block a user