feat: 新增需求理解并实现human in loop
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
"""整理澄清问题,等待用户补充"""
|
||||
|
||||
import json
|
||||
|
||||
from langchain_core.messages import HumanMessage, SystemMessage
|
||||
|
||||
from app.clients.llm import get_llm
|
||||
@@ -16,23 +18,20 @@ class ClarifyNode(BaseNode):
|
||||
intent = state["intent"]
|
||||
print(intent)
|
||||
print("=================")
|
||||
if intent == "unclear":
|
||||
llm = get_llm(Clarification)
|
||||
clarification = await llm.ainvoke(
|
||||
[
|
||||
SystemMessage(content=CLARIFY_SYSTEM_PROMPT),
|
||||
HumanMessage(
|
||||
content=state["input_context"].model_dump_json(
|
||||
exclude_unset=True
|
||||
)
|
||||
),
|
||||
]
|
||||
)
|
||||
else:
|
||||
# 需求理解已经给出问题,直接复用
|
||||
clarification = Clarification(
|
||||
question=state["requirement"].clarification_question
|
||||
)
|
||||
payload = {
|
||||
"intent": intent,
|
||||
"input_context": state["input_context"].model_dump(mode="json"),
|
||||
}
|
||||
if intent != "unclear":
|
||||
# 以需求节点的问题为依据补齐选项,不重新判断意图
|
||||
payload["requirement"] = state["requirement"].model_dump(mode="json")
|
||||
llm = get_llm(Clarification)
|
||||
clarification = await llm.ainvoke(
|
||||
[
|
||||
SystemMessage(content=CLARIFY_SYSTEM_PROMPT),
|
||||
HumanMessage(content=json.dumps(payload, ensure_ascii=False)),
|
||||
]
|
||||
)
|
||||
return {**state, "clarification": clarification}
|
||||
|
||||
|
||||
@@ -54,7 +53,9 @@ if __name__ == "__main__":
|
||||
}
|
||||
}
|
||||
try:
|
||||
final_state = await query_app.ainvoke(state)
|
||||
final_state = await query_app.ainvoke(
|
||||
state, config={"configurable": {"thread_id": "clarify-test"}}
|
||||
)
|
||||
finally:
|
||||
await close_decision_engine()
|
||||
print(
|
||||
@@ -67,6 +68,7 @@ if __name__ == "__main__":
|
||||
},
|
||||
ensure_ascii=False,
|
||||
indent=2,
|
||||
default=str,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -11,6 +11,41 @@ class InputNode(BaseNode):
|
||||
name = "input_node"
|
||||
|
||||
def process(self, state: QueryState) -> QueryState:
|
||||
reply = state.get("clarification_reply")
|
||||
if reply is not None:
|
||||
data = state["input_context"].model_dump(mode="json")
|
||||
turn = {
|
||||
"question": state["clarification"].question,
|
||||
"answer": reply.answer,
|
||||
}
|
||||
if reply.option_id is not None:
|
||||
option = next(
|
||||
option
|
||||
for option in state["clarification"].options
|
||||
if option.id == reply.option_id
|
||||
)
|
||||
turn["selected_option"] = option.model_dump(mode="json")
|
||||
data["clarification_history"].append(turn)
|
||||
if reply.screen is not None:
|
||||
data["screen"] = reply.screen.model_dump(mode="json")
|
||||
# 新快照不沿用可能已经失效的选中节点
|
||||
if reply.context is None:
|
||||
data["context"]["selected_node_ids"] = []
|
||||
data["context"]["screen_revision"] = None
|
||||
if reply.context is not None:
|
||||
data["context"] = reply.context.model_dump(mode="json")
|
||||
context = InputContext.model_validate(data)
|
||||
# 显式清空旧推导结果,LangGraph 的状态合并不会删除省略字段
|
||||
return {
|
||||
**state,
|
||||
"input_context": context,
|
||||
"clarification_reply": None,
|
||||
"intent_decision": None,
|
||||
"intent": None,
|
||||
"requirement": None,
|
||||
"clarification": None,
|
||||
"status": "running",
|
||||
}
|
||||
# 深拷贝隔离原始请求,后续修改上下文不会改变提交时的快照
|
||||
context = InputContext.model_validate(state["request"]).model_copy(deep=True)
|
||||
updated_state: QueryState = {**state, "input_context": context}
|
||||
|
||||
@@ -38,6 +38,7 @@ class IntentNode(BaseNode):
|
||||
)
|
||||
return {
|
||||
"prompt": context.prompt,
|
||||
"clarification_history": context.clarification_history,
|
||||
"context": context.context.model_dump(mode="json", exclude_unset=True),
|
||||
"screen_summary": {
|
||||
"canvas": {
|
||||
|
||||
Reference in New Issue
Block a user