文章目录
LangGraph项目实例
一个典型的基于LangGraph的智能客服工作流,其核心思想是:根据用户的提问,决定调用不同的工具或采取不同的策略,并最终生成回答。我将简单使用LangGraph实现这一个工作流,其中的RAG检索我将采用模拟的方式。以下是整个工作流图。

流程步骤
一、开始 (用户输入问题):工作流的起点,接收用户提出的问题。
二、意图识别与分类:这是整个工作流的决策核心(Router)。由一个大型语言模型(LLM)来分析用户输入的意图,并将其分类到不同的处理分支。
- 常规问题:例如“你好”、“你是谁”,直接交给通用对话链处理。
- 专业领域问题:例如“产品A的保修期是多久?”,需要进入RAG流程。
- 人工客服请求:例如“转人工”,进入相应流程。
- 无法处理/无关问题:例如用户胡言乱语,进入委婉拒绝流程。
三、分支处理:
- 1. 调用通用对话链:使用LLM的通用知识生成友好、自然的回复。
- 2. RAG(检索增强生成):
- 将用户问题转换为查询语句,在向量数据库等知识库中搜索最相关的文档片段。
- 2.1. 相关性检查:这是一个质量控制点。再次使用LLM判断检索到的内容是否真正与用户问题相关,避免“幻觉”或答非所问。
- 如果相关,则基于这些检索到的可靠内容生成回答(H)。
- 如果不相关,则告知用户无法找到答案,并可建议下一步操作(I)。
- 3. 生成转接提示信息:告知用户即将转接至人工客服,或说明人工客服的工作时间。
- 4. 生成委婉拒绝回复:礼貌地告知用户该问题超出了自己的能力范围。
四、组装最终回复:将所有分支的处理结果汇聚到此节点,准备最终输出。在复杂流程中,这里可能还会做一些格式整理、添加免责声明等后处理操作。
五、结束 (返回回答):工作流的终点,将最终生成的回答返回给用户。
项目实操
一、导入依赖
uv add langgraph langchain
二、创建项目结构
project/
├── state.py
├── tools.py
├── nodes.py
├── graph.py
├── main.py
三、state.py - 状态定义模块
主要定义的是state,方便每个节点后续的使用。
from langgraph.graph import MessagesState
class AgentState(MessagesState):
question: str
response: str
router: str
RAG_Content : str
四、tools.py - 工具函数模块
定义llm模型、RAG模型(模拟),我这就只写了一个llm模型,
from langchain_openai import ChatOpenAI
# 初始化LLM并绑定工具
llm = ChatOpenAI(
openai_api_key="***************************",
base_url="https://api.siliconflow.cn/v1",
model="Qwen/Qwen2.5-7B-Instruct"
)
五、nodes.py - 节点函数模块
每个节点对应的操作,我这里只有在整合RAG内容的时候调用了LLM,其余几个分支我直接返回的一个写死的结果。
from state import *
from langchain_core.messages import HumanMessage, SystemMessage
from tools import *
# 定义意图分类函数
def intent_classification(state: AgentState):
system_msg = """请分类用户的问题类型:
- conventional: 问候、通用知识问题
- Major: 专业领域问题(如产品、服务、政策等)
- Custom_Server: 明确要求转人工客服
- forbidden: 我规定不准用户查有关天气的所有信息。
只返回分类结果,不要解释。"""
messages = [
SystemMessage(content=system_msg),
HumanMessage(content=state["question"])
]
router = llm.invoke(messages).content
state["router"] = router
return state
def intent_router(state: AgentState):
router = state["router"]
return router
def conventional(state: AgentState):
state["response"] = "常规回答"
return state
def Major(state: AgentState):
state["response"] = "专业知识回答"
#模拟的RAG,内容相关。
state["RAG_Content"] = "退货政策是无需退还货物,直接申请退款即可"
system_msg = f"你是一个售后服务人员你要回答用户的提问,搜索到的外部知识:{state["RAG_Content"]}"
messages = [
SystemMessage(content=system_msg),
HumanMessage(content=state["question"])
]
content = llm.invoke(messages).content
state["response"] = content
return state
def Custom_Server(state: AgentState):
state["response"] = "转人工"
return state
def forbidden(state: AgentState):
state["response"] = "拒绝回答"
return state
六、graph.py - 图构建模块
以下是整个工作流程。
from langgraph.graph import *
from nodes import *
def create_workflow():
workflow = StateGraph(AgentState)
workflow.add_node("conventional", conventional)
workflow.add_node("Major",Major)
workflow.add_node("Custom_Server",Custom_Server)
workflow.add_node("forbidden",forbidden)
workflow.add_node("intent_classification",intent_classification)
workflow.add_edge(START,"intent_classification")
workflow.add_conditional_edges("intent_classification",intent_router,{
"conventional":"conventional",
"Major":"Major",
"Custom_Server":"Custom_Server",
"forbidden":"forbidden",
})
workflow.add_edge("conventional",END)
workflow.add_edge("Major",END)
workflow.add_edge("Custom_Server",END)
workflow.add_edge("forbidden",END)
return workflow.compile()
七、main.py - 主程序模块
from graph import create_workflow
def main():
# 编译图
app = create_workflow()
# 测试不同问题
test_questions = [
"你好",
"你们的退货政策是什么?",
"我要找人工客服",
"今天天气怎么样?",
"配送需要多长时间?"
]
for question in test_questions:
print(f"用户问题: {question}")
# 初始化状态
state = {"question": question}
# 运行图
final_state = app.invoke(state)
print(f"回答: {final_state["response"]}")
print("-" * 50)
if __name__ == "__main__":
main()
八、运行结果
以下就是整个代码的运行结果,不同的问题走了不同的分支,完成了一个简单的智能客服的这么一个小项目。

总结
这次用 LangGraph 搭智能客服,就是将“流程图终于成了代码本身”。过去做对话系统,路由逻辑散在 if-else 里,想加一条分支得翻五六层函数;现在把“意图识别”“RAG 检索”“转人工”都拆成独立节点,在一张 StateGraph 里用条件边串起来,节点只管读状态、写状态,图只管调度,逻辑一目了然。
将 RAG 环节整个模拟掉,向量检索直接返回一段写死的退货政策,但后续可以把模拟直接替成真向量库。之后加 rerank、接人工客服,都只是“再画一个节点、再拉一条边”的事。
:智能客服项目示例(流程+完整代码)&spm=1001.2101.3001.5002&articleId=151576120&d=1&t=3&u=314d6cf816f84941bff87f21182d0b45)
1914

被折叠的 条评论
为什么被折叠?



