remove:移除tool_use模型,修复Jargon提取问题,修改统计为tool统计

This commit is contained in:
SengokuCola
2026-03-29 16:26:34 +08:00
parent 868438e3c1
commit 82bbf0fd52
25 changed files with 906 additions and 311 deletions

View File

@@ -198,7 +198,6 @@ class HeartFChatting:
"""判定和生成回复"""
asyncio.create_task(self._trigger_expression_learning(self.message_cache))
# TODO: 完成反思器之后的逻辑
start_time = time.time()
current_cycle_detail = self._start_cycle()
logger.info(f"{self.log_prefix} 开始第{self._cycle_counter}次思考")
@@ -207,10 +206,7 @@ class HeartFChatting:
# TODO: 动作执行逻辑
cycle_detail = self._end_cycle(current_cycle_detail)
if wait_time := global_config.chat.planner_smooth - (time.time() - start_time) > 0:
await asyncio.sleep(wait_time)
else:
await asyncio.sleep(0.1) # 最小等待时间,避免过快循环
await asyncio.sleep(0.1) # 最小等待时间,避免过快循环
return True
def _handle_loop_completion(self, task: asyncio.Task):

View File

@@ -577,29 +577,6 @@ class DefaultReplyer:
duration = end_time - start_time
return name, result, duration
async def _build_disabled_jargon_explanation(self) -> str:
"""当关闭黑话解释时使用的占位协程避免额外的LLM调用"""
return ""
async def _build_unknown_words_jargon(self, unknown_words: Optional[List[str]], chat_id: str) -> str:
"""针对 Planner 提供的未知词语列表执行黑话检索"""
if not unknown_words:
return ""
# 清洗未知词语列表,只保留非空字符串
concepts: List[str] = []
for item in unknown_words:
if isinstance(item, str):
s = item.strip()
if s:
concepts.append(s)
if not concepts:
return ""
try:
return await retrieve_concepts_with_jargon(concepts, chat_id)
except Exception as e:
logger.error(f"未知词语黑话检索失败: {e}")
return ""
async def _build_jargon_explanation(
self,
chat_id: str,
@@ -609,19 +586,14 @@ class DefaultReplyer:
) -> str:
"""
统一的黑话解释构建函数:
- 根据 enable_jargon_explanation / jargon_mode 决定具体策略
- 根据 enable_jargon_explanation 决定是否启用
"""
del unknown_words
enable_jargon_explanation = getattr(global_config.expression, "enable_jargon_explanation", True)
if not enable_jargon_explanation:
return ""
jargon_mode = getattr(global_config.expression, "jargon_mode", "context")
# planner 模式:仅使用 Planner 的 unknown_words
if jargon_mode == "planner":
return await self._build_unknown_words_jargon(unknown_words, chat_id)
# 默认 / context 模式:使用上下文自动匹配黑话
# 使用上下文自动匹配黑话
try:
return await explain_jargon_in_context(chat_id, messages_short, chat_talking_prompt_short) or ""
except Exception as e:
@@ -1209,7 +1181,7 @@ class DefaultReplyer:
prompt = await prompt_manager.render_prompt(template_prompt)
generation_result = await llm_api.generate(
llm_api.LLMServiceRequest(
task_name="tool_use",
task_name="utils",
request_type="replyer.lpmm_knowledge",
prompt=prompt,
tool_options=[search_knowledge_tool.get_tool_definition()],

View File

@@ -20,8 +20,8 @@ from src.services.llm_service import LLMServiceClient
from src.maisaka.message_adapter import (
get_message_kind,
get_message_role,
get_message_source,
get_message_text,
is_perception_message,
parse_speaker_content,
)
@@ -121,6 +121,9 @@ class MaisakaReplyGenerator:
role = get_message_role(message)
timestamp = self._format_message_time(message)
if get_message_source(message) == "user_reference":
continue
if role == "user":
guided_reply = self._extract_guided_bot_reply(message)
if guided_reply:
@@ -148,7 +151,6 @@ class MaisakaReplyGenerator:
chat_history: List[SessionMessage],
reply_reason: str,
expression_habits: str = "",
jargon_explanation: str = "",
) -> str:
"""构建 Maisaka replyer 提示词。"""
current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
@@ -167,8 +169,6 @@ class MaisakaReplyGenerator:
extra_sections: List[str] = []
if expression_habits.strip():
extra_sections.append(expression_habits.strip())
if jargon_explanation.strip():
extra_sections.append(jargon_explanation.strip())
user_sections = [
f"当前时间:{current_time}",
@@ -198,7 +198,6 @@ class MaisakaReplyGenerator:
log_reply: bool = True,
chat_history: Optional[List[SessionMessage]] = None,
expression_habits: str = "",
jargon_explanation: str = "",
selected_expression_ids: Optional[List[int]] = None,
) -> Tuple[bool, ReplyGenerationResult]:
"""结合上下文生成 Maisaka 的最终可见回复。"""
@@ -223,20 +222,20 @@ class MaisakaReplyGenerator:
f"Maisaka replyer start: stream_id={stream_id} reply_reason={reply_reason!r} "
f"history_size={len(chat_history)} target_message_id="
f"{reply_message.message_id if reply_message else None} "
f"expression_count={len(result.selected_expression_ids)} "
f"jargon_enabled={bool(jargon_explanation.strip())}"
f"expression_count={len(result.selected_expression_ids)}"
)
filtered_history = [
message
for message in chat_history
if get_message_role(message) != "system" and get_message_kind(message) != "perception"
if get_message_role(message) != "system"
and get_message_kind(message) != "perception"
and get_message_source(message) != "user_reference"
]
prompt = self._build_prompt(
chat_history=filtered_history,
reply_reason=reply_reason or "",
expression_habits=expression_habits,
jargon_explanation=jargon_explanation,
)
result.completion.request_prompt = prompt

View File

@@ -12,7 +12,7 @@ from sqlmodel import col, select
from src.common.logger import get_logger
from src.common.database.database import get_db_session
from src.common.database.database_model import OnlineTime, ModelUsage, Messages, ActionRecord
from src.common.database.database_model import Messages, ModelUsage, OnlineTime, ToolRecord
from src.manager.async_task_manager import AsyncTask
from src.manager.local_store_manager import local_storage
from src.config.config import global_config
@@ -648,7 +648,7 @@ class StatisticOutputTask(AsyncTask):
def _collect_message_count_for_period(
self,
collect_period: list[tuple[str, datetime]],
) -> StatPeriodMapping:
) -> dict[str, dict[str, object]]:
"""
收集指定时间段的消息统计数据
@@ -659,8 +659,13 @@ class StatisticOutputTask(AsyncTask):
collect_period.sort(key=lambda x: x[1], reverse=True)
stats: StatPeriodMapping = {
period_key: StatisticOutputTask._build_stat_period_data() for period_key, _ in collect_period
stats: dict[str, dict[str, object]] = {
period_key: {
TOTAL_MSG_CNT: 0,
MSG_CNT_BY_CHAT: defaultdict(int),
TOTAL_REPLY_CNT: 0,
}
for period_key, _ in collect_period
}
query_start_timestamp = collect_period[-1][1]
@@ -710,24 +715,24 @@ class StatisticOutputTask(AsyncTask):
StatisticOutputTask._add_defaultdict_int(stats[period_key], MSG_CNT_BY_CHAT, chat_id, 1)
break
# 使用 ActionRecords 中的 reply 动作次数作为回复数基准
# 使用 ToolRecord 中的 reply 工具次数作为回复数基准
try:
action_query_start_timestamp = collect_period[-1][1]
tool_query_start_timestamp = collect_period[-1][1]
with get_db_session(auto_commit=False) as session:
statement = select(ActionRecord).where(col(ActionRecord.timestamp) >= action_query_start_timestamp)
actions = session.exec(statement).all()
for action in actions:
if action.action_name != "reply":
statement = select(ToolRecord).where(col(ToolRecord.timestamp) >= tool_query_start_timestamp)
tool_records = session.exec(statement).all()
for tool_record in tool_records:
if tool_record.tool_name != "reply":
continue
action_time_ts = action.timestamp.timestamp()
action_time_ts = tool_record.timestamp.timestamp()
for idx, (_, period_start_dt) in enumerate(collect_period):
if action_time_ts >= period_start_dt.timestamp():
for period_key, _ in collect_period[idx:]:
StatisticOutputTask._add_int_stat(stats[period_key], TOTAL_REPLY_CNT, 1)
break
except Exception as e:
logger.warning(f"统计 reply 动作次数失败,将回复数视为 0错误信息{e}")
logger.warning(f"统计 reply 工具次数失败,将回复数视为 0错误信息{e}")
return stats