用:Agent開發(fā)避坑指南與擴(kuò)展路徑)
大家做 Agent 最常卡住的地方不是框架選型不是記憶設(shè)計(jì)也不是工具調(diào)用鏈而是連第一行大模型調(diào)用都沒跑通。我最近重新整理自己的 Agent 項(xiàng)目把之前踩過的坑翻出來復(fù)盤一遍發(fā)現(xiàn)第一次跑通大模型調(diào)用的代碼其實(shí) 10 行就能搞定但如果沒有經(jīng)驗(yàn)這個(gè)過程中足夠讓你踩出四五個(gè)跟頭。這篇文章就圍繞“10 行代碼跑通大模型調(diào)用”這條主線寫把環(huán)境準(zhǔn)備、代碼拆解、四個(gè)典型坑、以及從一次調(diào)用走向 Agent 的擴(kuò)展思路全部串起來。已經(jīng)跑過 API 的老手可以直接跳到第二部分看踩坑記錄剛上手的朋友建議從頭讀完每一步我給的都是可直接復(fù)制運(yùn)行的方案。1. 內(nèi)容整體設(shè)計(jì)與思路拆解1.1 為什么從“調(diào)大模型”開始才是 Agent 的正確起跑線很多人一上來就翻 Agent 框架的文檔什么規(guī)劃、記憶、工具調(diào)用、多智能體協(xié)作看了一堆結(jié)果自己動(dòng)手寫的時(shí)候連“把一句話發(fā)給大模型再拿回結(jié)果”這一步都做得磕磕絆絆。其實(shí) Agent 的上層玩法再花哨底層都離不開一個(gè)最基礎(chǔ)的能力穩(wěn)定、可控地調(diào)用大模型。就像蓋樓先打地基調(diào)用大模型就是 Agent 的地基。我從零手?jǐn)] Agent 的第一步就是先讓一個(gè)真實(shí)的模型調(diào)用跑起來。這聽起來簡(jiǎn)單實(shí)際操作中卻涉及到 API 密鑰管理、請(qǐng)求參數(shù)設(shè)置、超時(shí)處理、返回結(jié)構(gòu)解析、異常捕獲等多個(gè)環(huán)節(jié)。標(biāo)題里說的“10 行代碼”指的是核心邏輯控制在 10 行以內(nèi)但為了讓它穩(wěn)定跑通前后需要補(bǔ)的環(huán)境準(zhǔn)備和防護(hù)代碼才是真正決定成敗的部分。這里也給正準(zhǔn)備入坑的朋友一個(gè)明確的建議初期不要去折騰那些復(fù)雜的 Agent 框架直接用大模型廠商提供的官方 SDK自己寫一個(gè)最簡(jiǎn)調(diào)用感受一下“發(fā)請(qǐng)求、收響應(yīng)、解析結(jié)果”這個(gè)最基本的閉環(huán)。這一步跑順了后面所有 Agent 的復(fù)雜功能才有附著點(diǎn)。1.2 這 10 行代碼解決的核心問題是什么先說結(jié)論這段代碼解決的就是一個(gè)最基礎(chǔ)的問題——把用戶輸入發(fā)送給大模型拿到模型返回的文本結(jié)果。聽起來平平無奇但這是后續(xù)一切 Agent 能力的底座。比如你想給 Agent 加“記憶”本質(zhì)是把歷史消息一起拼到請(qǐng)求里再發(fā)送你想給 Agent 加“工具調(diào)用”本質(zhì)是在請(qǐng)求里聲明可用工具然后解析模型返回的工具調(diào)用指令你想給 Agent 加“多步推理”本質(zhì)是循環(huán)執(zhí)行“發(fā)請(qǐng)求-拿結(jié)果-再發(fā)請(qǐng)求”這個(gè)動(dòng)作。所以別看 10 行代碼簡(jiǎn)單它背后是 Agent 邏輯閉環(huán)的最小原型。1.3 技術(shù)選型為什么用官方 SDK 而不是 HTTP 直連第一次做模型調(diào)用很多人糾結(jié)用 requests 直接發(fā) HTTP 請(qǐng)求還是用官方 SDK。我的建議非常明確用官方 SDK。原因有四個(gè)官方 SDK 封裝好了鑒權(quán)、簽名、請(qǐng)求重試這些繁瑣細(xì)節(jié)減少初期的出錯(cuò)面。SDK 內(nèi)部對(duì)返回結(jié)構(gòu)做了處理拿結(jié)果比手動(dòng)解析 JSON 更省事。官方 SDK 會(huì)跟隨模型版本升級(jí)同步更新字段不容易出現(xiàn)“接口格式變了但代碼沒改”的問題。社區(qū)和官方文檔的示例代碼基本都是基于 SDK 寫的遇到問題更容易搜到答案。當(dāng)然如果你用的模型比較冷門或者有特殊的網(wǎng)絡(luò)環(huán)境限制可能需要退回到 HTTP 直連。但那是少數(shù)情況不在本文的討論范圍內(nèi)。我這里用最常見的 OpenAI SDK 格式作為示例其實(shí)國(guó)內(nèi)很多大模型的 SDK 都是與之兼容的代碼幾乎可以無縫切換。2. 核心細(xì)節(jié)解析與實(shí)操要點(diǎn)2.1 環(huán)境準(zhǔn)備把路鋪平再出發(fā)跑代碼之前有幾個(gè)準(zhǔn)備工作必須做。第一個(gè)是安裝 SDK。我建議用一個(gè)獨(dú)立的虛擬環(huán)境避免跟系統(tǒng)其他項(xiàng)目依賴沖突。創(chuàng)建虛擬環(huán)境的命令很簡(jiǎn)單python -m venv agent_env source agent_env/bin/activate # Windows 下是 agent_env\Scripts\activate pip install openai python-dotenv這里同時(shí)裝了 python-dotenv是為了管理 API Key。強(qiáng)烈建議不要把密鑰直接硬編碼在代碼里一方面是有泄露風(fēng)險(xiǎn)另一方面是后續(xù)不方便換 Key。在項(xiàng)目根目錄創(chuàng)建一個(gè).env文件里面寫上 API KeyOPENAI_API_KEYsk-你的密鑰代碼里用load_dotenv()加載然后從環(huán)境變量讀取。這一步雖然多花了十秒鐘但能幫你避開一個(gè)極大的隱患代碼誤上傳到公開倉(cāng)庫(kù)導(dǎo)致密鑰泄露。我見過不止一個(gè)朋友因?yàn)橛簿幋a Key最后 Key 被別人盜刷損失慘重。2.2 10 行核心代碼逐行拆解直接上代碼我這次用的模型調(diào)用格式是當(dāng)前主流的 Chat Completions 風(fēng)格兼容 OpenAI SDK 的大模型廠商都可以用from openai import OpenAI from dotenv import load_dotenv import os load_dotenv() client OpenAI(api_keyos.getenv(OPENAI_API_KEY)) response client.chat.completions.create( modelgpt-4o-mini, messages[{role: user, content: 你好請(qǐng)用一句話介紹你自己}], timeout30 ) print(response.choices[0].message.content)八行代碼加上一個(gè)空行滿打滿算 10 行。逐個(gè)拆解一下作用第 1-3 行導(dǎo)入 SDK 和系統(tǒng)庫(kù)。OpenAI 是客戶端主類dotenv 負(fù)責(zé)加載環(huán)境變量文件os 用于讀取環(huán)境變量。第 5 行加載.env文件把里面的 API Key 注入到環(huán)境變量這行必不可少少了她你會(huì)得到一個(gè) None。第 6 行創(chuàng)建客戶端實(shí)例。傳入 API Key這個(gè) client 后面所有請(qǐng)求都復(fù)用不需要每次重復(fù)創(chuàng)建。第 8-12 行核心請(qǐng)求。指定模型名傳入消息列表設(shè)置超時(shí)時(shí)間。這個(gè)messages參數(shù)是后續(xù)做 Agent 的抓手它支持多輪對(duì)話和系統(tǒng)提示詞。第 13 行從返回結(jié)構(gòu)中提取文本內(nèi)容。response 是一個(gè)復(fù)雜的嵌套對(duì)象choices[0]是第一個(gè)候選結(jié)果.message.content才是模型回答的文本。2.3 返回結(jié)構(gòu)到底長(zhǎng)什么樣第一次調(diào)用大模型很多人會(huì)print整個(gè)response看看里面有什么這完全正確但你要做好心理準(zhǔn)備——返回結(jié)構(gòu)比你想象中復(fù)雜得多。以 Chat Completions 為例核心結(jié)構(gòu)大致是這樣的{ id: chatcmpl-xxx, object: chat.completion, created: 1234567890, model: gpt-4o-mini, choices: [ { index: 0, message: { role: assistant, content: 你好我是一個(gè)人工智能助手... }, finish_reason: stop } ], usage: { prompt_tokens: 13, completion_tokens: 12, total_tokens: 25 } }初次接觸可能會(huì)被這個(gè)嵌套結(jié)構(gòu)嚇到其實(shí)只需要關(guān)心三個(gè)地方choices[0].message.content模型回答的正文、choices[0].finish_reason結(jié)束原因是正常結(jié)束還是因?yàn)殚L(zhǎng)度截?cái)?、usage本次請(qǐng)求消耗的 token 數(shù)做成本統(tǒng)計(jì)用。這三個(gè)字段是后續(xù) Agent 開發(fā)天天要打交道的核心字段建議直接把這一小段 JSON 存成筆記后面寫代碼時(shí)經(jīng)常翻。2.4 第一次運(yùn)行前必做的兩個(gè)小驗(yàn)證代碼寫完之后別急著直接跑正常請(qǐng)求。我建議先做兩個(gè)小驗(yàn)證把問題提前暴露出來。第一個(gè)是驗(yàn)證 API Key 能不能用。可以在.env文件所在目錄執(zhí)行一個(gè)極簡(jiǎn)測(cè)試腳本只打印 Key 的前幾位import os from dotenv import load_dotenv load_dotenv() key os.getenv(OPENAI_API_KEY) print(Key 前8位:, key[:8] if key else 未找到 Key) print(Key 長(zhǎng)度:, len(key) if key else 0)如果這里查不到那后面不管你代碼寫成什么樣請(qǐng)求都會(huì)報(bào)鑒權(quán)錯(cuò)誤。第二個(gè)驗(yàn)證是網(wǎng)絡(luò)連通性直接運(yùn)行一次最簡(jiǎn)單的請(qǐng)求看能不能順利拿到返回。如果網(wǎng)絡(luò)有問題報(bào)錯(cuò)信息通常會(huì)直接給出來比如連接超時(shí)或 DNS 解析失敗。這兩步驗(yàn)證加起來不到一分鐘但能把后面四個(gè)坑里的兩個(gè)提前排掉效率非常高。3. 實(shí)操過程與核心環(huán)節(jié)實(shí)現(xiàn)3.1 從零開始的完整操作流程現(xiàn)在把完整流程走一遍從建目錄到看到第一行模型輸出整個(gè)過程大概五分鐘前提是 API Key 已經(jīng)準(zhǔn)備好且賬戶有余額。第一步建一個(gè)項(xiàng)目目錄專門放這次實(shí)踐的文件mkdir my_first_agent cd my_first_agent第二步創(chuàng)建虛擬環(huán)境并激活python -m venv venv source venv/bin/activate # Windows 下用 venv\Scripts\activate第三步安裝依賴pip install openai python-dotenv第四步創(chuàng)建.env文件寫入 API Key。注意.env文件沒有任何后綴名就是一個(gè)小寫的點(diǎn)加 env。第五步在同一目錄下創(chuàng)建main.py把前面那段 10 行代碼復(fù)制進(jìn)去。第六步運(yùn)行程序python main.py如果一切順利你會(huì)看到終端里打印出一段中文文本那是模型的自我介紹。如果報(bào)錯(cuò)了大概率就是下面要講的四個(gè)坑之一。3.2 踩坑實(shí)錄一模型名稱寫錯(cuò)認(rèn)證通過了但請(qǐng)求失敗我第一次跑通模型調(diào)用的時(shí)候以為自己已經(jīng)非常小心了結(jié)果第一個(gè)坑還是踩了——模型名稱寫錯(cuò)。當(dāng)時(shí)我把模型名寫成了gpt-4o實(shí)際上賬戶可用的模型并不是這個(gè)精確的字符串。報(bào)錯(cuò)信息也不是“檢測(cè)不到模型”而是給出了一個(gè)模型列表提示我選擇的模型不存在或沒有權(quán)限。這個(gè)問題其實(shí)非常好排查因?yàn)閳?bào)錯(cuò)信息里通常會(huì)說明。這里分享一個(gè)實(shí)用方法官方 SDK 一般都有查模型列表的方法可以精確看到你的賬戶到底能用哪些模型from openai import OpenAI from dotenv import load_dotenv import os load_dotenv() client OpenAI(api_keyos.getenv(OPENAI_API_KEY)) models client.models.list() for m in models: print(m.id)運(yùn)行之后把模型列表和自己代碼里的模型名對(duì)一下多一個(gè)字符、少一個(gè)連字符、大小寫不對(duì)全都原形畢露。這個(gè)坑算不上高深但它告訴我們一個(gè)道理不要憑記憶寫模型名一定要以官方文檔或列表接口返回為準(zhǔn)。3.3 踩坑實(shí)錄二超時(shí)設(shè)置缺失程序假裝死掉第二個(gè)坑是超時(shí)問題。我第一次寫代碼的時(shí)候沒有加timeout參數(shù)想著讓模型慢慢返回也沒關(guān)系。結(jié)果有一次趕上服務(wù)波動(dòng)請(qǐng)求發(fā)出去之后整整一分多鐘沒有任何響應(yīng)程序一直掛在那里看起來就像死掉了一樣。后來我在所有請(qǐng)求里都顯式加上超時(shí)參數(shù)并且會(huì)依據(jù)具體場(chǎng)景選擇合適的值普通聊天/簡(jiǎn)單生成建議timeout30默認(rèn)情況足夠。復(fù)雜推理/長(zhǎng)文生成可以放寬到timeout60或timeout120。對(duì)響應(yīng)時(shí)間要求高的場(chǎng)景建議timeout10超時(shí)后走降級(jí)邏輯。加超時(shí)還有一個(gè)額外好處能幫你快速定位網(wǎng)絡(luò)問題。如果請(qǐng)求總是超過 10 秒才響應(yīng)說明鏈路可能有問題而不是參數(shù)寫錯(cuò)了。如果請(qǐng)求秒回超時(shí)那大概率是網(wǎng)絡(luò)被掐斷或者域名解析異常。3.4 踩坑實(shí)錄三上下文過長(zhǎng)被拒絕請(qǐng)求還沒到模型就失敗了第三個(gè)坑跟請(qǐng)求內(nèi)容本身有關(guān)。有一次我在測(cè)試多輪對(duì)話把前面十幾輪的歷史消息原封不動(dòng)地拼在messages里發(fā)給模型結(jié)果返回了一個(gè)上下文長(zhǎng)度超限的錯(cuò)誤。大模型對(duì)輸入長(zhǎng)度有硬性上限不同模型的上限不同有的 8K token有的 128K token。超出限制后請(qǐng)求會(huì)直接被拒絕而不是截?cái)嗵幚?。解決思路有兩個(gè)一個(gè)是控制歷史消息的數(shù)量早期做 Agent 最簡(jiǎn)單的方式是只保留最近 N 輪對(duì)話另一個(gè)是用支持更長(zhǎng)上下文的模型。這里給一個(gè)實(shí)用建議在早期調(diào)通階段messages里只放當(dāng)前這一輪的用戶輸入就好等基礎(chǔ)調(diào)用沒問題了再去搞記憶和歷史消息管理。先把地基打牢再蓋樓。3.5 踩坑實(shí)錄四返回結(jié)果解析錯(cuò)誤把整個(gè)對(duì)象當(dāng)文本打印第四個(gè)坑是最“低級(jí)”但也最容易忽略的拿到響應(yīng)之后直接print(response)看結(jié)果發(fā)現(xiàn)打印出來一大長(zhǎng)串看不懂的對(duì)象結(jié)構(gòu)以為自己調(diào)用失敗了。其實(shí)響應(yīng)已經(jīng)成功返回只是沒有取對(duì)字段。正確的做法是取response.choices[0].message.content這才是模型輸出的純文本內(nèi)容。如果你把整個(gè) response 對(duì)象打印出來看到的是一大堆元數(shù)據(jù)、usage 信息、嵌套結(jié)構(gòu)看起來非?;H说⒉皇悄P突卮鸨旧怼N疫€見過另一種情況有人用response[choices]的方式取值結(jié)果報(bào)類型錯(cuò)誤。因?yàn)?SDK 返回的是對(duì)象而不是字典需要用點(diǎn)號(hào)屬性訪問而不是方括號(hào)鍵名訪問。如果你非要用字典的方式可以調(diào).model_dump()把對(duì)象轉(zhuǎn)成字典再取但沒必要點(diǎn)號(hào)訪問更直接。3.6 關(guān)于四個(gè)坑的最省心排查序列把這四個(gè)坑串起來給你一個(gè)最省心的排查順序以后跑模型調(diào)用報(bào)錯(cuò)按這個(gè)順序查基本不會(huì)走彎路錯(cuò)誤現(xiàn)象優(yōu)先排查驗(yàn)證方法401 鑒權(quán)失敗API Key 是否正確、是否被正確加載打印 Key 前幾位和長(zhǎng)度404 或模型不存在模型名是否正確調(diào)用模型列表接口核對(duì)超時(shí)/連接錯(cuò)誤網(wǎng)絡(luò)狀態(tài)、超時(shí)參數(shù)是否設(shè)置ping 供應(yīng)商域名或換網(wǎng)絡(luò)測(cè)試上下文長(zhǎng)度錯(cuò)誤請(qǐng)求體是否超長(zhǎng)統(tǒng)計(jì) token 總量或減少歷史消息拿到對(duì)象不是文本返回字段取值路徑是否正確用response.choices[0].message.content做最小提取這個(gè)表格是我自己實(shí)踐中濃縮出來的對(duì)照著排查大多數(shù)問題五分鐘之內(nèi)能定位。4. 常見問題與排查技巧實(shí)錄4.1 不同模型調(diào)用的兼容性怎么處理整個(gè)大模型生態(tài)目前還處于快速發(fā)展期幾乎每個(gè)月都有新模型冒出來。不同廠商提供的 SDK 風(fēng)格不完全一樣但主流的 Chat Completions 格式兼容性做得不錯(cuò)。如果你今天用 A 廠商 SDK 跑通了明天想換 B 廠商代碼改動(dòng)量通常很小主要改base_url和api_key方法名和參數(shù)結(jié)構(gòu)大同小異。比如很多國(guó)內(nèi)模型的 OpenAI 兼容模式是這樣配置的from openai import OpenAI client OpenAI( api_key你的密鑰, base_urlhttps://api.某廠商.com/v1 )這行配置值得專門記住因?yàn)椴簧倌P蛷S商提供了兼容 Chat Completions 的接口你只要把base_url指過去代碼就能復(fù)用。這意味著你之前學(xué)到的調(diào)用方式可以平移到很多不同的模型上不用重學(xué)一套 SDK。4.2 多輪對(duì)話的正確實(shí)現(xiàn)姿勢(shì)從一次調(diào)用走向 Agent最先遇到的擴(kuò)展需求一定是多輪對(duì)話。很多人會(huì)把多輪對(duì)話理解成“多次調(diào)用”其實(shí)不準(zhǔn)確。模型本身是無狀態(tài)的它不會(huì)記得之前的請(qǐng)求。你必須把完整的對(duì)話歷史在每次請(qǐng)求時(shí)都交給它它才能基于上下文回答。正確的多輪對(duì)話實(shí)現(xiàn)方式是維護(hù)一個(gè)消息數(shù)組messages [ {role: system, content: 你是一個(gè)樂于助人的助手}, {role: user, content: 你好}, {role: assistant, content: 你好有什么可以幫你的}, {role: user, content: 我叫小明}, ]每次用戶說一句話就往這個(gè)數(shù)組里追加一條user消息然后把整個(gè)數(shù)組發(fā)給模型。模型返回的結(jié)果再追加一條assistant消息作為下一輪請(qǐng)求的一部分。這個(gè)數(shù)組就是 Agent 的“記憶”雛形。你不需要任何高級(jí)框架先把消息數(shù)組維護(hù)好就已經(jīng)實(shí)現(xiàn)了 Agent 的記憶基礎(chǔ)能力。4.3 流式輸出為什么值得盡早掌握第一次跑通模型調(diào)用時(shí)用的是非流式請(qǐng)求就是一次性把完整結(jié)果打印出來。這在體驗(yàn)上有一個(gè)明顯問題如果模型生成內(nèi)容較長(zhǎng)你要等好幾秒甚至十幾秒才能看到第一個(gè)字。流式輸出可以解決這個(gè)問題。它讓模型生成一個(gè) token 就推送一個(gè) token用戶側(cè)的效果就是“打字機(jī)式”地看到內(nèi)容逐漸出現(xiàn)體驗(yàn)好很多而且首字延遲大幅降低。在 Chat Completions 格式下流式輸出的代碼改動(dòng)量非常小只要加一個(gè)參數(shù)并把返回遍歷方式改一下stream client.chat.completions.create( modelgpt-4o-mini, messages[{role: user, content: 寫一篇短文}], streamTrue ) for chunk in stream: if chunk.choices[0].delta.content: print(chunk.choices[0].delta.content, end)對(duì)于做 Agent 的人來說流式輸出是剛需因?yàn)?Agent 內(nèi)部可能有多步執(zhí)行過程如果每一步都非流式整個(gè)交互過程會(huì)顯得非常笨重。建議在基礎(chǔ)調(diào)用跑通之后第一時(shí)間研究流式輸出。4.4 請(qǐng)求異常統(tǒng)一包裝的思路代碼跑通之后接下來要面對(duì)的是“健壯性”問題。大模型調(diào)用不是一個(gè)百分之百穩(wěn)定的操作受網(wǎng)絡(luò)、服務(wù)負(fù)載、參數(shù)合法性影響隨時(shí)可能拋異常。好的做法是把調(diào)用封裝成一個(gè)統(tǒng)一的函數(shù)統(tǒng)一處理超時(shí)、重試和異常def call_model(client, messages, retry3): for i in range(retry): try: response client.chat.completions.create( modelgpt-4o-mini, messagesmessages, timeout30 ) return response.choices[0].message.content except Exception as e: print(f第{i1}次調(diào)用失敗: {e}) if i retry - 1: raise return None這里注意幾點(diǎn)重試之間最好加一點(diǎn)退避延遲直接加time.sleep(1)就夠用只有網(wǎng)絡(luò)類異常才值得重試參數(shù)類錯(cuò)誤重試多少次都一樣失敗所以實(shí)際項(xiàng)目中通常還會(huì)細(xì)分異常類型再?zèng)Q定是否重試。這一層封裝是 Agent 項(xiàng)目的第一個(gè)基礎(chǔ)設(shè)施。4.5 成本控制從調(diào)用量到 token 統(tǒng)計(jì)跑通模型調(diào)用后很快會(huì)關(guān)心成本問題。每次請(qǐng)求消耗多少 token通過返回結(jié)構(gòu)里的usage字段就能拿到。但做 Agent 時(shí)成本問題更復(fù)雜因?yàn)橐粋€(gè) Agent 任務(wù)可能包含多個(gè)模型調(diào)用比如規(guī)劃、推理、工具結(jié)果分析各調(diào)一次。粗淺的統(tǒng)計(jì)方式是每次調(diào)用都記錄 usage最后加總精確的統(tǒng)計(jì)方式是按任務(wù)維度打標(biāo)簽在日志里記錄每次調(diào)用的來源。我個(gè)人的習(xí)慣是初期把每次調(diào)用的total_tokens打出來做到心里有數(shù)。等你發(fā)現(xiàn)一個(gè)大任務(wù)消耗的 token 超過預(yù)期時(shí)再回頭優(yōu)化消息歷史數(shù)量、限制max_tokens、控制工具返回結(jié)果的大小這些都是成本控制的有效手段。5. 從 10 行代碼到 Agent 的擴(kuò)展路線5.1 給模型加上“工具調(diào)用”能力大模型調(diào)用跑通之后Agent 的下一步核心能力是工具調(diào)用也就是讓模型在回答過程中決定“要不要調(diào)用某個(gè)函數(shù)”。模型本身不會(huì)去執(zhí)行代碼但會(huì)在返回結(jié)果中聲明它想調(diào)用哪個(gè)工具、傳入什么參數(shù)你拿到這些信息后在本地執(zhí)行再把執(zhí)行結(jié)果回傳給模型讓它基于結(jié)果繼續(xù)回答。在官方 SDK 里工具調(diào)用的寫法和普通調(diào)用非常接近只要在請(qǐng)求參數(shù)里聲明工具即可。不過這部分代碼量會(huì)比 10 行多不少我建議的基礎(chǔ)調(diào)用流程是先跑通純文本問答再跑通多輪對(duì)話最后才加工具調(diào)用。每一步都在前一步的基礎(chǔ)上疊加問題出現(xiàn)時(shí)容易定位。5.2 用什么標(biāo)準(zhǔn)判斷“可以開始寫 Agent 了”一個(gè)很實(shí)際的問題到什么時(shí)候才算具備了開始寫 Agent 的能力我的判斷標(biāo)準(zhǔn)很簡(jiǎn)單就三條能用一個(gè)函數(shù)兼容不同模型切換base_url和api_key就能用。能正確處理多輪消息數(shù)組包括追加歷史消息和控制長(zhǎng)度。能拿到完整的返回結(jié)構(gòu)并解析出所有關(guān)鍵字段包括正文、結(jié)束原因、token 用量。這三個(gè)能力都具備了那你已經(jīng)能自己手寫一個(gè)簡(jiǎn)單的單輪 Agent再加上循環(huán)判斷邏輯就變成一個(gè)多步推理 Agent。別小看這幾步能力的積累它們比任何框架文檔都重要。5.3 回歸現(xiàn)實(shí)手?jǐn)] Agent 的價(jià)值重估寫到這里想稍微展開說一句關(guān)于“從零手?jǐn)]”這件事本身。現(xiàn)在 Agent 框架非常多成熟的開源項(xiàng)目各種低代碼平臺(tái)都在解決調(diào)度和編排的問題。那為什么還要手?jǐn)]一次底層調(diào)用我的體會(huì)是框架幫你省掉的是重復(fù)勞動(dòng)但幫不了你理解問題本質(zhì)。當(dāng)你親手寫過一遍請(qǐng)求、調(diào)試過返回結(jié)構(gòu)、踩過超時(shí)和鑒權(quán)的坑之后再去用任何框架遇到報(bào)錯(cuò)你能大致猜到問題出在哪個(gè)環(huán)節(jié)而不是兩眼一抹黑到處問人。這份對(duì)底層的體感是任何框架都代替不了的。最后說兩句實(shí)在的整個(gè)“10 行代碼跑通模型調(diào)用”的過程看起來簡(jiǎn)單但每一個(gè)步驟背后都有值得深挖的細(xì)節(jié)。我個(gè)人在實(shí)際操作中最深的一個(gè)體會(huì)是第一次跑通時(shí)不要追求代碼量少而要追求把每一步都走扎實(shí)——密鑰怎么管理、網(wǎng)絡(luò)怎么排障、返回怎么解析、異常怎么兜底這四件事做完整后面所有 Agent 功能的擴(kuò)展都會(huì)非常順暢。還有一個(gè)每次都會(huì)分享的小技巧把你項(xiàng)目里的.env文件第一時(shí)間加入.gitignore永遠(yuǎn)不要讓密鑰有機(jī)會(huì)進(jìn)到代碼倉(cāng)庫(kù)里。這個(gè)習(xí)慣救了我好幾次。最后再補(bǔ)充一個(gè)善意的提醒大模型調(diào)用看似簡(jiǎn)單但它連接的是整個(gè) Agent 體系的地基。這篇內(nèi)容里每個(gè)環(huán)節(jié)都有可延展的空間——比如對(duì)話記憶怎么管理、工具結(jié)果怎么截?cái)?、多步調(diào)用怎么控制總成本。后續(xù)我會(huì)繼續(xù)更新“從零手?jǐn)] Agent”系列把每個(gè)環(huán)節(jié)單獨(dú)拆出來分享。第一次跑通的那份興奮感值得你親手體驗(yàn)一次。