feat:意图识别优化
This commit is contained in:
@@ -13,6 +13,7 @@ from app.processor.state import QueryState
|
||||
from app.prompt.action import build_action_prompt
|
||||
from app.schemas.action_validation import ActionValidationError, schema_errors
|
||||
from app.schemas.actions import ActionBatch, AddAction
|
||||
from app.schemas.operations import is_direct_operation
|
||||
|
||||
|
||||
def can_generate_actions(state: QueryState) -> bool:
|
||||
@@ -47,12 +48,7 @@ def action_block_reason(state: QueryState) -> str | None:
|
||||
unsupported = [
|
||||
f"{change.target_scope}/{change.operation}"
|
||||
for change in requirement.changes
|
||||
if not (
|
||||
change.target_scope == "nodes"
|
||||
and change.operation in ("move", "resize", "update", "delete")
|
||||
or change.target_scope == "canvas"
|
||||
and change.operation in ("update", "resize", "update_canvas")
|
||||
)
|
||||
if not is_direct_operation(change.target_scope, change.operation)
|
||||
]
|
||||
|
||||
# 如果存在不支持的操作,按出现顺序去重后返回原因,便于展示失败信息
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
"""意图识别节点"""
|
||||
|
||||
from typing import cast
|
||||
|
||||
from app.clients.decision import close_decision_engine, get_decision_engine
|
||||
from app.processor.base import BaseNode
|
||||
from app.processor.intent_policy import resolve_intent
|
||||
from app.processor.state import QueryState
|
||||
from app.prompt.intent import build_intent_question
|
||||
from app.schemas.base import JsonObject
|
||||
from app.schemas.decision import DecisionRequest
|
||||
from app.schemas.input_context import InputContext
|
||||
from app.schemas.requirement import Intent
|
||||
|
||||
|
||||
class IntentNode(BaseNode):
|
||||
@@ -101,15 +99,17 @@ class IntentNode(BaseNode):
|
||||
# 从响应中取出 intent 对应的判断结果
|
||||
decision = decision_res.results["intent"]
|
||||
|
||||
# 如果模型无法明确意图,或置信度低于配置阈值,则转入澄清流程
|
||||
if (
|
||||
decision.choice == "unclear"
|
||||
or decision.confidence < self.config.intent_min_confidence
|
||||
):
|
||||
intent: Intent = "unclear"
|
||||
else:
|
||||
# 置信度达标时沿用模型选项,cast 仅作类型提示,不进行运行时转换或校验
|
||||
intent = cast(Intent, decision.choice)
|
||||
# 用户刚点选了澄清选项时,选择本身已表达明确意图
|
||||
history = context.clarification_history
|
||||
# 按选中项概率、风险和澄清轮数确定最终意图,规则集中在 intent_policy
|
||||
intent = resolve_intent(
|
||||
decision,
|
||||
action_min_probability=self.config.intent_min_probability,
|
||||
qa_min_probability=self.config.intent_qa_min_probability,
|
||||
clarified_rounds=len(history),
|
||||
max_clarify_rounds=self.config.intent_max_clarify_rounds,
|
||||
option_selected=bool(history and history[-1].get("selected_option")),
|
||||
)
|
||||
|
||||
# 完整保留原始决策,便于查看模型选项及其置信度
|
||||
updated_state["intent_decision"] = decision_res
|
||||
|
||||
@@ -10,6 +10,7 @@ from app.actions.plan import plan_materials
|
||||
from app.clients.llm import get_llm
|
||||
from app.processor.base import BaseNode
|
||||
from app.processor.state import QueryState
|
||||
from app.schemas.capabilities import USER_FAILURE_MESSAGE
|
||||
from app.prompt.reflection import REFLECTION_SYSTEM_PROMPT
|
||||
from app.schemas.action_repair import ActionRepairPlan
|
||||
|
||||
@@ -71,8 +72,12 @@ class ReflectionNode(BaseNode):
|
||||
updated_state["repair_plan"] = plan
|
||||
# 仅在建议允许重试时将次数加一,缺少历史计数时从零开始,不可重试时保持原次数
|
||||
updated_state["retry_count"] = state.get("retry_count", 0) + int(plan.retryable)
|
||||
# 可以重试时清空旧失败原因,否则使用建议中的原因说明为何停止修正
|
||||
updated_state["failure_reason"] = None if plan.retryable else plan.reason
|
||||
# 可以重试时清空旧失败原因;不可重试时建议中的分析含内部术语,只记录日志,对用户使用统一说明
|
||||
if not plan.retryable:
|
||||
self.logger.warning("动作无法修正: {}", plan.reason)
|
||||
updated_state["failure_reason"] = (
|
||||
None if plan.retryable else USER_FAILURE_MESSAGE
|
||||
)
|
||||
|
||||
# 返回修正建议、重试次数和失败原因,由后续路由决定重新生成动作还是结束
|
||||
return updated_state
|
||||
|
||||
@@ -56,6 +56,27 @@ class RequirementNode(BaseNode):
|
||||
# 如果存在无效目标,立即抛出异常,并排序输出 ID 以便定位问题
|
||||
raise ValueError(f"需求引用了不存在的节点: {sorted(unknown_ids)}")
|
||||
|
||||
# 纯新增需求缺少位置、尺寸等信息时不澄清,采用默认值先执行,用户之后可再次提出调整
|
||||
# 提示词无法保证模型每次都遵守,因此在这里兜底;含待确认目标的需求不受影响
|
||||
if (
|
||||
requirement.needs_clarification
|
||||
and requirement.changes
|
||||
and all(
|
||||
change.target_scope == "screen" and change.operation == "add"
|
||||
for change in requirement.changes
|
||||
)
|
||||
):
|
||||
requirement = requirement.model_copy(
|
||||
update={
|
||||
"needs_clarification": False,
|
||||
"clarification_question": None,
|
||||
"assumptions": [
|
||||
*requirement.assumptions,
|
||||
"未指定的位置、尺寸和数据来源采用默认值,数据使用物料示例数据",
|
||||
],
|
||||
}
|
||||
)
|
||||
|
||||
# 保存通过结构及目标校验的需求,供后续澄清或范围判断使用
|
||||
updated_state["requirement"] = requirement
|
||||
# 返回更新后的状态,由图继续执行后续节点
|
||||
|
||||
@@ -8,6 +8,7 @@ from app.processor.base import BaseNode
|
||||
from app.processor.state import QueryState
|
||||
from app.schemas.action_validation import ActionValidationError, schema_errors
|
||||
from app.schemas.actions import ActionBatch, AddAction, UpdateCanvasAction
|
||||
from app.schemas.operations import is_canvas_operation
|
||||
|
||||
|
||||
class ValidatorNode(BaseNode):
|
||||
@@ -76,8 +77,7 @@ class ValidatorNode(BaseNode):
|
||||
allowed.update(
|
||||
("canvas", "", "update_canvas")
|
||||
for change in requirement.changes
|
||||
if change.target_scope == "canvas"
|
||||
and change.operation in ("update", "resize", "update_canvas")
|
||||
if is_canvas_operation(change.target_scope, change.operation)
|
||||
)
|
||||
|
||||
# 画布没有组件 ID,使用独立作用域避免与同名组件混淆
|
||||
|
||||
Reference in New Issue
Block a user