路線:Function Calling與ReAct循環(huán)核心解析)
AI Agent入門這個話題我前前后后帶過不少實習生和轉(zhuǎn)行過來的同事發(fā)現(xiàn)大家?guī)缀醪韧粋€坑上來不管三七二十一先搜“AI Agent框架對比”然后在langchain、dify、crewai之間反復橫跳折騰了兩三周最后連一個最簡單的工具調(diào)用demo都沒跑通。今天我想直接跟你說點實在的新手和轉(zhuǎn)行者入門AI Agent第一課不是框架而是把基礎(chǔ)能力補上來之后再碰框架。這篇內(nèi)容適合完全零基礎(chǔ)的小白也適合后端、前端、測試轉(zhuǎn)AI方向的同學參考。我會把Agent最核心的那點東西拆開揉碎講清楚并且給你一條可以直接照著學的基礎(chǔ)路線文章里給出的代碼也可以直接抄去當訓練項目用。1. 先搞明白一件事Agent和框架是兩碼事1.1 別被熱詞帶偏了節(jié)奏很多人理解錯了“AI Agent”這個詞。它不是一個工具、不是一個軟件而是一種程序范式。所謂Agent本質(zhì)上是讓大模型在一個循環(huán)里自主決策它分析你給的目標決定下一步調(diào)用什么工具看到工具返回的結(jié)果以后再決定下一步做什么直到任務(wù)完成。而框架是什么框架是別人提前把這一套循環(huán)邏輯封裝好、打包好的代碼庫。LangChain、Dify、CrewAI都干這件事只是封裝的程度、設(shè)計理念不一樣。打個比方Agent是你想做的菜框架是半成品料理包。你連火候、調(diào)味、刀工都沒練過上來先研究哪個料理包的供應(yīng)鏈更完善、哪個包裝盒更漂亮這不是本末倒置么你真正該做的是先把鍋鏟拿起來從最基礎(chǔ)的東西練起。1.2 入門之前先認清Agent的三件套不管業(yè)界怎么吹“多智能體”“自主規(guī)劃”“記憶增強”Agent跑起來其實就是這三樣東西大腦LLM負責理解、規(guī)劃、判斷。沒有大模型Agent就是一堆死代碼。手Tools大模型不能直接查天氣、訂票、讀寫數(shù)據(jù)庫你需要給它掛上工具它通過函數(shù)調(diào)用去操作外部世界。循環(huán)Loop思考-行動-觀察不斷重復直到得到一個滿意的結(jié)果。剩下什么規(guī)劃、記憶、反思、多Agent協(xié)作都是在這三件套之上疊加的增強手段。你如果一開始就鉆進框架源碼里很容易被各種抽象類、回調(diào)器、鏈式調(diào)用搞暈根本不知道該看哪里。反過來把上面三件套吃透再去看任何框架你都能一眼認出“哦這不就是一個循環(huán)外面包了一層封裝”。1.3 我總結(jié)的入門路線先基礎(chǔ)再原理后框架帶過的人多了我劃線劃得很清楚。新手和轉(zhuǎn)行者入門AI Agent按下面這個順序走就對了打基礎(chǔ)Python編程、異步處理、數(shù)據(jù)模型、調(diào)用大模型API。理解原理把Chat Completions消息結(jié)構(gòu)、Function Calling、ReAct循環(huán)搞明白。做最小實現(xiàn)不依賴任何框架自己手寫一個能調(diào)用工具的Agent跑通一個完整任務(wù)。再碰框架當你發(fā)現(xiàn)手寫代碼開始重復、要處理工程化問題的時候再去看LangChain、Dify這些。這個順序不是我拍腦袋定的。我見過太多人跳過前兩步直接卡在第四步。他們的問題非常類似丟一個Token進去不知道為什么會爆模型不按預期調(diào)用工具不知道參數(shù)哪里寫錯了配了一個Agent套娃出bug以后完全沒法調(diào)試。這些問題的根子都在基礎(chǔ)層。2. 啃框架之前先把這三項基礎(chǔ)夯實2.1 Python基本功至少要能寫異步和Pydantic很多轉(zhuǎn)行者說“我會Python”實際上只會print(hello)和for i in range(10)。做Agent開發(fā)Python水平要求沒那么玄乎但下面幾個點你必須能用起來類型注解函數(shù)簽名寫清楚參數(shù)和返回值的類型。你會發(fā)現(xiàn)自己寫代碼的時候思路會清晰很多而且Pydantic全靠它。異步編程async/awaitAgent經(jīng)常要并發(fā)調(diào)用多個工具、同時請求多個大模型接口不會asyncio后面會非常痛苦。Pydantic數(shù)據(jù)模型現(xiàn)在主流框架的數(shù)據(jù)校驗底層基本都是Pydantic。你會覺得它有點像寫類型定義但又能做校驗非常實用。我建議你花一周時間把FastAPI官方文檔里的教程過一遍。學完了以后你再看Agent框架會覺得好多概念特別眼熟道理都是一通百通的。2.2 消息結(jié)構(gòu)和Function CallingAgent的核心命脈Agent的底層工作對象是“消息”不是你腦子里的自然語言對話。你去看所有大模型API發(fā)送的內(nèi)容基本都是一組消息列表每條消息有角色和內(nèi)容system系統(tǒng)提示詞設(shè)定模型的身份和行為準則user用戶輸入assistant模型的回復tool工具執(zhí)行完以后返回的結(jié)果你會注意到真正的Agent工作流里這幾種角色會反復交替出現(xiàn)。模型輸出一段“需要調(diào)用工具”的指令你執(zhí)行完工具把結(jié)果以tool角色塞回去模型再接著回答。這個機制就是Function Calling函數(shù)調(diào)用。Function Calling的原理我可以一句話講明白你預先定義一批工具每一個工具都用JSON Schema格式來描述它接受什么參數(shù)。模型看到你的問題以后不直接執(zhí)行工具它只負責“決定該調(diào)用哪個工具、參數(shù)應(yīng)該填什么”返回給你一個結(jié)構(gòu)化的工具調(diào)用指令。真正的執(zhí)行還是由你的代碼去做的。很多新手不理解這件事為什么不讓模型直接執(zhí)行工具因為模型本身沒有“執(zhí)行代碼”的能力它只能輸出文本。同時讓代碼來控制執(zhí)行過程才是最安全、最可控的。理解了這一點你就理解了一半Agent。2.3 提示詞能力能不能控住模型Agent的穩(wěn)定性很大程度上取決于提示詞。新人覺得提示詞就是“你好請你幫我做某事”差遠了。你至少要學會這幾件事定義角色和邊界告訴模型它是什么、應(yīng)該做什么、不應(yīng)該做什么。給定輸出格式約束有時候你需要模型輸出JSON那就明確把JSON格式寫進系統(tǒng)提示甚至給一個示例。使用Few-shot給一兩個輸入輸出的示例模型理解你意圖的成功率會高非常多。善用CoT思維鏈讓模型“先分析再判斷最后給結(jié)論”而不是直接一股腦輸出。你會發(fā)現(xiàn)輸出質(zhì)量明顯提升。我見過一個特別典型的情況新手寫Agent提示詞就一句話“幫我查詢今天的天氣”然后抱怨“模型不調(diào)用工具”。你稍微改一改提示詞跟它說“你先根據(jù)用戶的問題判斷是否需要調(diào)用get_weather工具需要的話直接輸出json格式的工具調(diào)用”效果立竿見影。這就是提示詞能力帶來的差距。2.4 記憶的三種實現(xiàn)別上來就想著向量數(shù)據(jù)庫“Agent要擁有記憶”這句話把很多人帶偏了。有人一上來就要接Redis、上向量數(shù)據(jù)庫、裝Milvus結(jié)果基礎(chǔ)模型還沒跑通。記憶在Agent里其實分三個層次短期記憶在當前一輪對話的上下文里保留完整對話歷史直接拼進消息列表就行。長期記憶把關(guān)鍵信息存到外部存儲下次對話再取回來拼進系統(tǒng)提示或上下文。工作記憶Agent在執(zhí)行任務(wù)過程中臨時記錄的一些中間結(jié)果通常放在變量里或額外的上下文字段里。剛?cè)腴T先做好短期記憶就夠了。等你把簡單的上下文拼接做熟了再考慮引入向量檢索做長期記憶否則你會被“檢索效果差”“相關(guān)度不高”“存儲結(jié)構(gòu)設(shè)計不合理”這些問題折磨到崩潰。3. 從零手寫一個Agent源碼級拆解3.1 定義工具JSON Schema其實不復雜第一步是給大模型準備一份“工具說明書”。下面這段代碼我定義了一個查詢天氣的工具import json import os from openai import OpenAI client OpenAI( api_keyos.environ.get(OPENAI_API_KEY), base_urlos.environ.get(OPENAI_BASE_URL) ) def get_weather(city: str) - str: 真實環(huán)境下這里應(yīng)該去調(diào)用天氣服務(wù)API 這里為了演示直接返回固定字符串 return f{city} 今天多云最高氣溫 28℃適合出行。 tools [ { type: function, function: { name: get_weather, description: 查詢指定城市的實時天氣情況, parameters: { type: object, properties: { city: { type: string, description: 城市名稱比如 北京 } }, required: [city] } } } ]這段代碼一點花哨的東西都沒有但它把Agent工具機制的核心全講透了工具的名字要清晰描述要寫清楚什么情況用什么工具參數(shù)要定義好類型和必填項。模型會依據(jù)這個JSON結(jié)構(gòu)來決定怎么調(diào)用你的工具。3.2 主循環(huán)理解ReAct的思考-行動-觀察寫主循環(huán)是整個Agent實現(xiàn)里最重要的環(huán)節(jié)。我講課時經(jīng)常畫一個循環(huán)圖其實邏輯很簡單把當前消息列表發(fā)給大模型。檢查模型的回復。如果模型要求調(diào)用工具就執(zhí)行工具把工具結(jié)果以tool角色追加到消息列表然后回到第1步。如果模型給出最終回復直接把內(nèi)容返回給用戶循環(huán)結(jié)束。代碼實現(xiàn)如下def execute_tool(name: str, args_json: str): args json.loads(args_json) if name get_weather: return get_weather(args[city]) return 未找到該工具 def run_agent(user_input: str, messages: list) - str: messages.append({role: user, content: user_input}) for step in range(6): # 設(shè)置最大步數(shù)防止死循環(huán) resp client.chat.completions.create( modelgpt-4o-mini, messagesmessages, toolstools, tool_choiceauto, ) msg resp.choices[0].message if msg.tool_calls: # 模型要求調(diào)用工具 messages.append(msg) for tc in msg.tool_calls: tool_result execute_tool(tc.function.name, tc.function.arguments) messages.append({ role: tool, tool_call_id: tc.id, content: tool_result }) else: # 模型給出最終回答 messages.append(msg) return msg.content return 達到最大步數(shù)任務(wù)尚未完成請重試這個循環(huán)里有一個特別容易忽視的細節(jié)tc.function.arguments是一個寫JSON字符串你在真實項目里一定要做異常捕獲防止模型給出來的參數(shù)格式不合法。我在生產(chǎn)環(huán)境里遇到過一次模型把字符串參數(shù)里塞了換行符帶上奇怪的引號導致json.loads直接拋異常整個Agent就掛了。3.3 讓Agent記住對話別把歷史一股腦全塞進去上面的messages列表就是短期記憶。你可以把它保存到數(shù)據(jù)庫里下次用戶再來的時候查出來接著拼Agent看起來就“記住”了之前說過什么。但是這里有個坑消息列表不能無限增長。模型上下文窗口有限資金也不是無限的。你所有歷史消息全塞進去到后面既費錢又容易超出窗口報錯。我處理這個問題的原始辦法比較實用只保留最近幾輪對話或者把早期內(nèi)容做一層摘要用摘要代替長歷史。你可以先做第一種簡單粗暴等后面有需要再優(yōu)化摘要策略。這個思路同樣適用于你現(xiàn)在直接上手任何框架的時候因為框架只是把“手動拼消息”變成“自動拼消息”底層成本邏輯一點沒變。3.4 補一個真實的調(diào)用示例把上面代碼串起來你可以這么跑messages [] result run_agent(幫我看看北京今天怎么樣, messages) print(result)模型會先回復一個工具調(diào)用指令代碼執(zhí)行g(shù)et_weather把結(jié)果塞回消息模型再基于天氣結(jié)果生成最終回復。你可能會看到類似這樣的輸出北京今天多云最高氣溫 28℃適合出行。建議你穿一件薄外套中午活動注意防曬。整個鏈路就閉環(huán)了。你親手把這個閉環(huán)跑通以后再去學任何Agent框架都會有一種“這背后的東西我已經(jīng)懂了”的感覺學習效率完全不是一個量級。3.5 手寫Agent過程中我被問得最多的三個問題新手在做最小實現(xiàn)的時候經(jīng)常遇到一些奇怪問題這里我挑三個高頻的集中說一說第一個模型怎么也不調(diào)用工具怎么辦先檢查你的工具描述是否清晰再檢查提示詞里有沒有明確告訴模型“你可以調(diào)用工具完成用戶需求”最后把temperature調(diào)低一點我一般調(diào)到0.2左右可以降低隨機性。第二個agent陷入死循環(huán)怎么解決加最大步數(shù)限制跟我上面的代碼一樣。另外在工具的返回內(nèi)容里加入“如果這個結(jié)果已經(jīng)是最終結(jié)論請直接輸出”也能有效避免模型傻乎乎地一直原地重復。第三個工具返回結(jié)果太長導致上下文爆掉。工具該報異常就報異常該截斷就截斷不要無腦把幾千幾萬字原樣塞回消息列表。你給模型的信息越多它反而越容易抓不住重點。4. 什么時候可以碰框架選型與心態(tài)4.1 我建議你先問自己三個問題在你打開LangChain文檔之前先用手寫Agent跑通上面那個示例。然后問自己三個問題我是不是已經(jīng)在重復寫同一個主循環(huán)和消息拼接代碼我是不是需要一個RAG流程、內(nèi)存存儲、多Agent協(xié)作這些更復雜的機制我是不是需要快速做一個產(chǎn)品Demo給老板或客戶演示如果答案是“是”恭喜你現(xiàn)在可以去看框架了。如果三個都是“否”你想學框架純粹是因為“大家都在學”那我還是建議你把基礎(chǔ)再磨一磨。4.2 LangChain、Dify、CrewAI怎么選我簡單講一下這三個主流框架的差異方便你按自己的場景去選LangChain偏代碼層的編排庫適合開發(fā)者。它提供大量鏈、工具、記憶組件靈活度高但抽象層次比較多新手上手成本相對大。Dify偏產(chǎn)品化和工作流適合快速搭建應(yīng)用有可視化界面。你不太擅長寫代碼也可以拖拽出Agent應(yīng)用但要深入定制的時候反而不如LangChain自由。CrewAI主打多Agent角色協(xié)作特別適合做“幾個Agent分工配合”的場景。如果你要做任務(wù)拆解、角色扮演類Agent這個框架會省不少事。我的選型建議是先按場景選再看團隊熟悉度。如果你只是自己練手可以先把這三者各跑一個最小的Agent Demo精力不需要花太多重點看哪個最貼合你未來的項目場景。4.3 從框架源碼里學設(shè)計才是高層次的學習很多人用框架只停留在“照著文檔抄”出問題了不會排查。我想給你一個不一樣的角度當你已經(jīng)會手寫Agent以后看框架源碼是最佳的學習路徑。拿LangChain來說它里面有一個AgentExecutor類你扒開源碼會發(fā)現(xiàn)核心邏輯仍然是我的主循環(huán)里那個套路調(diào)用模型、判斷工具、執(zhí)行、返回??蚣茏龅氖虑槭菐湍惆堰@些步驟抽象成了可配置的對象讓你能做一些更靈活的處理比如錯誤重試、調(diào)用次數(shù)限制、工具超時等。這就好像你練毛筆字先自己一筆一劃寫熟了再去臨摹名家的字帖收獲很大。如果一開始就直接描摹你根本不知道哪些筆力扎實、哪些結(jié)構(gòu)巧妙。源碼閱讀同理它是你理解和鑒賞框架的最好方式。5. 新手和轉(zhuǎn)行者最容易踩的坑5.1 五個高頻問題速查我整理了一張表是我在實際帶人和做項目時反復遇到的問題你可以直接收藏當備查現(xiàn)象常見原因排查方向模型不調(diào)用工具工具描述不清晰、參數(shù)Schema有誤先跑一個最小工具確認Schema格式再檢查系統(tǒng)提示詞Token莫名其妙暴漲歷史消息無限制拼接、工具返回過長做歷史截斷、摘要限制工具返回內(nèi)容長度Agent進入死循環(huán)缺少最大步數(shù)、模型沒有終止條件加步數(shù)限制在提示詞中寫清“沒有新信息時直接回答”工具執(zhí)行失敗參數(shù)解析失敗、工具異常未捕獲對json.loads做異常處理給工具外層加try/except輸出結(jié)果不理想temperature過高、提示詞約束不夠調(diào)低temperature到0.2左右在系統(tǒng)提示里加入輸出格式約束5.2 排查技巧先懷疑你的提示詞再懷疑工具我見過太多人一遇到Agent表現(xiàn)不對第一反應(yīng)是“框架有問題”“模型有問題”“庫版本不對”。實際上絕大多數(shù)問題的根源都在提示詞和工具調(diào)用邏輯上。我的排查順序是這樣的先把temperature調(diào)低。手動把一條對話歷史打印出來逐條看消息角色和內(nèi)容是不是對的。檢查模型到底有沒有收到工具定義。很多人把tools參數(shù)忘了傳或者在代碼里拼錯了字段名。最后再懷疑框架和環(huán)境。你可能會發(fā)現(xiàn)80%的bug都是這幾個原因根本不用去翻框架源碼。5.3 給轉(zhuǎn)行者的一句實在話轉(zhuǎn)做AI Agent方向最大的優(yōu)勢其實是你的跨界背景。做后端的系統(tǒng)性思維強適合搞Agent工程架構(gòu)做前端的交互體驗敏感適合做Agent產(chǎn)品和界面做測試的對異常情況敏感特別適合做Agent的質(zhì)量保障和調(diào)試。別一上來就覺得“必須成為Prompt大師”“必須把所有框架都學會”。我?guī)Я诉@么多人真正決定你能不能在Agent方向走下去的反而是一次次debug之后積累起來的體感。你會逐漸知道模型什么時候會亂來、JSON參數(shù)為什么容易被解析錯、上下文為什么會失控這些東西不是你背多少框架文檔能替代的。最后再分享一個小技巧你應(yīng)該自己維護一個“踩坑筆記本”把每次遇到Agent異常、模型表現(xiàn)不符合預期的案例都記下來旁邊標注原因和解決方案。你自己整理的這套經(jīng)驗比任何別人的筆記都有效。這也是我到現(xiàn)在為止遇到Agent問題最快定位、最快解決的核心方法。