"""中医意图识别节点
输入: state['input_semantic_trans'] 语义转写节点补全后的提问
输出: state['is_zhongyi_intent'] 该提问是否与中医相关
读转写结果而不是 state['input']:多轮对话里"那它有什么副作用?"单看一句判不出跟
中医有关,补全成"人参有什么副作用?"才判得准。
"""
from langchain_core.messages import HumanMessage, SystemMessage
from _004_langgraph_more_nodes.agent_state import AgentState
from common.llm import my_llm
llm = my_llm
SYSTEM_PROMPT = (
"你是一个意图分类助手,判断用户输入是否与'中医'相关。\n"
"与中医相关的特征:询问中药材(性味、功效、用法用量、归经、产地、炮制等)、"
"方剂(组成、主治、宜忌、出处)、中医证候与病症(如咳嗽、失眠、脾虚、湿热)、"
"中医理论(阴阳五行、经络、辨证论治)、针灸推拿、药膳食疗,"
"或者描述身体不适并希望用中医方式调理。\n"
"与中医无关的特征:闲聊、编程、数学、天气、新闻、纯西医的药品与检查,"
"以及其他与中医药无关的话题。\n"
"请只回答:是 或 否,不要输出任何其他内容。"
)
def zhongyi_intent_node(state: AgentState) -> AgentState:
"""判断用户输入是否和中医意图相关,结果写回 is_zhongyi_intent"""
print("中医意图识别节点执行开始了")
user_input = (state.get("input_semantic_trans") or "").strip()
# 空输入不必调用大模型,直接判为无关
if not user_input:
state["is_zhongyi_intent"] = False
return state
messages = [
SystemMessage(content=SYSTEM_PROMPT),
HumanMessage(content=user_input),
]
response = llm.invoke(messages).content.strip()
# 模型可能返回"是的"、"否。"这类带尾巴的回答,所以取首字符判断
state["is_zhongyi_intent"] = response.startswith("是")
print(f"中医意图识别节点执行完成: {state['is_zhongyi_intent']}")
return state
if __name__ == "__main__":
for text in [
"麻黄的性味和功效是什么?",
"小柴胡汤由哪些药材组成?",
"我最近总是失眠,中医怎么调理?",
"帮我写一段 Python 快排代码",
"明天上海天气怎么样?",
"",
]:
result = zhongyi_intent_node({"input_semantic_trans": text})
print(f"{text!r} -> {result['is_zhongyi_intent']}")