feat: 集成Hermes智能体系统,增强聊天和差旅报销功能

This commit is contained in:
caoxiaozhu
2026-05-16 06:14:08 +00:00
parent 763afa0ee2
commit 212c935308
46 changed files with 8802 additions and 5372 deletions

View File

@@ -335,7 +335,6 @@ class SemanticOntologyService:
context_json = payload.context_json or {}
reference = self._load_reference_catalog()
compact_query = self._compact(query)
entities = self._extract_entities(query, compact_query, reference)
rule_scenario, scenario_score = self._detect_scenario(compact_query)
time_range, _time_score = self._extract_time_range(
@@ -343,7 +342,11 @@ class SemanticOntologyService:
compact_query,
context_json=context_json,
)
session_scenario = self._resolve_session_type_scenario(context_json)
context_scenario = self._resolve_context_scenario(context_json)
if session_scenario == "knowledge":
rule_scenario = "knowledge"
scenario_score = max(scenario_score, 0.34)
if rule_scenario == "unknown" and context_scenario is not None:
rule_scenario = context_scenario
scenario_score = max(scenario_score, 0.14)
@@ -393,6 +396,8 @@ class SemanticOntologyService:
constraints=constraints,
)
scenario = self._resolve_scenario(rule_scenario, model_parse)
if session_scenario == "knowledge":
scenario = "knowledge"
entities = self._merge_entities(
entities,
model_parse.entity_hints if model_parse is not None else [],
@@ -419,6 +424,14 @@ class SemanticOntologyService:
context_json=context_json,
)
)
relax_knowledge_follow_up = self._should_relax_knowledge_follow_up_clarification(
compact_query=compact_query,
scenario=scenario,
context_json=context_json,
missing_slots=missing_slots,
)
if relax_knowledge_follow_up:
missing_slots = [item for item in missing_slots if item != "expense_type"]
ambiguity = self._normalize_short_text_list(
model_parse.ambiguity if model_parse is not None else []
)
@@ -450,12 +463,16 @@ class SemanticOntologyService:
intent=intent,
),
model_clarification_required=bool(
model_parse is not None and model_parse.clarification_required
model_parse is not None
and model_parse.clarification_required
),
model_clarification_question=(
model_parse.clarification_question if model_parse is not None else None
),
)
if relax_knowledge_follow_up:
clarification_required = False
clarification_question = None
fallback_confidence = self._compute_confidence(
scenario=scenario,
scenario_score=scenario_score,
@@ -496,6 +513,30 @@ class SemanticOntologyService:
"field_errors": field_errors,
}
@staticmethod
def _should_relax_knowledge_follow_up_clarification(
*,
compact_query: str,
scenario: str,
context_json: dict[str, Any],
missing_slots: list[str],
) -> bool:
if scenario != "knowledge" or "expense_type" not in missing_slots:
return False
history = context_json.get("conversation_history")
if not isinstance(history, list):
return False
has_previous_user_turn = any(
isinstance(item, dict)
and str(item.get("role") or "").strip() == "user"
and str(item.get("content") or "").strip()
for item in history
)
if not has_previous_user_turn:
return False
follow_up_markers = ("", "那么", "这个", "这种", "", "的话", "p", "P")
return any(marker in compact_query for marker in follow_up_markers)
def _record_semantic_parse(
self,
*,
@@ -599,6 +640,14 @@ class SemanticOntologyService:
return value
return None
@staticmethod
def _resolve_session_type_scenario(context_json: dict[str, Any]) -> str | None:
value = str(context_json.get("session_type") or "").strip()
if value == "knowledge":
return "knowledge"
return None
def _detect_scenario(self, compact_query: str) -> tuple[str, float]:
scores = {key: 0.0 for key in SCENARIO_KEYWORDS}
for scenario, keywords in SCENARIO_KEYWORDS.items():
@@ -1593,6 +1642,8 @@ class SemanticOntologyService:
) -> tuple[bool, str | None]:
if permission.level == AgentPermissionLevel.FORBIDDEN.value:
return True, "当前动作超出权限范围。是否改为生成草稿或建议?"
if scenario == "knowledge" and intent in {"query", "explain"}:
return False, None
if model_clarification_required:
question = str(model_clarification_question or "").strip()
if question: