更新回复格式
This commit is contained in:
@@ -66,6 +66,30 @@ async def after_model_callback(callback_context, llm_response):
|
|||||||
)
|
)
|
||||||
total_tokens = getattr(usage, "total_token_count", None) if usage else None
|
total_tokens = getattr(usage, "total_token_count", None) if usage else None
|
||||||
|
|
||||||
|
# ── 打印模型输出的完整内容(用于排查问题) ──
|
||||||
|
content = getattr(llm_response, "content", None)
|
||||||
|
if content:
|
||||||
|
parts = getattr(content, "parts", None) or []
|
||||||
|
for i, part in enumerate(parts):
|
||||||
|
text = getattr(part, "text", None)
|
||||||
|
if text:
|
||||||
|
logger.info(
|
||||||
|
"【模型输出】agent=%s part=%d text=%s",
|
||||||
|
agent_name,
|
||||||
|
i,
|
||||||
|
text[:2000] if len(text) > 2000 else text,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
# 非文本 part(如工具调用)
|
||||||
|
func_call = getattr(part, "function_call", None)
|
||||||
|
if func_call:
|
||||||
|
logger.info(
|
||||||
|
"【工具调用】agent=%s function=%s args=%s",
|
||||||
|
agent_name,
|
||||||
|
getattr(func_call, "name", "?"),
|
||||||
|
getattr(func_call, "args", {}),
|
||||||
|
)
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
"模型调用完成 | agent=%s model=%s latency=%.3fs "
|
"模型调用完成 | agent=%s model=%s latency=%.3fs "
|
||||||
"prompt_tokens=%s completion_tokens=%s total_tokens=%s",
|
"prompt_tokens=%s completion_tokens=%s total_tokens=%s",
|
||||||
|
|||||||
@@ -11,6 +11,37 @@ from typing import List
|
|||||||
|
|
||||||
from common.knowledge_loader import list_knowledge_files, load_knowledge_file
|
from common.knowledge_loader import list_knowledge_files, load_knowledge_file
|
||||||
|
|
||||||
|
|
||||||
|
# ───────────────────────────── Markdown 清理 ─────────────────────────────
|
||||||
|
def _strip_markdown(text: str) -> str:
|
||||||
|
"""将 Markdown 格式转为纯文本,方便微信等平台显示"""
|
||||||
|
# 移除代码块
|
||||||
|
text = re.sub(r"```[\s\S]*?```", lambda m: m.group(0).strip("`\n"), text)
|
||||||
|
# 移除行内代码反引号
|
||||||
|
text = re.sub(r"`([^`]+)`", r"\1", text)
|
||||||
|
# 移除加粗/斜体
|
||||||
|
text = re.sub(r"\*\*(.+?)\*\*", r"\1", text)
|
||||||
|
text = re.sub(r"\*(.+?)\*", r"\1", text)
|
||||||
|
text = re.sub(r"__(.+?)__", r"\1", text)
|
||||||
|
text = re.sub(r"_(.+?)_", r"\1", text)
|
||||||
|
# 移除标题标记,保留文字
|
||||||
|
text = re.sub(r"^#{1,6}\s+", "", text, flags=re.MULTILINE)
|
||||||
|
# 移除链接,保留文字
|
||||||
|
text = re.sub(r"\[([^\]]+)\]\([^)]+\)", r"\1", text)
|
||||||
|
# 移除图片
|
||||||
|
text = re.sub(r"!\[([^\]]*)\]\([^)]+\)", "", text)
|
||||||
|
# 移除水平线
|
||||||
|
text = re.sub(r"^---+$", "", text, flags=re.MULTILINE)
|
||||||
|
# 移除引用标记
|
||||||
|
text = re.sub(r"^>\s?", "", text, flags=re.MULTILINE)
|
||||||
|
# 移除列表标记(- 和 * 开头)
|
||||||
|
text = re.sub(r"^[\-\*]\s+", "· ", text, flags=re.MULTILINE)
|
||||||
|
# 移除编号列表
|
||||||
|
text = re.sub(r"^\d+\.\s+", "", text, flags=re.MULTILINE)
|
||||||
|
# 清理多余空行(最多保留一个空行)
|
||||||
|
text = re.sub(r"\n{3,}", "\n\n", text)
|
||||||
|
return text.strip()
|
||||||
|
|
||||||
# ───────────────────────────── 配置 ─────────────────────────────
|
# ───────────────────────────── 配置 ─────────────────────────────
|
||||||
_KB_DIR = Path(__file__).parent / "knowledge_base"
|
_KB_DIR = Path(__file__).parent / "knowledge_base"
|
||||||
|
|
||||||
@@ -128,12 +159,11 @@ def list_kb() -> str:
|
|||||||
|
|
||||||
当你不确定该查哪个知识库文件时,先调用此工具查看列表。
|
当你不确定该查哪个知识库文件时,先调用此工具查看列表。
|
||||||
"""
|
"""
|
||||||
lines = ["# 可用知识库文件\n"]
|
lines = ["【可用知识库文件】\n"]
|
||||||
for fname, meta in _KB_METADATA.items():
|
for fname, meta in _KB_METADATA.items():
|
||||||
lines.append(f"## {meta['title']}")
|
lines.append(f"◆ {meta['title']}")
|
||||||
lines.append(f"- 文件名: `{fname}`")
|
lines.append(f" 描述: {meta['description']}")
|
||||||
lines.append(f"- 描述: {meta['description']}")
|
lines.append(f" 关键词: {', '.join(meta['keywords'][:5])}...\n")
|
||||||
lines.append(f"- 关键词: {', '.join(meta['keywords'][:5])}...\n")
|
|
||||||
|
|
||||||
return "\n".join(lines)
|
return "\n".join(lines)
|
||||||
|
|
||||||
@@ -154,7 +184,7 @@ def load_kb(filename: str) -> str:
|
|||||||
if not content:
|
if not content:
|
||||||
return f"错误: 无法读取文件 '{filename}'"
|
return f"错误: 无法读取文件 '{filename}'"
|
||||||
|
|
||||||
return content
|
return _strip_markdown(content)
|
||||||
|
|
||||||
|
|
||||||
def search_kb(query: str, top_k: int = 3) -> str:
|
def search_kb(query: str, top_k: int = 3) -> str:
|
||||||
@@ -193,12 +223,11 @@ def search_kb(query: str, top_k: int = 3) -> str:
|
|||||||
if not top_results:
|
if not top_results:
|
||||||
return f"未找到与 '{query}' 相关的知识库内容。"
|
return f"未找到与 '{query}' 相关的知识库内容。"
|
||||||
|
|
||||||
lines = [f"# 知识库搜索结果: '{query}'\n"]
|
lines = [f"【知识库搜索结果: '{query}'】\n"]
|
||||||
for i, (score, fname, section) in enumerate(top_results, 1):
|
for i, (score, fname, section) in enumerate(top_results, 1):
|
||||||
meta = _KB_METADATA.get(fname, {})
|
meta = _KB_METADATA.get(fname, {})
|
||||||
title = meta.get("title", fname)
|
title = meta.get("title", fname)
|
||||||
lines.append(f"## 结果 {i}(相关度: {score:.2f})")
|
lines.append(f"结果{i}(相关度: {score:.2f})| 来源: {title}")
|
||||||
lines.append(f"**来源**: {title} (`{fname}`)")
|
lines.append(f"{_strip_markdown(section[:800])}\n")
|
||||||
lines.append(f"**内容**:\n{section[:800]}...\n")
|
|
||||||
|
|
||||||
return "\n".join(lines)
|
return "\n".join(lines)
|
||||||
|
|||||||
@@ -411,7 +411,7 @@
|
|||||||
|
|
||||||
普通回复场景,默认只输出两段:
|
普通回复场景,默认只输出两段:
|
||||||
|
|
||||||
【可直接发送给学员】
|
【可参考回复】
|
||||||
这里写老师可以直接复制发给学员的话。必须放在最前面。
|
这里写老师可以直接复制发给学员的话。必须放在最前面。
|
||||||
|
|
||||||
【老师提醒】
|
【老师提醒】
|
||||||
|
|||||||
Reference in New Issue
Block a user