11-Agent智能体【附详细代码案例】
文章目录简介演变过程两版本对比第一个智能体组装Agent工作原理v0.3Agent工作原理v1.0案例实战案例一案例二案例三简介Agent是一个决策引擎可以决定什么时候调用哪个Tool并根据上下文决定下一步应该做什么处理Tool返回的结果并决定是否需要继续调用其他Tool。Agent的核心是 推理 行动 Reason Act也就是ReAct模式。Agent LLM Memory Tools Planning Action为什么有了Tool还需要Agent场景Tool 能否解决Agent 的作用用户问“北京现在的天气怎么样”✅ 直接调用天气 Tool 就行❌ 不需要 Agent用户问“帮我订一张明天从北京到上海的机票并且查一下上海的天气”❌ Tool 无法决定先订票还是先查天气✅ Agent 会推理先订票 → 再查天气 → 组合结果用户问“我有一份 PDF帮我总结一下然后把总结发到我的邮箱”❌ 需要多个 ToolPDF读取、总结、发邮件✅ Agent 会按顺序调用多个 ToolTool与Agent的关系对象角色示例Tool能力组件数据查询、Python计算、API调用等Agent大脑/决策者判断使用哪个 tool、如何组合使用Tool 就像工具箱里的螺丝刀锤子Agent 就像一个有判断力的工匠,他知道什么时候用跟丝刀什么时候用锤子甚至知道先用缓丝刀再用锤子。演变过程两版本对比第一个智能体组装Agent工作原理v0.3在LangChainV0.3的Agents实际架构中Agent的角色是接收输入并决定采取的操作但它本身并不直接执行这些操作。这一任务是由AgentExecutor来完成的。将Agent (决策大脑)与AgentExecutor (执行操作的Runtime)结合使用才构成了完整的Agents(智能体)其中AgentExecutor负责调用代理并执行指定的工具以此来实现整个智能体的功能。工作流程可以分为以下步骤:输入解析语言模型分析用户输入理解任务目标。推理规划:使用推理框架(如ReAct)生成操作计划。ReAct就是结合推理和行动模型在每次迭代中思考(生成推理)并执行(调用工具)决定是否调用工具、调用哪些工具以及调用顺序。工具调用:根据推理计划调用工具传递输入并获取结果。工具结果反馈给语言模型迭代推理语言模型根据工具结果更新推理可能触发更多工具调用。循环直到任务完成或达到终止条件。语言模型综合所有信息生成最终答案。Agent工作原理v1.0案例实战案例一from langchain.chat_modelsimportinit_chat_modelfrom langchain_classic.agentsimportcreate_tool_calling_agent,AgentExecutorfrom langchain_core.promptsimportChatPromptTemplatefrom langchain_core.toolsimporttoolfrom lang_chain.configimportOPENAI_API_KEY# 多工具并行调用一次问题-多次工具调用-聚合回答 #1.定义普通工具tooldefget_weather(city:str)-str:根据城市名称查询天气信息。ifcity上海:return上海的天气为:{{weather: sunny, temperature: 20摄氏度}}elif city北京:return北京的天气为:{{weather: sunny, temperature: 25摄氏度}}else:return其他城市的天气为:{{weather: sunny, temperature: 30摄氏度}}tools[get_weather]#2.定义大模型 llminit_chat_model(modeldeepseek-chat,model_providerdeepseek,api_keyOPENAI_API_KEY,base_urlhttps://api.deepseek.com)#3.提示词模版 promptChatPromptTemplate.from_messages([(system,你是一个 helpful的天气助手.需要使用提供的工具来完成用户请求),(human,{input}),(placeholder,{agent_scratchpad}),])#4.创建Agentv0.3版本与AgentExecutor#Agent负责根据用户问题调用相应的工具类 #AgentExecutor负责协调Agent与工具类的执行过程 agentcreate_tool_calling_agent(llm,tools,prompt)agent_executorAgentExecutor(agentagent,# 要执行的Agent实例 toolstools,#Agent可调用的工具类 verboseTrue,# 是否显示详细信息 handle_parsing_errors解析用户请求失败重新输入)#5.执行Agentresultagent_executor.invoke({input:请问北京和上海的天气哪个城市更热})print(fAgentExecutor结果:{result})案例二importjsonfrom typingimportTypedDictfrom langchain.agentsimportcreate_agentfrom langchain.chat_modelsimportinit_chat_modelfrom langchain_core.toolsimporttoolfrom lang_chain.configimportOPENAI_API_KEY#1.定义普通工具tooldefget_weather(city:str)-str:根据城市名称查询天气信息。ifcity上海:return上海的天气为:{{weather: sunny, temperature: 20摄氏度}}elif city北京:return北京的天气为:{{weather: sunny, temperature: 25摄氏度}}else:return其他城市的天气为:{{weather: sunny, temperature: 30摄氏度}}tools[get_weather]#2.定义大模型 llminit_chat_model(modeldeepseek-chat,model_providerdeepseek,api_keyOPENAI_API_KEY,base_urlhttps://api.deepseek.com)#PS结构化输出classWeatherCompareOutput(TypedDict):beijing_temp:floatshanghai_temp:floathotter_city:str summary:str #3.创建Agentv1.0版本 agentcreate_agent(modelllm,toolstools,system_prompt(你是一个 helpful的天气助手.需要使用提供的工具来完成用户请求当用户询问多个城市天气时请使用多个工具分别查询每个城市天气然后将结果进行比较并返回最热的城市。),response_formatWeatherCompareOutput)#4.执行Agentresultagent.invoke({input:请问北京和上海的天气哪个城市更热})print(result)print(fAgent结构化结果:{json.dumps(result[structured_response],ensure_asciiFalse,indent2)})案例三from langchain.agentsimportcreate_agentfrom langchain.chat_modelsimportinit_chat_modelfrom langchain_core.toolsimporttoolfrom lang_chain.configimportOPENAI_API_KEY#1.模拟产品数据库PRODUCT_DATABASE{无线耳机:[{id:1,name:AirPods,popularity:99,price:299},{id:2,name:Bose QuietComfort,popularity:95,price:249},{id:3,name:Samsung Galaxy Buds,popularity:90,price:199},{id:4,name:Sony WH-1000XM4,popularity:85,price:399},{id:5,name:Jabra Elite 7t,popularity:80,price:299},],游戏鼠标:[{id:6,name:罗技,popularity:99,price:399},{id:7,name:三星 Galaxy Watch 4,popularity:95,price:299},{id:8,name:苹果 Watch Series 7,popularity:90,price:399},],笔记本电脑:[{id:9,name:Apple MacBook Air,popularity:99,price:899},{id:10,name:Dell XPS 13,popularity:95,price:799},{id:11,name:HP Spectre x360,popularity:90,price:699},{id:12,name:Lenovo ThinkPad X1 Carbon,popularity:85,price:599},{id:13,name:Fitbit Versa 3,popularity:90,price:199},{id:14,name:Garmin Venu 2,popularity:85,price:399},{id:15,name:Moto 360 Smartwatch,popularity:80,price:299},]}#2.模拟库存数据库INVENTORY_DATABASE{1:{stock:10,location:A1},2:{stock:5,location:A2},3:{stock:20,location:B1},4:{stock:15,location:B2},5:{stock:10,location:C1},6:{stock:12,location:C2},7:{stock:8,location:D1},8:{stock:18,location:D2},9:{stock:14,location:E1},10:{stock:22,location:E2},11:{stock:10,location:F1},12:{stock:12,location:F2},13:{stock:14,location:G1},14:{stock:22,location:G2},}#3.工具1:搜索产品tooldefsearch_products(query:str)-str|None:搜索产品并返回接受程度排序的结果 print(f[工具调用,search_products({query})]) keyword_mapping { 无线耳机: [无线耳机, 有线耳机, 蓝牙耳机], 智能手表: [智能手表, 智能手环, 智能腕表], 智能手环: [智能手环, 智能手表, 智能腕环], } # 匹配类别 matched_category None for category, keywords in keyword_mapping.items(): if any(keyword in query for keyword in keywords): matched_category category break return matched_category # 4.工具2:搜索库存 tool def search_inventory(product_id: str) - str: 搜索库存并返回结果 print(f[工具调用,search_inventory({product_id})]) if product_id in INVENTORY_DATABASE: stock_info INVENTORY_DATABASE[product_id] status 有库存 if stock_info[stock] 0 else 无库存 return f产品{product_id}: {status}, 库存数量: {stock_info[stock]}, 位置: {stock_info[location]} else: return 产品不存在:{product_id} # 5.定义大模型与agent llm init_chat_model( modeldeepseek-chat, model_providerdeepseek, api_keyOPENAI_API_KEY, base_urlhttps://api.deepseek.com ) agent create_agent( modelllm, tools[search_products, search_inventory], system_prompt你是一个 helpful的助手.遵循ReAct模式1.理解用户输入2.选择合适的工具执行操作3.基于工具返回的结果进行下一步推理4.重复上述过程直到得到最终结果,response_formatNone,)# 测试案例1无线耳机搜索 result1agent.invoke({messages:[{role:user,content:查找当前最受欢迎的无线耳机并检查是否还有库存}]})# 详细追踪ReAct循环过程 deftract_react_loop(messages):print(ReAct循环步骤分析)step1fori,msg inenumerate(messages):msg_typemsg.__class__.__name__ifmsg_typeAIMessageandhasattr(msg,tool_calls)and msg.tool_calls:print(f步骤{step}:ReasonAct)fortool_call in msg.tool_calls:print(f工具调用{tool_call[name]})step1elif msg_typeToolMessage:print(f观察结果{msg.content[:80]}...)elif msg_typeAIMessageand not(hasattr(msg,tool_calls)and msg.tool_calls):print(f最终结果{msg.content})tract_react_loop(result1[messages])