】Agent 智能體)
文章目錄1. Agent2. 基礎使用3. 流式輸出4. ReAct 介紹5. middleware 中間件使用系列文章【agent 開發(fā)】agent 開發(fā)學習 - LangChain1【agent 開發(fā)】agent 開發(fā)學習 - LangChain2【agent 開發(fā)】agent 開發(fā)學習 - LangChain3前置介紹避免老年人跟不上時代也是時候開始學習 agent 相關的知識還是經典的黑馬程序員教程開始學習。1. Agent前面學習的都是普通的調用鏈 chain也就是固定好每一步要做什么而 Agent 與普通的調用鏈有著本質的區(qū)別區(qū)別在于誰來決定執(zhí)行步驟調用鏈是由開發(fā)者預先定義好的固定路徑而 Agent 則是由大語言模型LLM根據(jù)任務動態(tài)決定的執(zhí)行路徑。Agent 并不會遵循嚴格的腳本而是通過推理行動來自主決定下一步該做什么然后不斷循環(huán)思考 → 行動 → 觀察 → 再思考的過程直到收集到足夠信息并完成任務。2. 基礎使用Langchain 中通過create_agent就可以創(chuàng)建出一個 Agent同時可以將工具給智能體傳入使用的工具但是在執(zhí)行代碼之前更新下版本pip install -U langgraph langchain langchain-core langchain-community --force-reinstall不然會報錯cannot import name ‘ExecutionInfo’ from ‘langgraph.runtime’問 AI 說是版本過低了。from langchain.agentsimportcreate_agent from langchain_community.chat_models.tongyiimportChatTongyi from langchain_core.toolsimporttool tool(description查詢天氣)defget_weather()-str:return晴天agentcreate_agent(modelChatTongyi(modelqwen3-max),# 智能體的大腦LLM tools[get_weather],# 向智能體提供工具列表 system_prompt你是一個聊天助手可以回答用戶問題。,)resagent.invoke({messages:[{role:user,content:明天深圳的天氣如何},]})formsg in res[messages]:print(type(msg).__name__,msg.content)上面就是整體的代碼下面來看下輸出。HumanMessage 明天深圳的天氣如何 AIMessage ToolMessage 晴天 AIMessage 明天深圳的天氣是晴天適合外出活動記得做好防曬哦可以看到HumanMessage 下面的 AIMessage 是空也就是說大模型并沒有思考回復只是做了一個決策要用我們提供的工具get_weather來判斷明天深圳的天氣是什么接下來獲取到天氣之后再思考返回最終的 AIMessage。3. 流式輸出from langchain.agentsimportcreate_agent from langchain_community.chat_models.tongyiimportChatTongyi from langchain_core.toolsimporttool tool(description獲取股價傳入股票名稱返回字符串信息)defget_price(name:str)-str:returnf股票{name}的價格是20元tool(description獲取股票信息傳入股票名稱返回字符串信息)defget_info(name:str)-str:returnf股票{name}是一家A股上市公司專注于IT職業(yè)教育。agentcreate_agent(modelChatTongyi(modelqwen3-max),tools[get_price,get_info],system_prompt你是一個智能助手可以回答股票相關問題記住請告知我思考過程讓我知道你為什么調用某個工具)forchunk in agent.stream({messages:[{role:user,content:傳智教育股價多少并介紹一下}]},stream_modevalues):latest_messagechunk[messages][-1]# 如果有內容,就打印 AI 返回的回復iflatest_message.content:print(type(latest_message).__name__,latest_message.content)try:# 打印工具調用情況iflatest_message.tool_calls:print(f工具調用: {[tc[name] for tc in latest_message.tool_calls]})except AttributeError as e:pass輸出如下HumanMessage 傳智教育股價多少并介紹一下 工具調用:[get_price,get_info]ToolMessage 股票傳智教育是一家A股上市公司專注于IT職業(yè)教育。 AIMessage 傳智教育的當前股價是20元。這是一家A股上市公司專注于IT職業(yè)教育領域。如果您對該公司或其業(yè)務有更多具體問題可以隨時告訴我4. ReAct 介紹ReActReasoning Acting是一種讓大語言模型LLM通過思考-行動-觀察動態(tài)循環(huán)實現(xiàn)自主決策的智能體框架其核心在于交替生成推理步驟與具體行動并依賴環(huán)境反饋持續(xù)修正策略而非僅依賴內部知識完成任務。核心流程如下思考ThoughtLLM 分析當前任務生成可解釋的推理步驟明確下一步行動目標也就是是否需要調用外部工具來獲取更多信息。行動Action基于推理結果調用外部工具如搜索API、數(shù)據(jù)庫查詢執(zhí)行具體操作而非僅依賴模型內部知識。觀察Observation獲取上面第二步行動的結果提取出有效信息也就是獲取工具返回值判斷工具是否正常工作為下一輪大模型思考提供有效的信息。循環(huán)迭代LLM 根據(jù)觀察結果重新推理重復上述過程直至任務完成。上面幾個步驟的好處就是實時調整策略如果工具返回結果矛盾或缺失比如說搜索失敗根據(jù)觀察步驟Agent 可以立即更換關鍵詞或工具。決策過程比較透明因為上面的流程比較標準化所以可以追溯 AI 的每一次思考決定調用什么工具依此來去 debug。內外部知識融合上面的流程里面 AI 身份變成了決策者很多情況下都是決定要用什么工具而這些工具可以是我們自己提供這樣我們就可以把一些內部的資料或者一些實時的資料比如天氣也返回給 AI讓 AI 額外獲得實時查詢的能力。下面來看下演示代碼。from langchain.agentsimportcreate_agent from langchain_community.chat_models.tongyiimportChatTongyi from langchain_core.toolsimporttool tool(description獲取體重返回值是整數(shù)單位千克)defget_weight()-int:return90tool(description獲取身高返回值是整數(shù)單位厘米)defget_height()-int:return172agentcreate_agent(modelChatTongyi(modelqwen3-max),tools[get_weight,get_height],system_prompt你是嚴格遵循ReAct框架的智能體必須按「思考→行動→觀察→再思考」的流程解決問題 且**每輪僅能思考并調用1個工具**禁止單次調用多個工具。 并告知我你的思考過程工具的調用原因按思考、行動、觀察三個結構告知我,)forchunk in agent.stream({messages:[{role:user,content:計算我的BMI}]},stream_modevalues):latest_messagechunk[messages][-1]iflatest_message.content:print(type(latest_message).__name__,latest_message.content)try:iflatest_message.tool_calls:print(f工具調用 { [tc[name] for tc in latest_message.tool_calls] })except AttributeError as e:pass然后就是輸出情況。HumanMessage 計算我的BMI AIMessage**思考**計算BMI需要體重千克和身高厘米兩個數(shù)據(jù)當前兩者均未知。根據(jù)ReAct框架需分步獲取優(yōu)先獲取體重。**行動**調用get_weight工具獲取體重數(shù)據(jù)。 工具調用[get_weight]ToolMessage90AIMessage**觀察**獲取到體重為90千克。**思考**已獲得體重數(shù)據(jù)下一步需要獲取身高數(shù)據(jù)才能計算BMI。根據(jù)ReAct框架現(xiàn)在應調用獲取身高的工具。**行動**調用get_height工具獲取身高數(shù)據(jù)。 工具調用[get_height]ToolMessage172AIMessage**觀察**獲取到身高為172厘米。**思考**現(xiàn)在已獲得計算BMI所需的全部數(shù)據(jù)體重90千克身高172厘米。根據(jù)BMI公式體重(kg)/(身高(m))2可直接計算結果無需進一步調用工具。**行動**無工具調用直接計算并返回結果。 計算過程 身高轉換為米172cm1.72m BMI90/(1.72×1.72)≈90/2.9584≈30.4您的BMI約為30.4屬于肥胖范圍BMI ≥30??梢钥吹降氖沁@里面每一次 AI 調用都是調用一個那是因為我們在提示詞里面強制每次只調用一個工具方便查看調用過程。從上面過程也可以看到整體流程大概就是用戶輸入問題。模型思考需要獲取體重和身高由于用戶沒有傳因此從工具列表中先調用get_weight獲取體重。模型調用工具獲取到體重繼續(xù)新一輪思考判斷出還缺少身高于是從工具列表中通過get_height獲取身高。模型調用工具獲取到身高最后計算 BMI 返回。5. middleware 中間件使用中間件就是夾在【大模型 LLM思考層】和【外部工具 / 業(yè)務系統(tǒng)Action 執(zhí)行層】之間的一層軟件服務可以做翻譯、調度、管控、適配等工具其實就相當于攔截器了一些比較重要的場景如下日志記錄、分析、調試提示詞轉換工具選擇重試、備用、提前終止等邏輯控制安全防護、個人身份檢測下面是代碼的使用其實整體看起來感覺跟 Java 的 AOP 差不多。fromlangchain.agentsimportcreate_agent,AgentStatefromlangchain.agents.middlewareimportbefore_agent,after_agent,before_model,after_model,wrap_model_call,\ wrap_tool_callfromlangchain_community.chat_models.tongyiimportChatTongyifromlangchain_core.toolsimporttoolfromlanggraph.runtimeimportRuntimetool(description查詢天氣傳入城市名稱字符串返回字符串天氣信息)defget_weather(city:str)-str:returnf{city}天氣晴天 1. agent執(zhí)行前 2. agent執(zhí)行后 3. model執(zhí)行前 4. model執(zhí)行后 5. 工具執(zhí)行中 6. 模型執(zhí)行中 before_agentdeflog_before_agent(state:AgentState,runtime:Runtime)-None:# agent執(zhí)行前會調用這個函數(shù)并傳入state和runtime兩個對象print(f[before agent]agent啟動并附帶{len(state[messages])}消息)after_agentdeflog_after_agent(state:AgentState,runtime:Runtime)-None:print(f[after agent]agent結束并附帶{len(state[messages])}消息)before_modeldeflog_before_model(state:AgentState,runtime:Runtime)-None:print(f[before_model]模型即將調用并附帶{len(state[messages])}消息)after_modeldeflog_after_model(state:AgentState,runtime:Runtime)-None:print(f[after_model]模型調用結束并附帶{len(state[messages])}消息)wrap_model_calldefmodel_call_hook(request,handler):print(模型調用啦)returnhandler(request)wrap_tool_calldefmonitor_tool(request,handler):print(f工具執(zhí)行{request.tool_call[name]})print(f工具執(zhí)行傳入?yún)?shù){request.tool_call[args]})returnhandler(request)agentcreate_agent(modelChatTongyi(modelqwen3-max),tools[get_weather],middleware[log_before_agent,log_after_agent,log_before_model,log_after_model,model_call_hook,monitor_tool])resagent.invoke({messages:[{role:user,content:深圳今天的天氣如何呀如何穿衣}]})formsginres[messages]:print(type(msg).__name__,msg.content)上面我們定義了幾個 AOP 方法。before_agent在 Agent 執(zhí)行前調用這個函數(shù)參數(shù)是AgentState和Runtime。after_agent在 Agent 執(zhí)行結束調用這個函數(shù)參數(shù)是AgentState和Runtime。before_model在 model 執(zhí)行前調用這個函數(shù)參數(shù)是AgentState和Runtime。after_model在 model 執(zhí)行結束調用這個函數(shù)參數(shù)是AgentState和Runtime。wrap_model_call在模型調用的時候會回調這個方法參數(shù)是request和handler。wrap_tool_call在工具調用的時候會回調這個方法參數(shù)是request和handler。接下來在create_agent創(chuàng)建 Agent 的時候將這幾個方法作為中間件傳進去運行的時候就會被攔截然后執(zhí)行對應的邏輯了下面看下最后的輸出結果。[before agent]agent啟動并附帶1消息[before_model]模型即將調用并附帶1消息 模型調用啦[after_model]模型調用結束并附帶2消息 工具執(zhí)行get_weather 工具執(zhí)行傳入?yún)?shù){city:深圳}[before_model]模型即將調用并附帶3消息 模型調用啦[after_model]模型調用結束并附帶4消息[after agent]agent結束并附帶4消息 HumanMessage 深圳今天的天氣如何呀如何穿衣 AIMessage ToolMessage 深圳天氣晴天 AIMessage 深圳今天是晴天陽光明媚建議穿著輕便、透氣的衣物比如短袖T恤、薄款長褲或短褲。同時注意防曬可以戴帽子、太陽鏡并涂抹防曬霜哦可以看到執(zhí)行的順序就是Agent 開始 - model1 - tool - model2 - Agent 結束。如有錯誤歡迎指出