:Ollama+Python調(diào)度+工具調(diào)用完整指南)
最近不少朋友問我怎么在本地搭一個真正能干活的 AI Agent而不是只會聊天的對話框。我自己摸索了一段時間最后選定的方案是Ollama 跑本地模型再寫一套輕量的調(diào)度邏輯把模型變成一個能查資料、能調(diào)工具、能按流程執(zhí)行任務(wù)的智能代理。整套下來不花一分錢 API 費用數(shù)據(jù)全在自己機器上隱私和可控性都拿捏得很穩(wěn)。這篇文章就把我完整踩過的坑、選型的邏輯、以及可以直接照抄的搭建流程全部寫出來適合有一定編程基礎(chǔ)、想擺脫云 API 依賴的開發(fā)者參考。1. 搭一個本地 AI Agent 前先想清楚三件事1.1 Agent 到底是什么和聊天機器人有什么區(qū)別先說個基礎(chǔ)認知問題。很多人把能連續(xù)對話誤當(dāng)成 Agent其實完全不是一回事。普通的聊天機器人是你說一句我回一句它沒有目標也不會主動調(diào)用外部工具。而 AI Agent 的核心是給定一個目標它能自己規(guī)劃步驟、調(diào)用工具、分析結(jié)果、調(diào)整策略直到把任務(wù)完成。舉個生活化的例子。你讓聊天機器人幫我查一下明天的天氣并規(guī)劃出行它只會回復(fù)一段建議。但一個合格的 Agent 會這樣做先調(diào)用天氣 API 獲取數(shù)據(jù)判斷是否需要帶傘再調(diào)用地圖 API 規(guī)劃路線最后把結(jié)果匯總成一段可讀的答復(fù)。每一步都是模型在思考但每一步的執(zhí)行都依賴外部工具。所以搭建 Agent 的關(guān)鍵不只是選一個大模型而是要把模型推理和工具執(zhí)行這兩條線拼接起來。Ollama 解決的是推理這一半另一半需要我們自己用代碼搭一個調(diào)度器這也是這篇文章里最核心的內(nèi)容。1.2 為什么選 Ollama 而不是云 API你可以用任何模型服務(wù)來搭 Agent但我最終選擇 Ollama原因有三個。第一是成本。我做的項目里有大量測試和反復(fù)調(diào)優(yōu)的場景每天可能要發(fā)幾百次請求。如果用云 API這些請求都是真金白銀。Ollama 跑在自己的 GPU 或 CPU 上沒有調(diào)用次數(shù)限制隨便刷。對于個人開發(fā)者、學(xué)習(xí)項目、原型驗證來說免費這個優(yōu)勢是壓倒性的。第二是隱私。很多企業(yè)場景或者個人敏感數(shù)據(jù)根本不適合發(fā)到云端。Ollama 的所有推理都在本地完成模型文件、中間結(jié)果、日志全部留在自己手里。這一點在做私有化知識庫、內(nèi)部文檔問答、代碼輔助工具時特別重要。第三是可控性。云 API 的版本更新、模型下架、限流策略都不由你控制。Ollama 裝好之后模型文件就在你的磁盤里你可以隨意切換版本、調(diào)整參數(shù)、做微調(diào)沒有任何外部約束。當(dāng)然Ollama 也有代價。你沒有云端那么強的算力所以跑不了超大參數(shù)模型模型效果也不一定比頂級商業(yè) API 好。但對我這種方式是先用起來、跑通流程的開發(fā)階段來說Ollama 是性價比最高的起點。1.3 整體方案本地模型 調(diào)度腳本 工具接口我先說一下最終架構(gòu)讓你心里有個地圖。用戶輸入 - 主調(diào)度循環(huán) - Ollama 本地模型 - 輸出意圖判斷 ↓ 需要工具 解析出工具名和參數(shù) - 執(zhí)行函數(shù) - 返回結(jié)果給模型 - 繼續(xù)推理 ↓ 不需要工具 直接輸出最終回答整個系統(tǒng)分成三層模型層Ollama 加載本地開源模型負責(zé)理解意圖、生成文本、決定是否調(diào)用工具。調(diào)度層一段 Python 腳本負責(zé)循環(huán)調(diào)用模型、解析輸出、維護多輪對話記憶、判斷任務(wù)是否結(jié)束。工具層一組普通的 Python 函數(shù)比如查詢天氣、讀寫文件、計算表達式、搜索本地文檔。每個函數(shù)就對應(yīng) Agent 的一只手。這個架構(gòu)看起來簡單但很實用。好處是每一層都能獨立替換今天用 Ollama 跑一個 7B 模型明天換更大的模型調(diào)度層完全不用改工具層加一個函數(shù)Agent 就多一項能力。下面我按這個框架逐步拆解搭建過程。2. 環(huán)境搭建裝好 Ollama 并選對模型2.1 安裝 Ollama3 分鐘跑起第一個模型Ollama 的安裝是我見過的最省心的 AI 工具之一。在 macOS 和 Windows 上直接去官網(wǎng)下載安裝包雙擊安裝即可。在 Linux 上執(zhí)行一句腳本就能裝好curl -fsSL https://ollama.com/install.sh | sh裝好之后驗證是否成功ollama --version然后拉取一個模型試試。我用的主力模型是 Qwen2.5 7B Instruct這個模型中文效果好、工具調(diào)用能力也不錯體積適中適合大多數(shù)人的硬件。拉取命令ollama pull qwen2.5:7b第一次拉取會下載幾個 GB 的文件等它跑完然后啟動一個簡單對話ollama run qwen2.5:7b 你好做個自我介紹如果能看到正?;貜?fù)就說明 Ollama 已經(jīng)跑通了。這里有個值得多說一句的點Ollama 安裝完成后會默認在后臺啟動一個本地服務(wù)監(jiān)聽11434端口。也就是說你用命令行能對話其實底層就是通過 HTTP API 在調(diào)用后面我們用 Python 寫 Agent 調(diào)度器也是走這個端口。2.2 模型量化與顯存需求怎么算很多新手卡在這一步模型下載好了但跑起來特別慢或者直接報內(nèi)存不足。這涉及模型量化和硬件配置的關(guān)系。模型文件有很多種精度格式最常見的是 FP16 和量化版。一個 7B 參數(shù)的模型FP16 格式大約占用 14GB 顯存很多人的顯卡根本裝不下。量化指的是把模型里的浮點數(shù)精度降低比如從 16 位降到 4 位模型體積直接縮到四分之一效果損失卻控制在可接受范圍內(nèi)。Ollama 上默認拉取的模型都自帶量化版本你不需要手動處理。以 Qwen2.5 7B 為例量化格式模型文件大小運行所需內(nèi)存估算推薦硬件q4_K_M約 4.7GB6-8GB8GB 顯存或 16GB 內(nèi)存q8_0約 8.2GB10-12GB12GB 顯存或 32GB 內(nèi)存FP16約 15GB16GB24GB 顯存或 64GB 內(nèi)存我自己的機器是 8GB 顯存的顯卡跑 q4_K_M 版本很流暢生成速度大約每秒 40 個 token。如果你沒有獨立顯卡只有 CPU 和 16GB 內(nèi)存也能跑就是速度慢一些大概每秒幾個 token做實驗夠用但聊天的體驗會打折扣。注意如果你的機器內(nèi)存或顯存小于模型所需Ollama 會優(yōu)先保證模型加載然后擠壓其他程序的內(nèi)存空間結(jié)果就是電腦卡死。所以選模型之前先看一眼自己的硬件再決定用哪個量化版本。2.3 調(diào)好關(guān)鍵運行參數(shù)Ollama 模型的運行參數(shù)可以通過命令行設(shè)置也可以直接在啟動時寫好。這些參數(shù)對 Agent 的穩(wěn)定性影響非常大我逐個說。溫度temperature控制生成隨機性。0 表示每次輸出最確定的答案1 表示最大隨機。做 Agent 任務(wù)我強烈建議把溫度調(diào)到 0 到 0.3 之間。因為 Agent 需要穩(wěn)定地輸出工具調(diào)用指令溫度太高它就會開始自由發(fā)揮格式一亂調(diào)度器就解析不了。上下文長度num_ctx這個決定模型能記住多少前面的對話。默認值通常是 2048 或 4096。做 Agent 任務(wù)時因為要包含工具返回的長文本、多輪對話歷史上下文很容易被打滿。建議調(diào)大比如 8192 或 16384但注意這會增加顯存消耗。重復(fù)懲罰repeat_penalty防止模型重復(fù)同樣的句子。默認值 1.1 就行不用動。top_p核采樣參數(shù)默認 0.9 附近一般不需要調(diào)。如果發(fā)現(xiàn)輸出質(zhì)量不穩(wěn)定可以降到 0.8。在實際項目中我通常把這些參數(shù)寫進啟動腳本不手動改全局配置。比如ollama run qwen2.5:7b --temperature 0.1 --num_ctx 8192這里要注意--num_ctx如果設(shè)得比模型默認值大會顯著增加顯存占用。比如 7B 模型 q4 量化本身只需 5GB但把上下文提到 16K 之后可能需要再多 3-4GB。根據(jù)你的顯存情況量力而行。3. 手把手讓 Agent 學(xué)會干活3.1 用 API 跟本地模型對話命令行只是用來測試的要搭建 Agent真正的核心是調(diào)用 Ollama 的 HTTP API。它提供了一個很簡潔的接口直接發(fā) POST 請求就行。先看一個簡單的對話請求curl http://localhost:11434/api/chat -d { model: qwen2.5:7b, messages: [ {role: user, content: 1 1 等于幾} ], stream: false }響應(yīng)的 JSON 里有個message.content字段就是模型的回答。用 Python 調(diào)用更直觀import requests def chat_with_model(messages, temperature0.2): response requests.post( http://localhost:11434/api/chat, json{ model: qwen2.5:7b, messages: messages, stream: False, options: { temperature: temperature } } ) return response.json()[message][content]注意stream參數(shù)。默認情況下模型是逐字輸出流式返回的對 Agent 這種機器對機器的場景來說流式反而增加解析復(fù)雜度所以直接設(shè)成false一次性拿完整結(jié)果簡單省事。3.2 讓模型輸出工具調(diào)用指令A(yù)gent 的關(guān)鍵一步是讓模型決定要不要調(diào)工具以及調(diào)哪個工具、傳什么參數(shù)。這本質(zhì)上是一個提示詞工程問題。我的做法是在系統(tǒng)提示詞里給模型一個明確的行為規(guī)則。下面是我真實用過的一套提示詞模板你是任務(wù)規(guī)劃助手。你有一個可以使用的工具列表 - weather(city: string): 查詢城市天氣 - calculator(expression: string): 計算數(shù)學(xué)表達式 - current_time(): 獲取當(dāng)前時間 規(guī)則 1. 如果用戶問題需要工具才能回答必須輸出嚴格的 JSON格式為 {tool: 工具名, params: {參數(shù)名: 參數(shù)值}, thought: 簡短推理說明} 2. 如果不需要工具直接輸出純文本回答。 3. 判斷要準確不能把簡單問題復(fù)雜化。然后把這段提示詞和用戶消息一起發(fā)給模型。模型在推理時要么輸出普通文本要么輸出 JSON 格式的工具調(diào)用指令。調(diào)度器拿到輸出后先用正則表達式提取 JSON再根據(jù)tool字段匹配對應(yīng)的 Python 函數(shù)完成調(diào)用。這里有一個很重要的經(jīng)驗?zāi)P洼敵?JSON 時經(jīng)常帶一些額外的文字比如好的我來查一下天氣JSON 如下{...}。如果你是直接json.loads整個字符串一定會報錯。所以必須用正則把大括號里的內(nèi)容提取出來再去解析。import re import json def extract_json(raw_text): pattern r\{[^{}]*\} match re.search(pattern, raw_text, re.DOTALL) if match: return json.loads(match.group(0)) return None注冊工具函數(shù)的時候用字典映射def weather(city): # 這里可以接真實天氣 API演示時返回模擬數(shù)據(jù) return f{city}今天晴氣溫 22-28 度 def calculator(expression): return str(eval(expression)) def current_time(): from datetime import datetime return datetime.now().strftime(%Y-%m-%d %H:%M) TOOLS { weather: weather, calculator: calculator, current_time: current_time, }新增工具的時候只需要寫一個普通 Python 函數(shù)然后在系統(tǒng)提示詞的工具列表里加上描述再把這個函數(shù)注冊進TOOLS字典Agent 就能用了。3.3 搭建工具調(diào)度主循環(huán)核心調(diào)度邏輯其實就是一個 while 循環(huán)把消息發(fā)給模型解析輸出如果輸出是工具調(diào)用指令就執(zhí)行工具把結(jié)果加進消息歷史再發(fā)給模型如果輸出是普通回答就結(jié)束并把回答展示給用戶。直接看我寫的一個完整骨架def run_agent(user_input): messages [ {role: system, content: SYSTEM_PROMPT}, {role: user, content: user_input}, ] max_iterations 5 # 防止死循環(huán) for _ in range(max_iterations): response_text chat_with_model(messages) tool_call extract_json(response_text) if tool_call and tool in tool_call: tool_name tool_call[tool] params tool_call.get(params, {}) if tool_name in TOOLS: # 執(zhí)行工具 result TOOLS[tool_name](**params) # 把工具結(jié)果追加到對話歷史 messages.append({role: assistant, content: response_text}) messages.append({role: tool, content: str(result)}) continue else: return f錯誤未知工具 {tool_name} else: # 沒有工具調(diào)用這就是最終回答 return response_text return 達到最大循環(huán)次數(shù)任務(wù)未完成這段代碼有幾個值得注意的點。第一為什么工具結(jié)果要作為消息的一部分發(fā)回去而不是直接在系統(tǒng)外部拼接因為模型需要看到工具返回的數(shù)據(jù)才能決定下一步是繼續(xù)調(diào)用工具還是生成最終回答。這本質(zhì)上是一個多輪推理的過程。如果你把工具結(jié)果存在變量里下一輪請求時模型根本不知道你查到了什么。第二max_iterations上限很重要。新手經(jīng)常踩這個坑模型在循環(huán)里反復(fù)調(diào)用同一個工具或者調(diào)用一個不存在工具導(dǎo)致無限循環(huán)程序卡死。設(shè)置一個上限最好打印日志這樣你能看到模型每一步在想什么、要調(diào)什么方便調(diào)試。第三消息歷史不能無限增長。每次工具返回結(jié)果都會追加兩條消息時間一長上下文會被撐爆。所以在實戰(zhàn)版本里我會加一個裁剪邏輯只保留最近 N 輪的消息丟棄更早的歷史。3.4 用 Open WebUI 給 Agent 一個可視界面調(diào)度腳本寫完之后你其實已經(jīng)擁有了一個能跑的 Agent 核心。但純命令行交互不太友好我建議加一層可視界面這里推薦開源項目 Open WebUI。Open WebUI 是一個很成熟的本地模型聊天界面支持與 Ollama 對接還能額外掛載知識庫、自定義工具。安裝最簡單的方式是用 Dockerdocker run -d \ -p 3000:8080 \ -v open-webui:/app/backend/data \ --name open-webui \ --restart always \ ghcr.io/open-webui/open-webui:main啟動后瀏覽器訪問http://localhost:3000注冊一個本地賬號然后在設(shè)置里把 Ollama 地址填成http://host.docker.internal:11434就能在網(wǎng)頁里和模型聊天了。不過要提醒的是Open WebUI 本身默認走的是聊天邏輯不是我們上面寫的調(diào)度邏輯。如果你想在網(wǎng)頁上體驗完整的工具調(diào)用 Agent需要再花點功夫把自定義工具注冊進 Open WebUI或者直接把調(diào)度腳本封裝成一個輕量 API再用一個簡單前端頁面去調(diào)用。我個人的建議是先靠腳本驗證 Agent 邏輯確認穩(wěn)定后再去折騰界面不要一開始就陷入前端的泥潭。4. 優(yōu)化、擴展與安全細節(jié)4.1 提示詞怎樣寫Agent 才穩(wěn)定提示詞對 Agent 的穩(wěn)定性影響怎么說都不為過。同樣的模型提示詞寫得模糊它就會頻繁誤判、亂調(diào)工具寫清楚了它能連續(xù)處理非常復(fù)雜的任務(wù)。我總結(jié)幾個實戰(zhàn)原則。第一工具描述必須具體到輸入?yún)?shù)是什么、返回值是什么、什么場景下使用。比如天氣工具不要只寫查詢天氣要寫輸入城市名返回該城市當(dāng)日天氣狀況適合用戶詢問天氣時使用。模型是靠描述來匹配意圖的描述越具體準確率越高。第二必須在提示詞里說清楚什么時候不要用工具。如果不加這一條模型可能看到任何問題都先輸出工具指令。加上如果用戶只是閑聊、問看法、做總結(jié)請不要調(diào)用工具之后誤調(diào)用率會大幅下降。第三給模型一些示例。如果某個工具容易誤匹配可以在提示詞里加一個示例比如用戶問明天需要帶傘嗎你應(yīng)該調(diào)用 weather 工具查詢城市天氣再根據(jù)結(jié)果回答。模型對示例的模仿能力非常強給一個例子勝過一百句規(guī)則。注意每次修改提示詞后建議跑一遍同一批測試用例對比輸出變化。我自己的經(jīng)驗是做一個簡單的回歸測試腳本把 10 個典型問題跑一遍檢查工具調(diào)用是否正確避免改好一處、弄壞三處。4.2 跑得更快顯存、上下文和并發(fā)調(diào)優(yōu)本地模型最難的就是性能。我把性能問題分為三個維度分別說。顯存層面最有效的做法是先把顯存占用降下來。優(yōu)先選擇量化程度高的模型版本比如 q4_K_M。如果還嫌不夠換一個更小的模型比如把 7B 換成 3B 甚至 1.8B。模型小了速度會快但推理質(zhì)量也會下降需要自己權(quán)衡。上下文層面上下文長度直接決定模型能吃多少內(nèi)容。很多 Agent 任務(wù)其實不需要非常長的上下文尤其是工具結(jié)果要精簡。我在設(shè)計工具返回值時會刻意讓工具返回簡短結(jié)果而不是一股腦輸出一大段。比如天氣工具返回晴22-28 度而不是返回一整篇天氣報告。這不僅省上下文還能減少模型的理解負擔(dān)。并發(fā)層面Ollama 默認是串行處理請求的一個模型同時只能服務(wù)一個請求。如果有多個人要同時用最簡單的方式是多加載幾個模型實例但顯存成本翻倍。實戰(zhàn)里我更推薦加一層請求隊列讓 Agent 系統(tǒng)排隊處理任務(wù)而不是同時強推多個請求導(dǎo)致內(nèi)存爆炸。另外可以開啟OLLAMA_NUM_PARALLEL環(huán)境變量允許一個模型并發(fā)處理多個請求。這個配置會顯著提高吞吐量但會同步增加顯存和內(nèi)存消耗適合顯存充足的情況。4.3 接入外部工具與私有數(shù)據(jù)Agent 的價值上限取決于你給它接了多少外掛。我建議優(yōu)先接這三類。第一類是 API 型工具。比如查天氣、查物流、翻譯、搜索網(wǎng)頁。實現(xiàn)方式就是寫一個函數(shù)內(nèi)部用requests請求外部接口返回 JSON 結(jié)果。注意要設(shè)置請求超時避免模型等一個遲遲不響應(yīng)的接口導(dǎo)致整個調(diào)度卡住。第二類是本地文件工具。比如讓 Agent 讀取、搜索、總結(jié)某個目錄下的文檔。做法是封裝一個read_file(path)和search_files(keyword)函數(shù)讓模型可以自己翻文件、提取信息。我在做一個內(nèi)部知識庫助手時就是靠這種工具讓 Agent 直接查詢本地文檔效果比預(yù)訓(xùn)練知識更準。第三類是代碼執(zhí)行工具。讓 Agent 寫 Python 代碼、執(zhí)行代碼、返回運行結(jié)果。這個能力非常強大但風(fēng)險也最高因為模型生成的代碼不一定安全可能執(zhí)行破壞性命令。我的建議是只在沙箱環(huán)境里開放這個工具比如 Docker 容器內(nèi)別在宿主機上裸跑。私有數(shù)據(jù)這塊除了上面的文件工具還可以用向量數(shù)據(jù)庫做語義檢索。把文檔切成小塊用本地 embedding 模型轉(zhuǎn)成向量存進向量庫然后給 Agent 一個search_vectors(query)工具它就能基于本地資料回答問題。整個鏈路全部在本地數(shù)據(jù)不出機器。用戶問我們項目的部署文檔里數(shù)據(jù)庫連接配置怎么寫 Agent 判斷需要查資料 - 調(diào)用 search_vectors(數(shù)據(jù)庫連接配置) 工具返回相關(guān)文檔片段 - Agent 總結(jié)片段 - 輸出最終回答這個架構(gòu)擴展性很強后續(xù)想把 Agent 從助手升級成自動執(zhí)行任務(wù)的角色只需要繼續(xù)加工具比如加定時任務(wù)工具、郵件發(fā)送工具、數(shù)據(jù)報表工具它就能完成更加復(fù)雜的組合操作。5. 常見問題速查搭建中一個坑一個坑踩過來這套系統(tǒng)我前前后后改了三版踩過不少坑。把最典型的幾個問題整理成一個速查表你大概率也會遇到。癥狀可能原因解決辦法模型啟動后一直顯示loading模型文件過大或顯存不足Ollama 在反復(fù)交換內(nèi)存換更小量化模型關(guān)閉其他占用顯存的程序加--num_ctx縮小上下文Agent 亂調(diào)用工具明明問題很簡單卻查了天氣提示詞里沒有不需要工具時直接回答的規(guī)則在系統(tǒng)提示詞中補充否定規(guī)則并加示例模型輸出的 JSON 解析失敗模型在 JSON 前后加了自然語言描述用正則提取大括號內(nèi)容再解析 JSON不要直接json.loads對話輪數(shù)多了之后模型開始失憶上下文長度被打滿最早的歷史被丟棄加大num_ctx或精簡工具返回內(nèi)容限制消息歷史條數(shù)請求報connection refusedOllama 服務(wù)沒啟動或者端口被占用執(zhí)行ollama serve啟動服務(wù)查看 11434 端口占用情況第一次調(diào)用模型特別慢模型正在加載進內(nèi)存Ollama 有冷啟動延遲等待幾秒或者在服務(wù)啟動前用預(yù)熱腳本發(fā)一個空請求提前加載模型工具函數(shù)報錯說參數(shù)不匹配模型傳了錯誤的參數(shù)名或參數(shù)個數(shù)給工具函數(shù)自定義一個 dict 描述參數(shù)格式并在提示詞里寫清楚5.1 Ollama 服務(wù)起不來怎么辦這個坑我踩得最狠。有一次我把模型參數(shù)調(diào)大之后運行ollama run直接報錯服務(wù)一直起不來查了半天發(fā)現(xiàn)是顯存不足導(dǎo)致 Ollama 進程崩潰。解決辦法是檢查一下nvidia-smi看顯存占用再確認模型文件的量化格式和顯存是否匹配。如果確認是顯存問題最穩(wěn)妥的方法是換小模型。當(dāng)時我把 7B 模型換成 3B一切恢復(fù)正常。又或者在啟動前釋放一下顯存關(guān)掉其他占用顯存的進程。另一個常見原因是端口被其他程序占用。Ollama 默認監(jiān)聽11434如果你機器上恰好有其他服務(wù)占了同一個端口服務(wù)就會啟動失敗。排查方法lsof -i :11434如果有結(jié)果說明端口被占用要么停掉那個程序要么修改 Ollama 的端口配置。5.2 模型一直處于上下文加載狀態(tài)對話半天沒響應(yīng)很多人遇到過第一次發(fā)消息后模型要卡很久才有反應(yīng)。這是因為 Ollama 第一次調(diào)用時需要把整個模型文件從磁盤加載到內(nèi)存這個過程取決于模型大小和磁盤速度。7B 模型大概需要幾十秒。解決辦法有兩個。第一設(shè)置環(huán)境變量OLLAMA_KEEP_ALIVE1h表示模型加載后在一小時內(nèi)保持駐留內(nèi)存避免每輪對話都重新加載。這個配置非常有效我設(shè)完之后第二輪對話的響應(yīng)時間從幾十秒降到了即時。第二做一個預(yù)熱調(diào)用。在 Agent 系統(tǒng)啟動的時候主動給模型發(fā)一個簡單請求讓它提前加載完成。這樣用戶真正使用時不會感受到冷啟動的延遲。5.3 工具調(diào)用輸出格式不穩(wěn)定同一個問題這次能用下次不能用這種情況通常不是模型本身的錯而是提示詞寫得不夠嚴格。模型在輸出 JSON 時有時候會用單引號有時候會多一個逗號有時候用中文冒號。這些都會導(dǎo)致解析失敗。除了用正則提取之外我還有一個糾錯策略如果 JSON 解析失敗就把錯誤信息和原始輸出反饋給模型讓模型重新輸出一遍。相當(dāng)于給模型一次自我修正的機會。代碼如下if tool_call is None: messages.append({role: user, content: 你的輸出包含無效的 JSON請重新輸出只輸出 JSON不要有其他文字。}) continue實測下來這個糾錯策略能讓成功率從 80% 提升到 95% 以上。偶爾出錯沒關(guān)系關(guān)鍵是系統(tǒng)能自我修正而不是一錯到底。5.4 API 請求耗時太長有沒有辦法優(yōu)化如果你的工具環(huán)節(jié)涉及外部網(wǎng)絡(luò)請求比如天氣 API、搜索 API這些請求的耗時可能比模型推理還長。我建議給每個外部工具設(shè)置 10 秒超時并且在工具層做結(jié)果緩存。同一個城市查天氣短時間內(nèi)不會有變化可以直接返回上次的結(jié)果大幅減少重復(fù)請求。另外Ollama 的num_predict參數(shù)也可以限制模型單次生成的最大 token 數(shù)。Agent 場景下模型很多輸出都是簡短的 JSON 指令把這個值設(shè)成 512 就能滿足需求不用讓它生成到默認的 2048。限制 token 數(shù)可以明顯提升響應(yīng)速度。options: { temperature: 0.2, num_predict: 512 }最后還有一個調(diào)優(yōu)思路如果任務(wù)簡單用一個小模型做判斷用一個大模型做總結(jié)。比如意圖識別階段直接用 3B 模型判斷是否要調(diào)工具速度快了好幾倍等真正需要生成長回答的時候再切換到 7B 模型。這個雙模型架構(gòu)雖然復(fù)雜一點但效果和成本的平衡非常好。我個人在這套系統(tǒng)上花的時間大概有一半是在調(diào)提示詞和做異常兜底而不是在寫核心調(diào)度代碼。這也印證了一個觀點Agent 能不能穩(wěn)定干活差的不是模型的智力而是你給它的規(guī)則、工具和容錯機制。當(dāng)你把提示詞寫清楚、把工具接口設(shè)計好、把異常處理補齊之后Ollama 跑出來的 Agent 完全可以勝任很多日常自動化任務(wù)。最后分享一個小技巧每次給 Agent 新增工具之前先在提示詞里手動描述這個工具的輸入輸出格式跑通一個任務(wù)之后再把工具注冊到代碼里。這樣增量式開發(fā)排查問題會輕松很多。