Files
group_xinghuo_jinrong/app/model/analyst_schemas.py
T
zhanghongyu_0626 601ed258f3 feat(analyst): Enhance asset management and ambiguity detection features
- Added new endpoints to the analyst API for managing assets, including `GET /assets` to list assets and `POST /assets/{kind}/{asset_id}/publish` to publish assets.
- Introduced `DictAmbiguityCheckRequest` schema for checking metric ambiguities, enhancing the analyst's ability to clarify definitions and aliases.
- Implemented `detect_dict_ambiguity` function to analyze potential ambiguities in metrics, providing structured feedback for users.
- Updated `AnalystAgent` to support the new asset management functionalities and ambiguity detection logic, improving overall user experience.
- Enhanced existing schemas and services to accommodate new features, ensuring robust data handling and validation.

This update significantly improves the analyst API's capabilities, allowing for better asset management and clarity in metric definitions.
2026-09-12 15:14:01 +08:00

134 lines
4.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""数据分析 Agent 请求/响应 Pydantic 模型(输出四件套,需求规格 §3 全局约定)。"""
from __future__ import annotations
from typing import Literal
from pydantic import BaseModel, Field
DISCLAIMER = (
"本内容仅为投资分析参考,不构成任何直接投资建议,不构成对任何产品的收益承诺,"
"据此操作风险自负,请谨慎对待。"
)
CUSTOMER_AI_RISK_NOTE = "AI 分析有风险,仅供参考。"
class ChatRequest(BaseModel):
question: str = Field(..., description="自然语言问题")
session_id: str | None = None
trace_id: str | None = None
interpret: bool = Field(
default=False,
description="true=问数后立即 LLM 解读;false=仅 SQL+表格(解读走 /interpret)",
)
class TableData(BaseModel):
columns: list[str] = Field(default_factory=list)
rows: list[list] = Field(default_factory=list)
class Meta(BaseModel):
exec_ms: int = 0
row_count: int = 0
cache_hit: bool = False
template_hit: bool = False
template_key: str | None = None
data_as_of: str | None = None
source: str = ""
cost_est: float = 0.0
class InterpretRequest(BaseModel):
"""按需解读:上下文仅本轮问数快照(看图说话)。"""
question: str
status: str
answer: str = ""
table: TableData = Field(default_factory=TableData)
sql: str = ""
trace_id: str | None = None
meta: Meta = Field(default_factory=Meta)
ChartType = Literal["line", "bar", "column", "pie", "none"]
AnalysisKind = Literal["text", "chart", "both", "none"]
class ChartSpec(BaseModel):
chart_type: ChartType
title: str = ""
reason: str | None = None
x_field: str | None = None
y_fields: list[str] = Field(default_factory=list)
series_field: str | None = None
class AnalyzeRequest(InterpretRequest):
"""分析助手:快照 + 用户提示词(文字/图表/both)。"""
analysis_prompt: str = Field(..., min_length=1, max_length=2000)
class ClarifyOption(BaseModel):
metric_key: str
metric_name: str
definition: str = ""
class ClarifyPayload(BaseModel):
term: str
options: list[ClarifyOption] = Field(default_factory=list)
llm_hint: str | None = None
class DictAmbiguityCheckRequest(BaseModel):
metric_key: str = Field(..., min_length=1, max_length=128)
metric_name: str = Field(..., min_length=1, max_length=128)
definition: str = Field(..., min_length=1)
aliases: str = Field(default="", description="逗号分隔或 JSON 数组字符串")
class AnalystResponse(BaseModel):
"""统一输出四件套 + 状态/错误信息。"""
answer: str = ""
table: TableData = Field(default_factory=TableData)
sql: str = ""
meta: Meta = Field(default_factory=Meta)
disclaimer: str = DISCLAIMER
status: str = "success" # success / clarify / deny / degrade / error / escalate
error_code: str | None = None
suggestions: list[str] | None = Field(
default=None, description="权限拒绝时的可查范围引导(D-08)"
)
trace_id: str | None = None
analysis_kind: AnalysisKind = "none"
chart: ChartSpec | None = None
clarify: ClarifyPayload | None = Field(default=None, description="status=clarify 时可选口径")
class AssetCreateRequest(BaseModel):
"""沉淀资产(D-11):few_shot / dict / template。"""
kind: str = Field(..., description="few_shot / dict / template")
payload: dict = Field(default_factory=dict)
publish: bool = Field(
False,
description="true 时写入 status=published 并立即参与问数(dict/few-shot/template)",
)
class EscalateRequest(BaseModel):
"""问数失败一键转人工(N-07)。"""
trace_id: str = Field(..., min_length=1, max_length=64)
question: str = Field(default="", max_length=2000)
reason: str = Field(default="", max_length=500)
class SampleRequest(BaseModel):
"""抽样明细(N-03)。"""
limit: int = Field(default=5, ge=1, le=20)