feat:修复孤儿工具报错,为replyer等tool添加统一的控制台展示接口

This commit is contained in:
SengokuCola
2026-04-07 16:21:42 +08:00
parent c5f514946b
commit 6968879a04
11 changed files with 1803 additions and 439 deletions

View File

@@ -1,6 +1,6 @@
"""回复生成结果相关数据模型。
该模块用于描述新版回复链中的三个层次:
该模块用于描述新版回复链中的三个层次:
1. LLM 原始完成结果。
2. 生成过程中的耗时与调试信息。
@@ -23,13 +23,6 @@ class LLMCompletionResult(BaseDataModel):
该模型只描述模型调用本身的输入与输出,不承载回复切分、
消息序列拼装或表达方式选择等后处理结果。
Attributes:
request_prompt: 实际发送给模型的 Prompt 文本。
response_text: 模型返回的主文本内容。
reasoning_text: 模型返回的推理内容。
model_name: 本次请求实际使用的模型名称。
tool_calls: 模型返回的工具调用列表。
"""
request_prompt: str = field(
@@ -52,19 +45,23 @@ class LLMCompletionResult(BaseDataModel):
default_factory=list,
metadata={"description": "模型返回的工具调用列表。"},
)
prompt_tokens: int = field(
default=0,
metadata={"description": "本次请求的输入 Token 数。"},
)
completion_tokens: int = field(
default=0,
metadata={"description": "本次请求的输出 Token 数。"},
)
total_tokens: int = field(
default=0,
metadata={"description": "本次请求的总 Token 数。"},
)
@dataclass
class GenerationMetrics(BaseDataModel):
"""一次生成流程的耗时与调试指标。
Attributes:
prompt_ms: Prompt 构建耗时,单位为毫秒。
llm_ms: LLM 调用耗时,单位为毫秒。
overall_ms: 整个生成流程总耗时,单位为毫秒。
stage_logs: 各阶段的简短耗时日志列表。
extra: 额外指标字典,用于承载不适合单独升格为字段的监控信息。
"""
"""一次生成流程的耗时与调试指标。"""
prompt_ms: Optional[float] = field(
default=None,
@@ -90,20 +87,7 @@ class GenerationMetrics(BaseDataModel):
@dataclass
class ReplyGenerationResult(BaseDataModel):
"""回复链的最终结构化结果。
该模型用于承接回复器和生成服务合并后的最终产物,供 HFC、
BrainChat、发送服务和日志系统继续消费。
Attributes:
success: 本次回复生成是否成功。
completion: LLM 原始完成结果。
metrics: 本次生成的耗时与调试指标。
selected_expression_ids: 本次选中的表达方式 ID 列表。
text_fragments: 对模型输出进行切分、规范化后的文本片段列表。
message_sequence: 最终可直接发送的消息序列。
error_message: 失败时的错误描述;成功时为空。
"""
"""回复链的最终结构化结果。"""
success: bool = field(
default=False,
@@ -133,10 +117,70 @@ class ReplyGenerationResult(BaseDataModel):
default_factory=str,
metadata={"description": "失败时的错误描述;成功时通常为空字符串。"},
)
monitor_detail: Optional[Dict[str, Any]] = field(
default=None,
metadata={"description": "供监控层直接消费的通用 tool 展示详情。"},
)
def build_reply_monitor_detail(result: ReplyGenerationResult) -> Dict[str, Any]:
"""构建 reply 工具统一监控详情结构。"""
detail: Dict[str, Any] = {}
prompt_text = result.completion.request_prompt.strip()
reasoning_text = result.completion.reasoning_text.strip()
output_text = result.completion.response_text.strip()
if prompt_text:
detail["prompt_text"] = prompt_text
if reasoning_text:
detail["reasoning_text"] = reasoning_text
if output_text:
detail["output_text"] = output_text
metrics: Dict[str, Any] = {}
if result.completion.model_name.strip():
metrics["model_name"] = result.completion.model_name.strip()
if result.completion.prompt_tokens > 0:
metrics["prompt_tokens"] = result.completion.prompt_tokens
if result.completion.completion_tokens > 0:
metrics["completion_tokens"] = result.completion.completion_tokens
if result.completion.total_tokens > 0:
metrics["total_tokens"] = result.completion.total_tokens
if result.metrics.prompt_ms is not None:
metrics["prompt_ms"] = result.metrics.prompt_ms
if result.metrics.llm_ms is not None:
metrics["llm_ms"] = result.metrics.llm_ms
if result.metrics.overall_ms is not None:
metrics["overall_ms"] = result.metrics.overall_ms
if metrics:
detail["metrics"] = metrics
extra_sections: List[Dict[str, str]] = []
if result.selected_expression_ids:
extra_sections.append({
"title": "已选表达方式",
"content": ", ".join(str(item) for item in result.selected_expression_ids),
})
if result.metrics.stage_logs:
extra_sections.append({
"title": "阶段日志",
"content": "\n".join(result.metrics.stage_logs),
})
if result.error_message.strip():
extra_sections.append({
"title": "错误信息",
"content": result.error_message.strip(),
})
if extra_sections:
detail["extra_sections"] = extra_sections
return detail
__all__ = [
"GenerationMetrics",
"LLMCompletionResult",
"ReplyGenerationResult",
"build_reply_monitor_detail",
]