理论讲了三篇今天开始动手。我们要写一个知识库问答Agent——用户提问Agent检索知识库返回答案。这是最经典的Agent场景也是入门的最佳选择。20分钟从零到能运行。我们用LangGraph框架因为它和后端工作流思维最接近。先确认你要什么开始之前明确目标# 目标Agent的行为用户输入如何申请退款Agent1.检测到问题意图2.调用知识库搜索工具3.检索到退款流程文档4.返回退款流程订单页面 → 申请退款 → 填写原因 → 等待审核...这是一个简单的Agent但包含了核心要素意图识别理解用户问什么工具调用搜索知识库结果处理返回有价值的信息完成这个你就掌握了Agent开发的基本套路。第一步环境准备3分钟安装依赖pipinstalllanggraph langchain-openai langchain-community准备LLM。我们用OpenAI你也可以换其他# config.pyimportosfromlangchain_openaiimportChatOpenAI os.environ[OPENAI_API_KEY]your-api-keyllmChatOpenAI(modelgpt-4o-mini,temperature0)temperature0很重要。新手Agent我们先追求稳定性降低随机性。第二步定义工具5分钟Agent需要一个知识库搜索工具。我们模拟一个简单的知识库# tools.pyfromlangchain_core.toolsimporttool# 模拟知识库实际项目中会连接真实数据库KNOWLEDGE_BASE{退款: 退款流程 1. 登录账户进入订单页面 2. 找到需要退款的订单点击申请退款 3. 选择退款原因质量问题/不想要了/其他 4. 提交申请等待审核通常1-3天 5. 审核通过后退款将在3-5个工作日内退回原支付方式 注意已签收超过7天的订单不支持退款 ,发货: 发货说明 - 订单确认后24小时内发货 - 默认使用顺丰快递 - 发货后可在订单页面查看物流信息 - 一般时效一线城市2-3天其他地区3-5天 ,会员: 会员权益 - VIP会员享受10%折扣优先发货专属客服 - 普通会员享受5%折扣 - 会员升级累计消费满1000元自动升级VIP ,}tooldefsearch_knowledge(query:str)-str: 搜索知识库返回相关信息 Args: query: 搜索关键词如退款、发货、会员 Returns: 知识库中的相关信息如果没有找到返回未找到相关信息 # 简单的关键词匹配实际项目会用向量检索forkeyword,contentinKNOWLEDGE_BASE.items():ifkeywordinquery:returncontent.strip()return未找到相关信息请尝试其他关键词或联系人工客服tool装饰器是LangChain的规范。每个工具必须有清晰的docstring——这是Agent理解工具用途的唯一途径。第三步定义Agent状态4分钟LangGraph的核心是状态管理。后端开发者熟悉这个概念# state.pyfromtypingimportTypedDict,Annotated,Listfromlangchain_core.messagesimportBaseMessageclassAgentState(TypedDict): Agent的状态定义 这就像后端的Session对象存储对话过程中的所有信息 messages:Annotated[List[BaseMessage],对话历史]tool_results:Annotated[List[str],工具调用结果]final_answer:Annotated[str,最终答案]状态定义清晰你才能追踪Agent的执行过程。这和定义API请求/响应结构一样重要。第四步构建Agent工作流5分钟LangGraph用图来定义Agent的执行流程# agent.pyfromlanggraph.graphimportStateGraph,ENDfromlangchain_core.messagesimportHumanMessage,AIMessagefromlangchain_core.promptsimportChatPromptTemplatefromconfigimportllmfromtoolsimportsearch_knowledgefromstateimportAgentState# Prompt定义promptChatPromptTemplate.from_messages([(system,你是客服助手Agent。 当用户提问时先判断问题类型然后使用search_knowledge工具搜索相关信息。 如果找到相关信息整理后返回给用户。 如果没有找到告知用户并建议联系人工客服。 回答时要简洁清晰不要冗长。 ),(human,{input}),])# 节点调用LLM决策defagent_node(state:AgentState)-AgentState:Agent决策节点分析用户输入决定下一步user_inputstate[messages][-1].contentifstate[messages]else# 让LLM绑定工具进行决策llm_with_toolsllm.bind_tools([search_knowledge])responsellm_with_tools.invoke(prompt.format(inputuser_input))# 更新状态state[messages].append(response)returnstate# 节点执行工具调用deftool_node(state:AgentState)-AgentState:工具执行节点调用search_knowledge工具last_messagestate[messages][-1]# 检查是否有工具调用请求ifhasattr(last_message,tool_calls)andlast_message.tool_calls:fortool_callinlast_message.tool_calls:iftool_call[name]search_knowledge:resultsearch_knowledge.invoke(tool_call[args])state[tool_results].append(result)# 把工具结果作为消息加入对话历史state[messages].append(AIMessage(contentf工具返回{result}))returnstate# 节点生成最终答案defanswer_node(state:AgentState)-AgentState:答案生成节点根据工具结果生成最终回复tool_resultsstate[tool_results]user_questionstate[messages][0].contentifstate[messages]elseiftool_results:# 有工具结果整理后回答context\n.join(tool_results)answer_promptf根据以下信息回答用户问题 信息{context}用户问题{user_question}请简洁清晰地回答。responsellm.invoke(answer_prompt)state[final_answer]response.contentelse:# 没有工具调用直接用LLM回答state[final_answer]state[messages][-1].contentreturnstate# 路由函数决定下一步defshould_call_tool(state:AgentState)-str:判断是否需要调用工具last_messagestate[messages][-1]ifhasattr(last_message,tool_calls)andlast_message.tool_calls:returntoolelse:returnanswer# 构建工作流图workflowStateGraph(AgentState)# 添加节点workflow.add_node(agent,agent_node)workflow.add_node(tool,tool_node)workflow.add_node(answer,answer_node)# 设置入口workflow.set_entry_point(agent)# 添加边工作流路径workflow.add_conditional_edges(agent,should_call_tool,{tool:tool,answer:answer})workflow.add_edge(tool,agent)# 工具执行后回到Agent决策workflow.add_edge(answer,END)# 答案生成后结束# 编译工作流appworkflow.compile()这个工作流图和后端开发的流程图很像入口 → Agent决策 → 是否调用工具 ↓是 ↓否 工具执行 → Agent决策 → 答案生成 → 结束每一步都是明确的节点状态在各节点间传递。第五步运行Agent3分钟# main.pyfromlangchain_core.messagesimportHumanMessagefromagentimportappfromstateimportAgentStatedefrun_agent(user_input:str)-str:运行Agent返回答案initial_stateAgentState(messages[HumanMessage(contentuser_input)],tool_results[],final_answer)# 执行工作流resultapp.invoke(initial_state)returnresult[final_answer]# 测试运行if__name____main__:questions[怎么退款,发货需要多久,VIP会员有什么权益,我想投诉,]forquestioninquestions:print(f\n用户{question})answerrun_agent(question)print(fAgent{answer})运行效果用户怎么退款 Agent退款流程如下 1. 登录账户进入订单页面 2. 找到需要退款的订单点击申请退款 3. 选择退款原因 4. 提交申请等待审核通常1-3天 5. 审核通过后退款将在3-5个工作日内退回原支付方式 注意已签收超过7天的订单不支持退款 用户发货需要多久 Agent发货说明 - 订单确认后24小时内发货 - 一线城市2-3天送达其他地区3-5天 - 可在订单页面查看物流信息 用户VIP会员有什么权益 AgentVIP会员权益 - 享受10%折扣 - 优先发货 - 专属客服通道 - 累计消费满1000元可自动升级VIP 用户我想投诉 Agent未找到相关信息建议您联系人工客服处理投诉事宜。你的第一个Agent已经能用了。看看Agent做了什么我们加个追踪看看Agent内部的决策过程# debug.pyfromagentimportappfromstateimportAgentStatefromlangchain_core.messagesimportHumanMessagedefdebug_agent(user_input:str):调试Agent查看内部过程stateAgentState(messages[HumanMessage(contentuser_input)],tool_results[],final_answer)# LangGraph支持step-by-step追踪forstepinapp.stream(state):node_namelist(step.keys())[0]node_statestep[node_name]print(f\n{node_name}节点 )ifnode_nameagent:last_msgnode_state[messages][-1]print(fAgent思考{last_msg.content[:100]}...)ifhasattr(last_msg,tool_calls)andlast_msg.tool_calls:print(f决定调用工具{last_msg.tool_calls})elifnode_nametool:print(f工具结果{node_state[tool_results]})elifnode_nameanswer:print(f最终答案{node_state[final_answer]})debug_agent(怎么退款)输出 agent节点 Agent思考... 决定调用工具[{name: search_knowledge, args: {query: 退款}}] tool节点 工具结果[退款流程...] agent节点 Agent思考根据工具返回的信息用户想知道退款流程... 没有工具调用准备回答 answer节点 最终答案退款流程如下...你能看到Agent的完整决策链路第一次agent节点检测到退款问题决定调用search_knowledgetool节点执行工具返回知识库内容第二次agent节点拿到工具结果决定直接回答不再调用工具answer节点整理信息生成最终答案这个追踪能力和后端日志追踪一样重要。几个设计要点完成第一个Agent后回顾几个关键设计1. 工具定义要有明确边界tooldefsearch_knowledge(query:str)-str: 搜索知识库返回相关信息 Returns: 知识库中的相关信息如果没有找到返回未找到相关信息 返回格式明确要么返回信息要么返回未找到相关信息。不要返回空字符串或None——LLM无法理解。2. Prompt要有执行约束prompt 你是客服助手Agent。 当用户提问时先判断问题类型然后使用search_knowledge工具搜索相关信息。 如果找到相关信息整理后返回给用户。 如果没有找到告知用户并建议联系人工客服。 “先判断、再搜索、再回答”——这个顺序约束防止Agent跳过关键步骤。3. 状态要有生命周期classAgentState(TypedDict):messages:List[BaseMessage]# 对话历史tool_results:List[str]# 工具结果本轮final_answer:str# 最终答案tool_results是本轮的工具结果不是累积的历史。每轮对话开始时清空防止状态污染。4. 工作流要有终止条件workflow.add_edge(answer,END)# 明确的终止Agent不会无限循环。answer节点执行后直接END。你可以继续扩展这个Agent是基础版本你可以继续扩展扩展1添加更多工具tooldefcheck_order(order_id:str)-str:查询订单状态...tooldeftransfer_to_human(reason:str)-str:转人工客服...# Agent的tools列表更新llm_with_toolsllm.bind_tools([search_knowledge,check_order,transfer_to_human])扩展2支持多轮对话defrun_multi_turn_conversation():多轮对话模式stateAgentState(messages[],tool_results[],final_answer)whileTrue:user_inputinput(用户)ifuser_inputexit:breakstate[messages].append(HumanMessage(contentuser_input))state[tool_results][]# 清空本轮工具结果resultapp.invoke(state)stateresult# 更新状态保留对话历史print(fAgent{state[final_answer]})扩展3使用真实知识库# 用向量数据库替代模拟数据fromlangchain_community.vectorstoresimportChromafromlangchain_openaiimportOpenAIEmbeddings vectorstoreChroma.from_documents(documentsyour_documents,embeddingOpenAIEmbeddings())tooldefsearch_knowledge(query:str)-str:向量检索知识库resultsvectorstore.similarity_search(query,k3)return\n.join([doc.page_contentfordocinresults])回顾这20分钟你完成了环境准备安装LangGraph配置LLM工具定义search_knowledge工具清晰的输入输出状态定义AgentState管理对话信息工作流构建agent→tool→answer→END的执行路径运行验证Agent能正确回答问题更重要的是你用后端思维理解了Agent工具 外部服务调用状态 Session管理工作流 业务流程编排Prompt 接口定义自然语言版下一篇文章我们聊框架选型LangChain vs LangGraph vs CrewAI帮你理解不同框架的设计理念和适用场景。