feta:优化AI回复
This commit is contained in:
@@ -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)} 个工具")
|
||||
|
||||
Reference in New Issue
Block a user