feta:优化AI回复

This commit is contained in:
2025-12-30 14:56:06 +08:00
parent 58f17e4497
commit 5b130485f0
2 changed files with 78 additions and 11 deletions

View File

@@ -828,6 +828,31 @@ class AIChat(PluginBase):
if strip_thinking:
cleaned = self._strip_thinking_content(cleaned)
# 清理模型偶发输出的“文本工具调用”痕迹(如 tavilywebsearch{query:...} / <ctrl46>
# 这些内容既不是正常回复,也会破坏“工具只能用 Function Calling”的约束
try:
cleaned = re.sub(r"<ctrl\\d+>", "", cleaned, flags=re.IGNORECASE)
cleaned = re.sub(
r"(?:展开阅读下文\\s*)?(?:tavilywebsearch|tavily_web_search|web_search)\\s*\\{[^{}]{0,1500}\\}",
"",
cleaned,
flags=re.IGNORECASE,
)
cleaned = re.sub(
r"(?:tavilywebsearch|tavily_web_search|web_search)\\s*\\([^\\)]{0,1500}\\)",
"",
cleaned,
flags=re.IGNORECASE,
)
cleaned = cleaned.replace("展开阅读下文", "")
cleaned = re.sub(
r"(已触发工具处理:[^]{0,300}结果将发送到聊天中。)",
"",
cleaned,
)
except Exception:
pass
# 再跑一轮:部分模型会把“思考/最终”标记写成 Markdown或在剥离标签后才露出标记
if strip_markdown:
cleaned = self._strip_markdown_syntax(cleaned)
@@ -855,6 +880,16 @@ class AIChat(PluginBase):
if strip_thinking and cleaned and self._contains_thinking_markers(cleaned):
return ""
# 长度限制:避免刷屏/上下文污染
max_chars = output_cfg.get("max_reply_chars")
try:
max_chars = int(max_chars) if max_chars is not None else 0
except Exception:
max_chars = 0
if max_chars and max_chars > 0 and cleaned and len(cleaned) > max_chars:
cleaned = cleaned[:max_chars].rstrip()
if cleaned:
return cleaned
@@ -2426,6 +2461,27 @@ class AIChat(PluginBase):
# 转换为列表
tool_calls_data = [tool_calls_dict[i] for i in sorted(tool_calls_dict.keys())] if tool_calls_dict else []
# 过滤掉模型“幻觉出来”的工具调用(未在本次请求提供 tools 的情况下不应执行)
allowed_tool_names = {
t.get("function", {}).get("name", "")
for t in (tools or [])
if isinstance(t, dict) and t.get("function", {}).get("name")
}
if tool_calls_data:
unsupported = []
filtered = []
for tc in tool_calls_data:
fn = (tc or {}).get("function", {}).get("name", "")
if not fn:
continue
if not allowed_tool_names or fn not in allowed_tool_names:
unsupported.append(fn)
continue
filtered.append(tc)
if unsupported:
logger.warning(f"检测到未提供/未知的工具调用,已忽略: {unsupported}")
tool_calls_data = filtered
logger.info(f"流式 API 响应完成, 内容长度: {len(full_content)}, 工具调用数: {len(tool_calls_data)}")
# 检查是否有函数调用
@@ -4240,6 +4296,27 @@ class AIChat(PluginBase):
tool_calls_data = [tool_calls_dict[i] for i in sorted(tool_calls_dict.keys())] if tool_calls_dict else []
# 检查是否有函数调用
if tool_calls_data:
# 过滤掉模型“幻觉出来”的工具调用(未在本次请求提供 tools 的情况下不应执行)
allowed_tool_names = {
t.get("function", {}).get("name", "")
for t in (tools or [])
if isinstance(t, dict) and t.get("function", {}).get("name")
}
unsupported = []
filtered = []
for tc in tool_calls_data:
fn = (tc or {}).get("function", {}).get("name", "")
if not fn:
continue
if not allowed_tool_names or fn not in allowed_tool_names:
unsupported.append(fn)
continue
filtered.append(tc)
if unsupported:
logger.warning(f"[图片] 检测到未提供/未知的工具调用,已忽略: {unsupported}")
tool_calls_data = filtered
if tool_calls_data:
# 提示已在流式处理中发送,直接启动异步工具执行
logger.info(f"[图片] 启动异步工具执行,共 {len(tool_calls_data)} 个工具")