
如果你問我現在做一個 Agent第一反應應該用什么我的答案可能和大多數人不一樣——先別急著上 LangChain自己手寫一遍。不是框架不好用而是很多人在真正吃過苦頭之前壓根沒意識到框架到底替你做了什么又悄悄拿走了什么。這篇文章想聊的不是框架 vs 手搓誰更高級而是一個更現實的問題在什么階段框架是朋友在什么階段框架是債。一、框架的糖衣為什么它一開始如此誘人從零搭一個 Agent遠不止調一次大模型這么簡單。你需要定義工具 Schema讓模型知道每個工具叫什么、參數怎么傳要解析模型返回的 tool_calls判斷該不該繼續執行要在每一輪調用之間正確維護消息順序不能丟也不能亂要處理工具失敗、參數缺失、超時重試甚至還要把任務狀態、日志、Token 成本存下來方便回放。這些事情每一個 Agent 項目都得做一遍而且大同小異。框架的價值就在這里——把大量重復樣板封裝好你直接用就行。拿 LangChain 來說一個tool裝飾器就能注冊工具AgentExecutor把整個 ReAct loop 收進去還內置了 tracing、callback、記憶管理。探索期它真的讓人上癮幾十行代碼搭起一個能跑的 Agent兩周的工作壓縮到兩天。這種爽感是真實的沒必要否認。二、痛點從什么時候開始出現框架的問題不是一開始就暴露的而是隨著項目推進在不同階段逐漸浮出來。第一個奇怪的 bug 出現之后感覺就變了。Agent 在某個特定場景下輸出了錯誤的工具參數你開始排查。代碼只有五十行但報錯的 stack trace 有四十層往下追到了框架內部。你不知道問題出在你寫的那五十行里還是框架某個版本的邏輯變化或者是 callback 觸發時機的問題。你只能在 GitHub issue 里翻或者一層層啃框架源碼。有個類比很貼切老式車出了問題打開引擎蓋自己就能看到哪根管子漏油現代豪華車出了問題你打開引擎蓋看到的是一堆你看不懂的電子設備只能去 4S 店讓診斷儀掃。框架的抽象層太多排查問題需要穿透那些你沒寫、也不完全懂的層這是實實在在的認知負擔。有篇反思寫得更狠——LangChain 一度是AI 界的 jQuery火過一陣子然后成了負債。作者讀了全部源碼在凌晨兩點排過由框架內部邏輯導致的線上事故最后得出一個結論現代 AI 工程需要的是更少的抽象而不是更多。另一篇《Why I Stopped Using LangChain》把這種代價稱作抽象稅——你用一段不透明的邏輯代碼置換了原本清晰的 API 請求。版本升級踩坑是另一個階段的痛苦。線上跑了好幾個月某次依賴升級LangChain 改了接口代碼直接報錯。你要么回滾要么把代碼改到兼容新版本可能涉及十幾處修改。早期 LangChain 版本升級頻率很高breaking change 是常態。有意思的是后來官方自己都把AgentExecutor廢棄了推薦遷移到 LangGraph——這本身就印證了框架設計在不斷變化而你把核心業務邏輯建立在一個變動頻繁的第三方框架上穩定性就得看別人臉色。再到規模化階段性能優化時你會撞見隱性開銷。你開始關心 Agent 的調用延遲發現某步 LLM 調用本身很快但總耗時超預期。仔細 profile 之后才發現框架內部每次調用都在做你根本不需要的事序列化中間結果、觸發一堆 callback、記錄詳細日志。這些邏輯是框架為了通用性設計的對你的場景沒用但每次都在跑。有對比測試顯示相同功能下 LangChain 的響應時間比直接調 API 平均高出 40% 到 60%。高流量下這些隱性開銷累積起來就是真實的延遲增加和費用浪費。三、手搓的本質優勢完全掌控說清楚框架的痛點之后手搓的價值就清楚了。它的核心優勢說白了就是三個字——完全掌控。第一是鏈路透明、可觀測性好。手搓的每一行代碼你都知道在干什么可以在任意位置加日志、打斷點、插入監控沒有任何黑盒。線上出了故障靠日志復現是最快的方式鏈路越清晰定位根因越快。這在生產環境里是真實的時間和成本節省。有實踐團隊算過一筆賬自定義管線前期的開發成本多花 2 到 4 周但整個項目生命周期里能省下 4 到 8 周——因為后期調試省下來的時間遠大于前期搭建的投入。第二是精確裁剪、沒有多余開銷。你只寫你確確實實需要的那部分邏輯不帶任何通用性包袱。工具調用、對話歷史維護、錯誤重試每一塊都按你的具體場景實現沒有為了兼容其他用法而存在的冗余代碼。在性能敏感的場景里這意味著優化空間完全在你手里不用繞過框架的限制來做裁剪。第三是穩定可控、不受框架升級影響。你自己寫的接口不會突然變沒有來自外部的 breaking change。依賴只剩底層的 LLM SDK相對穩定生產環境可以長期運行不用擔心某次例行升級把線上跑壞。其實這個觀點不只是個人經驗。Anthropic 在官方的 Agent 構建指南里也明確建議過不要一上來就用框架先用最少的抽象把核心邏輯跑通。他們的意思很接近——框架的抽象層會讓你離底層更遠一旦出了問題調試成本比你省下的開發時間還高。這和實際項目里的感受完全一致框架幫你快速搭起來的東西往往也是后期最難排查的東西。有個類比能很好地概括框架是租房裝修好直接住方便但結構改不了房東隨時可能調整政策手搓是自建建起來慢但所有結構都熟悉想改什么都能改住著踏實。框架給你省了搭建時間但你對這個房子的控制權始終有限。四、同一個需求框架寫 vs 手搓寫差別在哪光說理論還不夠直觀拿最常見的場景對比一下實現一個帶工具調用的 Agent loop。用框架寫大概是這么幾行fromlangchain.agentsimportAgentExecutor,create_openai_tools_agent agentcreate_openai_tools_agent(llm,tools,prompt)executorAgentExecutor(agentagent,toolstools)resultexecutor.invoke({input:幫我查一下今天的天氣})三四行就跑起來了確實簡潔。但問題是當你想知道這次調用里 LLM 返回了什么、工具是怎么被選中的、消息列表是什么順序的時候你得去讀AgentExecutor的源碼它內部的調用鏈可能有十幾層。手搓同樣的功能代碼量多一些但每一步都在你眼前messages[{role:system,content:system_prompt}]messages.append({role:user,content:user_input})foriinrange(max_turns):# 手動控制最大輪次responseclient.chat.completions.create(modelgpt-4,messagesmessages,toolstool_schemas)msgresponse.choices[0].message messages.append(msg)# 把 LLM 響應加入對話歷史ifnotmsg.tool_calls:# 沒有工具調用LLM 認為任務完成breakfortcinmsg.tool_calls:# 有工具調用逐個執行并寫回resultexecute_tool(tc.function.name,tc.function.arguments)messages.append({role:tool,tool_call_id:tc.id,content:result})logger.info(f工具{tc.function.name}返回:{result})# 隨意加日志手搓版本里消息列表怎么拼的、工具怎么選的、循環什么時候退出每一個細節都擺在明面上。出了問題你看這二三十行代碼就夠了不用去翻框架源碼。這就是完全掌控的具體含義——不是說框架不好而是當你需要理解和調試每一個環節時手搓版本給你的確定性是框架給不了的。這和《工程實踐中為什么有時手搓Agent 而不直接用現成框架》的核心判斷一致框架是黑盒難調試、依賴頻繁變動、prompt 難以精細控制而手搓換來的是完全可控的 prompt 與控制流。手搓不是炫技是為了拿回控制權。五、什么時候用框架什么時候手搓這不是非此即彼的選擇判斷關鍵看項目所處的階段以及你對控制權的需求。框架適合這些時機POC 階段快速驗證 idea目標是跑通而不是優化團隊剛接觸 Agent 開發用框架能少踩一些基礎性的坑周邊工具文檔解析、向量檢索依賴框架的生態而核心邏輯本身復雜度不高。這些場景里框架帶來的速度優勢是真實的值得用。低代碼可視化框架Dify、Coze尤其適合非技術團隊主導的快速驗證和 MVP 場景。手搓的時機準備上生產、穩定性成為核心關切流量開始上來性能和成本變得敏感業務邏輯高度定制和框架的通用設計偏差很大改起來反而費勁團隊需要高可觀測性鏈路要能隨時監控和回溯。選型原則其實很簡單簡單場景優先低代碼提效復雜核心場景用代碼級框架或自研來保障可控性。六、折中方案核心手寫周邊借用實踐中最常見也最務實的是介于兩者之間的折中核心邏輯手寫周邊工具性功能借用框架。控制邊界的邏輯是這樣的工具調用的循環、對話歷史的管理、錯誤處理和重試、任務狀態的維護這些是 Agent 的心臟直接決定系統行為必須百分百理解、百分百掌控所以手寫。而 LangSmith 的 tracing、LlamaIndex 的文檔解析、某個向量庫的 Python 客戶端這些是工具性的周邊功能出了問題一眼就能看出來不會帶來黑盒困境用外部工具節省時間完全值得。就像蓋房子承重墻在哪、房間怎么布局你必須完全掌控但門鎖、插座面板、水龍頭完全可以買現成的不必自己從頭制造每一個零件。真實項目往往走這樣一條路先用框架快速跑通、驗證方向遇到第一批線上問題之后把排查困難的關鍵部分替換為手寫流量上來之后把性能敏感的核心邏輯全部手寫最后框架只保留做得好的周邊工具。這條路既享受了早期框架的速度又在生產階段拿回了掌控權。有篇回國復盤寫得很實在——“從狂熱到理性”作者最初半年每天都用 LangChain 提交代碼兩年后技術棧里已經找不到它便利背后藏著過度抽象的性能損耗、黑箱化帶來的調試困難以及最關鍵的當你想突破框架限制時的束手束腳。寫在最后有一個判斷信號可以參考如果你能清楚說出框架在某個地方替我做了什么、我用的這個方法內部發生了什么說明你理解它用起來有掌控感如果你只是調了一個方法但完全不知道里面發生了什么出了問題就是一個不透明的黑盒——這才是需要警惕的信號。所以手搓從來不是要去貶低框架更不是炫技。它是把決定系統行為的核心邏輯寫清楚把該自己扛的控制權拿回來。框架不是問題不理解就依賴才是。這也是我想勸你先手搓一遍的根本原因真正寫過一遍那個 while 循環你才理解框架替你打包了什么、又藏起了什么。等你真的理解了再回去用框架那時你才是它的主人而不是它的乘客。權拿回來。框架不是問題不理解就依賴才是。這也是我想勸你先手搓一遍的根本原因真正寫過一遍那個 while 循環你才理解框架替你打包了什么、又藏起了什么。等你真的理解了再回去用框架那時你才是它的主人而不是它的乘客。