feat: BossAi v2.0 UI/UX 重构 + 看板断点续接 + 多轮上下文
- 新增 web2/ 前端:任务卡看板、风险雷达、决策日志、我的团队、快捷指令 - ChatPanel 增强:风险卡置顶、案卡接入、起诉状向导、语音输入 - 事项看板:点击查看详情弹窗、断点续接(恢复历史对话+matterId) - 保密模式恢复:密码验证后重建内存 session,保留多轮上下文 - 多轮对话:ask/ask-stream/ask-analyze 注入 session 历史,AI 有上下文 - 追问优化:紧扣用户问题,不再偏离主题(社保问社保,工伤问工伤) - 对话区可滚动,输入区固定可见 - 状态机放宽:允许从任意非终态转到 pending_expert - session 存活检查端点,后端重启后自动重建 session - DB migration:风险推送表、案卡表 Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
@@ -164,7 +164,7 @@ def assess_ai(question: str, kimi_client=None) -> RiskCard | None:
|
||||
return None
|
||||
|
||||
prompt = (
|
||||
"你是中国中小企业法务风险分诊专家。请判断以下问题的风险等级。\n\n"
|
||||
"你是中国中小企业法务风险分诊专家,服务对象是企业老板(雇主)。请判断以下问题的风险等级。\n\n"
|
||||
f"用户问题:{question}\n\n"
|
||||
"风险等级定义:\n"
|
||||
"- red: 重大法律风险,可能涉及刑事、行政处罚、重大诉讼、人身安全,必须人工复核\n"
|
||||
@@ -2117,7 +2117,7 @@ class DocumentGenerator:
|
||||
|
||||
try:
|
||||
return self.kimi_client.chat(
|
||||
[{"role": "system", "content": "你是法律文书撰写助手,生成正式规范的文书正文。"},
|
||||
[{"role": "system", "content": "你是法律文书撰写助手,服务对象是中小企业老板(原告方),生成正式规范的文书正文。"},
|
||||
{"role": "user", "content": prompt}],
|
||||
temperature=0.3,
|
||||
timeout=30,
|
||||
@@ -2483,7 +2483,7 @@ class FactFinder:
|
||||
}.get(scene, "通用")
|
||||
|
||||
prompt = (
|
||||
f"你是{scene_desc}顾问。判断已有事实是否足够给出有价值的建议。\n\n"
|
||||
f"你是{scene_desc}顾问,服务对象是中小企业老板。判断已有事实是否足够给出有价值的建议。\n\n"
|
||||
f"用户问题:{question}\n\n"
|
||||
)
|
||||
if previous_answers:
|
||||
@@ -2593,7 +2593,7 @@ class FactFinder:
|
||||
|
||||
def generate_ai_questions(self, question: str, scene: str,
|
||||
kimi_client, previous_answers: list[dict] = None,
|
||||
max_questions: int = 3) -> list[dict]:
|
||||
max_questions: int = 3, history: list[dict] = None) -> list[dict]:
|
||||
"""用 AI 分析问题,生成针对性追问问题。
|
||||
|
||||
Args:
|
||||
@@ -2613,25 +2613,25 @@ class FactFinder:
|
||||
scene_config = {
|
||||
"legal": {
|
||||
"desc": "法律/法务",
|
||||
"role": "你是中国执业律师",
|
||||
"role": "你是中国执业律师,服务对象是中小企业老板(雇主),所有追问必须从老板/雇主视角出发",
|
||||
"dim_examples": "合同、金额、时间、证据、对方态度、是否协商过",
|
||||
"focus": "影响法律结论的关键事实",
|
||||
},
|
||||
"decision": {
|
||||
"desc": "经营决策",
|
||||
"role": "你是中小企业经营顾问",
|
||||
"role": "你是中小企业经营顾问,服务对象是企业老板,所有追问从老板视角出发",
|
||||
"dim_examples": "规模金额、现金流、市场状况、团队能力、备选方案、时间窗口",
|
||||
"focus": "影响决策推演的关键事实",
|
||||
},
|
||||
"life": {
|
||||
"desc": "生活助理",
|
||||
"role": "你是生活管理顾问,擅长家庭、健康、出行等实用建议",
|
||||
"role": "你是生活管理顾问,擅长家庭、健康、出行等实用建议,服务对象是企业老板",
|
||||
"dim_examples": "具体状况、涉及人员、时间安排、当前困难、已有尝试",
|
||||
"focus": "让建议更具体可执行的关键细节,而非泛泛的'描述情况'",
|
||||
},
|
||||
"emotion": {
|
||||
"desc": "情绪疏导",
|
||||
"role": "你是心理咨询师",
|
||||
"role": "你是心理咨询师,服务对象是企业老板",
|
||||
"dim_examples": "触发事件、持续时间、当前感受、已有应对、社会支持",
|
||||
"focus": "理解情绪状态和触发因素的关键信息",
|
||||
},
|
||||
@@ -2644,6 +2644,16 @@ class FactFinder:
|
||||
f"用户问题:{question}\n\n"
|
||||
)
|
||||
|
||||
# 注入对话历史(多轮上下文),让追问能理解当前问题的背景
|
||||
if history:
|
||||
prompt += "之前的对话历史(用于理解当前问题的背景):\n"
|
||||
for h in history[-6:]:
|
||||
role_label = "用户" if h.get("role") == "user" else "AI"
|
||||
content = h.get("content", "")
|
||||
if content:
|
||||
prompt += f"{role_label}: {content[:200]}\n"
|
||||
prompt += "\n注意:当前问题是在上述对话背景下的延续,追问应结合之前的上下文,不要当成孤立问题处理。\n\n"
|
||||
|
||||
if previous_answers:
|
||||
prompt += "已知事实:\n"
|
||||
for ans in previous_answers:
|
||||
@@ -2653,19 +2663,24 @@ class FactFinder:
|
||||
prompt += (
|
||||
f"请生成最多 {max_questions} 个最关键的追问,帮助更准确地分析这个问题。\n\n"
|
||||
f"要求:\n"
|
||||
f"1. 每个问题针对一个关键事实维度(如{config['dim_examples']}等)\n"
|
||||
f"2. 问题必须具体、有针对性,针对用户问题中的实际情境提问\n"
|
||||
f"3. 不要问'能具体描述一下情况吗'这类泛泛的问题,要问具体的细节\n"
|
||||
f"4. 优先问对{config['focus']}影响最大的事实\n"
|
||||
f"5. 不要问用户已经回答过的事实\n"
|
||||
f"6. 如果已有足够信息,返回空列表\n\n"
|
||||
f"1. **追问必须与用户问题直接相关,不要偏离主题**。"
|
||||
f"例如用户问'社保未缴全',追问应该是关于社保缴纳情况、欠缴金额、是否被查等,"
|
||||
f"而不是问合同违约或股东纠纷等无关问题\n"
|
||||
f"2. 每个问题针对一个关键事实维度(如{config['dim_examples']}等)\n"
|
||||
f"3. 问题必须具体、有针对性,针对用户问题中的实际情境提问\n"
|
||||
f"4. 不要问'能具体描述一下情况吗'这类泛泛的问题,要问具体的细节\n"
|
||||
f"5. 优先问对{config['focus']}影响最大的事实\n"
|
||||
f"6. 不要问用户已经回答过的事实\n"
|
||||
f"7. 如果已有足够信息,返回空列表\n"
|
||||
f"8. **所有追问必须从老板/雇主视角出发**(用户是中小企业老板,不是员工)。"
|
||||
f"例如劳动用工场景,应问'公司与该员工签的劳动合同中解除条款怎么约定的',而非'您与公司签订的劳动合同'\n\n"
|
||||
f"请以 JSON 数组格式返回,每个元素包含 dim_key(维度英文标识)、dim_desc(维度中文描述)、question(追问问题):\n"
|
||||
f'[{{"dim_key": "amount", "dim_desc": "涉及金额", "question": "涉及的金额大约是多少?"}}]\n'
|
||||
)
|
||||
|
||||
try:
|
||||
answer = kimi_client.chat(
|
||||
[{"role": "system", "content": "你是专业顾问助手,擅长分析问题并生成精准追问。只返回 JSON 数组,不要其他内容。"},
|
||||
[{"role": "system", "content": "你是专业顾问助手,服务对象是中小企业老板。所有追问必须从老板/雇主视角出发,不要用员工视角提问。只返回 JSON 数组,不要其他内容。"},
|
||||
{"role": "user", "content": prompt}],
|
||||
temperature=0.3,
|
||||
timeout=30,
|
||||
@@ -2704,7 +2719,7 @@ class FactFinder:
|
||||
|
||||
def build_analysis_prompt(self, question: str, scene: str,
|
||||
answers: list[dict],
|
||||
kimi_client=None) -> tuple[str, dict]:
|
||||
kimi_client=None, history: list[dict] = None) -> tuple[str, dict]:
|
||||
"""完整的追问流程:分析 → 生成追问 → 汇总事实。
|
||||
|
||||
优先用 AI 生成针对性追问,Kimi 不可用时降级到规则匹配。
|
||||
@@ -2730,6 +2745,7 @@ class FactFinder:
|
||||
if kimi_client:
|
||||
questions = self.generate_ai_questions(
|
||||
question, scene, kimi_client, answers, self.max_questions_per_round,
|
||||
history=history,
|
||||
)
|
||||
# AI 不可用或返回空,降级到规则匹配
|
||||
if not questions:
|
||||
@@ -2841,9 +2857,11 @@ class KimiClient:
|
||||
# 场景 system prompt 映射:按模块路由不同人设,前端通过 scene 参数选择
|
||||
SCENE_PROMPTS: dict[str, str] = {
|
||||
"legal": (
|
||||
"你是中国中小企业老板的法务参谋。先给风险等级(绿色/黄色/橙色/红色),"
|
||||
"你是中国中小企业老板的法务参谋,服务对象是企业老板(雇主),所有分析和建议必须从老板/雇主视角出发。"
|
||||
"先给风险等级(绿色/黄色/橙色/红色),"
|
||||
"再给结论、立即行动、需保存证据、禁止事项和是否需要律师复核。"
|
||||
"覆盖劳动用工、合同审查、债权债务、股东纠纷、税务风险。"
|
||||
"劳动用工场景中,你是帮老板处理员工问题的律师,不是帮员工维权的律师。"
|
||||
"严禁编造法律依据;不确定时明确说明。"
|
||||
),
|
||||
"decision": (
|
||||
|
||||
Reference in New Issue
Block a user