大模型落地:網(wǎng)關(guān)與Agent自動(dòng)化編程實(shí)戰(zhàn)指南)
企業(yè)里做大模型落地最容易被低估的一環(huán)不是模型選型而是網(wǎng)關(guān)。我見(jiàn)過(guò)太多團(tuán)隊(duì)一開(kāi)始直接讓業(yè)務(wù)代碼裸調(diào)各家 API等到要換模型、要限流、要審計(jì)、要計(jì)費(fèi)的時(shí)候才發(fā)現(xiàn)改一處牽動(dòng)全身。這篇就圍繞大模型網(wǎng)關(guān)和自動(dòng)化編程這兩條線(xiàn)把從基礎(chǔ)搭建到真正落地的完整路徑講清楚包括 Agent、CLI、API 這幾個(gè)關(guān)鍵詞背后的實(shí)際工程含義。不管你是剛接觸這塊的開(kāi)發(fā)者還是已經(jīng)在做企業(yè)內(nèi)部 AI 平臺(tái)的負(fù)責(zé)人都能從里面找到可以直接抄作業(yè)的部分。1. 為什么企業(yè)一定要有大模型網(wǎng)關(guān)這層1.1 裸調(diào) API 的三個(gè)致命問(wèn)題先說(shuō)清楚網(wǎng)關(guān)到底解決什么問(wèn)題。很多團(tuán)隊(duì)初期為了快業(yè)務(wù)代碼里直接寫(xiě)openai.ChatCompletion.create(...)或者requests.post(https://api.xxx.com/v1/chat/completions, ...)跑起來(lái)確實(shí)沒(méi)問(wèn)題。但只要規(guī)模稍微上來(lái)三個(gè)問(wèn)題必然暴露。第一個(gè)是密鑰擴(kuò)散。每個(gè)調(diào)用方都持有真實(shí) API Key一旦某個(gè)服務(wù)被入侵或者日志打印了請(qǐng)求頭密鑰就泄露了。企業(yè)里幾十個(gè)服務(wù)共用一套密鑰出了事根本查不到是誰(shuí)泄露的。第二個(gè)是模型切換成本。今天用 A 家的模型明天老板說(shuō) B 家便宜一半要換你得改所有業(yè)務(wù)代碼。不同廠商的請(qǐng)求體格式、鑒權(quán)方式、流式返回格式都不一樣改起來(lái)是災(zāi)難。第三個(gè)是可觀測(cè)性缺失。誰(shuí)在調(diào)、調(diào)了多少次、花了多少錢(qián)、響應(yīng)多慢、有沒(méi)有報(bào)錯(cuò)這些數(shù)據(jù)散落在各個(gè)服務(wù)里根本沒(méi)法統(tǒng)一統(tǒng)計(jì)。等到財(cái)務(wù)問(wèn)這個(gè)月 AI 花了多少錢(qián)你只能干瞪眼。網(wǎng)關(guān)這層就是把這些橫切關(guān)注點(diǎn)全部收攏到一個(gè)統(tǒng)一入口。業(yè)務(wù)方只需要知道網(wǎng)關(guān)地址和一個(gè)內(nèi)部 token剩下的鑒權(quán)、路由、限流、計(jì)費(fèi)、日志全在網(wǎng)關(guān)內(nèi)部完成。1.2 網(wǎng)關(guān)的核心能力清單一個(gè)能上生產(chǎn)的大模型網(wǎng)關(guān)至少要具備下面這些能力我按優(yōu)先級(jí)排一下能力優(yōu)先級(jí)說(shuō)明統(tǒng)一鑒權(quán)P0內(nèi)部 token 換真實(shí)密鑰密鑰不出網(wǎng)關(guān)多模型路由P0按模型名/策略轉(zhuǎn)發(fā)到不同廠商流式轉(zhuǎn)發(fā)P0SSE 透?jìng)鞑荒芷茐牧魇襟w驗(yàn)限流限速P1按用戶(hù)/應(yīng)用/模型維度限流用量計(jì)費(fèi)P1token 統(tǒng)計(jì)、成本核算日志審計(jì)P1請(qǐng)求響應(yīng)留痕可追溯失敗重試與降級(jí)P2主模型掛了自動(dòng)切備用緩存P2相同請(qǐng)求命中緩存省錢(qián)這里要特別強(qiáng)調(diào)流式轉(zhuǎn)發(fā)。大模型的響應(yīng)是 SSEServer-Sent Events流式返回的網(wǎng)關(guān)如果處理不當(dāng)比如先把整個(gè)響應(yīng)讀完再返回用戶(hù)就會(huì)看到卡半天然后一次性蹦出來(lái)體驗(yàn)直接崩掉。正確的做法是邊收邊轉(zhuǎn)發(fā)用流式管道處理。1.3 網(wǎng)關(guān)的部署形態(tài)選擇網(wǎng)關(guān)部署形態(tài)主要有三種各有適用場(chǎng)景進(jìn)程內(nèi) SDK 模式把網(wǎng)關(guān)邏輯做成一個(gè)庫(kù)業(yè)務(wù)直接引入。優(yōu)點(diǎn)是零網(wǎng)絡(luò)開(kāi)銷(xiāo)缺點(diǎn)是每個(gè)語(yǔ)言都要實(shí)現(xiàn)一遍且升級(jí)困難。獨(dú)立服務(wù)模式網(wǎng)關(guān)是一個(gè)獨(dú)立部署的服務(wù)業(yè)務(wù)通過(guò) HTTP 調(diào)用。這是最主流的做法語(yǔ)言無(wú)關(guān)升級(jí)方便。Sidecar 模式每個(gè)業(yè)務(wù) Pod 旁邊掛一個(gè)網(wǎng)關(guān)容器。適合 K8s 環(huán)境隔離性好但資源開(kāi)銷(xiāo)大。對(duì)絕大多數(shù)企業(yè)我推薦獨(dú)立服務(wù)模式。用 Go 或 Rust 寫(xiě)性能足夠單機(jī)扛幾千 QPS 沒(méi)問(wèn)題。下面給一個(gè)用 Go 寫(xiě)的極簡(jiǎn)網(wǎng)關(guān)核心邏輯示意func handleChatCompletion(w http.ResponseWriter, r *http.Request) { // 1. 校驗(yàn)內(nèi)部 token internalToken : r.Header.Get(X-Internal-Token) app, err : auth.Verify(internalToken) if err ! nil { http.Error(w, unauthorized, 401) return } // 2. 解析請(qǐng)求確定目標(biāo)模型 var req ChatRequest json.NewDecoder(r.Body).Decode(req) provider : router.Select(req.Model) // 3. 限流檢查 if !limiter.Allow(app.ID, req.Model) { http.Error(w, rate limited, 429) return } // 4. 替換為真實(shí)密鑰轉(zhuǎn)發(fā)請(qǐng)求 upstreamReq : buildUpstreamRequest(req, provider.APIKey) resp, err : httpClient.Do(upstreamReq) if err ! nil { // 5. 失敗降級(jí)到備用模型 resp, err fallback(req, provider) } // 6. 流式透?jìng)黜憫?yīng) streamCopy(w, resp.Body) }這段代碼看著簡(jiǎn)單但每一步都有坑。比如第 6 步的streamCopy必須用http.Flusher強(qiáng)制刷新緩沖區(qū)否則 Go 的默認(rèn)緩沖會(huì)讓流式變成偽流式。提示網(wǎng)關(guān)轉(zhuǎn)發(fā)時(shí)一定要設(shè)置合理的超時(shí)。大模型首 token 延遲可能到幾秒甚至十幾秒超時(shí)設(shè)太短會(huì)誤殺正常請(qǐng)求設(shè)太長(zhǎng)又會(huì)拖垮連接池。我的經(jīng)驗(yàn)是首 token 超時(shí) 30s整體超時(shí)按模型最大輸出長(zhǎng)度估算。2. 自動(dòng)化編程里的 Agent 與 CLI 到底怎么配合2.1 Agent 和 CLI 不是一回事這兩個(gè)詞經(jīng)常被混著用但它們的定位完全不同。Agent 是決策者CLI 是執(zhí)行者。Agent 負(fù)責(zé)理解任務(wù)、拆解步驟、決定下一步做什么。它本質(zhì)上是一個(gè)循環(huán)觀察當(dāng)前狀態(tài) → 思考 → 選擇動(dòng)作 → 執(zhí)行 → 觀察結(jié)果 → 繼續(xù)。而 CLI 是 Agent 可以調(diào)用的一個(gè)具體工具比如git、npm、docker或者專(zhuān)門(mén)為 AI 編程設(shè)計(jì)的命令行工具。打個(gè)比方Agent 像是一個(gè)項(xiàng)目經(jīng)理CLI 像是他手下的各種專(zhuān)業(yè)工具。項(xiàng)目經(jīng)理不會(huì)自己去擰螺絲而是決定現(xiàn)在該用螺絲刀了然后調(diào)用螺絲刀?,F(xiàn)在市面上有不少專(zhuān)門(mén)給 AI 用的 CLI 工具比如一些代碼生成 CLI、文件操作 CLI。它們的共同特點(diǎn)是輸入輸出結(jié)構(gòu)化、冪等性好、錯(cuò)誤信息清晰。這三點(diǎn)是 Agent 能可靠調(diào)用它們的前提。2.2 Agent 調(diào)用 CLI 的典型循環(huán)一個(gè)自動(dòng)化編程 Agent 的完整工作循環(huán)大概是這樣接收任務(wù)比如給這個(gè)項(xiàng)目加上單元測(cè)試探索環(huán)境調(diào)用ls、cat、grep等 CLI 了解項(xiàng)目結(jié)構(gòu)制定計(jì)劃決定先看哪些文件再寫(xiě)哪些測(cè)試執(zhí)行動(dòng)作調(diào)用文件讀寫(xiě) CLI 創(chuàng)建測(cè)試文件驗(yàn)證結(jié)果調(diào)用測(cè)試運(yùn)行 CLI看是否通過(guò)修正迭代如果失敗讀錯(cuò)誤信息回到第 4 步這個(gè)循環(huán)里第 5 步的驗(yàn)證是靈魂。沒(méi)有驗(yàn)證的 Agent 就是瞎猜有了驗(yàn)證才能自我糾錯(cuò)。這也是為什么好的 Agent 框架都強(qiáng)調(diào)工具返回結(jié)果要可解析。下面是一個(gè) Agent 調(diào)用 CLI 的偽代碼結(jié)構(gòu)def agent_loop(task, max_steps20): context [{role: system, content: SYSTEM_PROMPT}] context.append({role: user, content: task}) for step in range(max_steps): # 讓模型決定下一步動(dòng)作 response llm.chat(context, toolsAVAILABLE_TOOLS) if response.is_final: return response.content # 執(zhí)行模型選擇的工具 tool_name response.tool_call.name tool_args response.tool_call.args result execute_tool(tool_name, tool_args) # 把結(jié)果喂回上下文 context.append(response.message) context.append({role: tool, content: result}) return 達(dá)到最大步數(shù)限制這里有個(gè)關(guān)鍵細(xì)節(jié)上下文會(huì)越來(lái)越長(zhǎng)。每輪工具調(diào)用都會(huì)往 context 里塞內(nèi)容幾十輪下來(lái) token 消耗驚人。所以生產(chǎn)級(jí) Agent 必須做上下文管理比如只保留最近 N 輪、對(duì)歷史做摘要、把大文件內(nèi)容截?cái)嗟取?.3 工具設(shè)計(jì)的三條鐵律給 Agent 設(shè)計(jì) CLI 工具時(shí)我總結(jié)了三條鐵律踩過(guò)坑的都懂第一輸出要精簡(jiǎn)且結(jié)構(gòu)化。你讓 Agent 跑一個(gè)ls -la返回幾百行帶權(quán)限、時(shí)間、大小的信息模型要花大量 token 去解析。更好的做法是提供一個(gè)list_files工具只返回文件名列表。第二錯(cuò)誤信息要能指導(dǎo)下一步。工具失敗時(shí)返回的不該是Error: failed而應(yīng)該是文件 xxx.py 第 42 行語(yǔ)法錯(cuò)誤缺少冒號(hào)。模型看到后者才知道怎么修。第三操作要冪等或可回滾。Agent 可能會(huì)重復(fù)調(diào)用同一個(gè)工具如果工具不冪等就會(huì)產(chǎn)生副作用。比如創(chuàng)建文件應(yīng)該是覆蓋式的而不是追加式的。注意涉及刪除、覆蓋、執(zhí)行系統(tǒng)命令的工具一定要加確認(rèn)機(jī)制或沙箱隔離。我見(jiàn)過(guò) Agent 誤刪整個(gè)目錄的案例血的教訓(xùn)。3. 把網(wǎng)關(guān)和 Agent 串起來(lái)一個(gè)完整的落地架構(gòu)3.1 整體架構(gòu)分層把前面兩塊拼起來(lái)一個(gè)企業(yè)級(jí)的自動(dòng)化編程平臺(tái)大概分四層接入層Web 界面、IDE 插件、CI/CD 鉤子用戶(hù)從這里發(fā)起任務(wù)編排層Agent 運(yùn)行時(shí)負(fù)責(zé)任務(wù)拆解、工具調(diào)度、上下文管理網(wǎng)關(guān)層統(tǒng)一的大模型網(wǎng)關(guān)處理所有 LLM 調(diào)用執(zhí)行層各種 CLI 工具、代碼倉(cāng)庫(kù)、測(cè)試環(huán)境這個(gè)分層的好處是職責(zé)清晰。編排層不關(guān)心用的是哪家模型網(wǎng)關(guān)層不關(guān)心任務(wù)是什么執(zhí)行層不關(guān)心誰(shuí)在調(diào)用。任何一層要替換或升級(jí)都不影響其他層。3.2 請(qǐng)求的完整生命周期一個(gè)幫我修復(fù)這個(gè) bug的請(qǐng)求走完整個(gè)鏈路是這樣的用戶(hù)在 IDE 插件里輸入任務(wù)插件把當(dāng)前文件內(nèi)容和任務(wù)發(fā)給編排層編排層啟動(dòng) Agent構(gòu)造初始上下文Agent 調(diào)用網(wǎng)關(guān)請(qǐng)求模型生成下一步動(dòng)作網(wǎng)關(guān)鑒權(quán)、限流、路由到具體模型返回結(jié)果Agent 解析出要調(diào)用的工具比如讀取 test.py執(zhí)行層執(zhí)行工具返回文件內(nèi)容Agent 把結(jié)果加入上下文再次調(diào)用網(wǎng)關(guān)循環(huán)直到 Agent 認(rèn)為任務(wù)完成返回最終結(jié)果編排層把結(jié)果返回給 IDE 插件這個(gè)鏈路里網(wǎng)關(guān)是唯一的模型出口所有 token 消耗、延遲、錯(cuò)誤都在這里被記錄。這對(duì)成本控制和問(wèn)題排查至關(guān)重要。3.3 關(guān)鍵配置示例網(wǎng)關(guān)的路由配置我一般用 YAML 管理方便運(yùn)維改providers: - name: primary base_url: https://api.provider-a.com/v1 api_key: ${PROVIDER_A_KEY} models: [gpt-4-class, gpt-3.5-class] timeout: 60s - name: backup base_url: https://api.provider-b.com/v1 api_key: ${PROVIDER_B_KEY} models: [claude-class] timeout: 60s routes: - match: gpt-4-class primary: primary fallback: backup rate_limit: 100/min - match: claude-class primary: backup rate_limit: 50/min billing: currency: CNY rates: gpt-4-class: { input: 0.03, output: 0.06 } # 每千 token claude-class: { input: 0.02, output: 0.04 }這份配置里fallback字段實(shí)現(xiàn)了自動(dòng)降級(jí)rate_limit實(shí)現(xiàn)了限流billing實(shí)現(xiàn)了計(jì)費(fèi)。運(yùn)維改配置不用動(dòng)代碼重啟網(wǎng)關(guān)即可生效。4. 實(shí)操中真正會(huì)踩的坑4.1 上下文長(zhǎng)度超限的處理大模型都有上下文窗口限制Agent 跑久了必然超。報(bào)錯(cuò)信息通常是這樣的API error: 400 This models maximum context length is 1048576 tokens. However, your messages resulted in 1200000 tokens.處理這個(gè)問(wèn)題的策略有三層第一層預(yù)防。在往上下文里塞內(nèi)容前先估算 token 數(shù)。大文件不要整個(gè)塞進(jìn)去只塞相關(guān)片段??梢杂煤?jiǎn)單的字符數(shù)除以 4 來(lái)粗估 token 數(shù)英文中文大概除以 1.5。第二層壓縮。當(dāng)上下文接近上限時(shí)對(duì)歷史消息做摘要。把前面十幾輪的對(duì)話(huà)壓縮成一段總結(jié)保留關(guān)鍵決策和結(jié)論。第三層截?cái)?。?shí)在不行就丟棄最早的幾輪但要保留 system prompt 和最近幾輪。丟棄時(shí)最好保留工具調(diào)用的結(jié)果摘要而不是直接刪。def manage_context(messages, max_tokens100000): total estimate_tokens(messages) if total max_tokens * 0.8: return messages # 保留 system 最近 5 輪 system messages[0] recent messages[-10:] # 中間部分做摘要 middle messages[1:-10] if middle: summary summarize(middle) return [system, {role: system, content: f歷史摘要{summary}}] recent return [system] recent4.2 流式響應(yīng)的中斷與重連流式響應(yīng)最煩人的是中途斷掉。網(wǎng)絡(luò)抖動(dòng)、模型服務(wù)重啟、網(wǎng)關(guān)超時(shí)都可能導(dǎo)致流中斷。用戶(hù)看到的是回答到一半沒(méi)了。處理方案是在網(wǎng)關(guān)層做流式重試。具體做法是網(wǎng)關(guān)記錄已經(jīng)轉(zhuǎn)發(fā)給客戶(hù)端的 token 數(shù)如果上游斷了用相同的 prompt 重新請(qǐng)求但要求模型跳過(guò)已發(fā)送的部分。不過(guò)這個(gè)方案實(shí)現(xiàn)復(fù)雜且不是所有模型都支持。更實(shí)用的方案是客戶(hù)端側(cè)容錯(cuò)。前端檢測(cè)到流中斷后把已收到的內(nèi)容作為上下文發(fā)起一個(gè)繼續(xù)請(qǐng)求。雖然會(huì)多花點(diǎn) token但實(shí)現(xiàn)簡(jiǎn)單可靠。async function streamWithRetry(messages, maxRetries 3) { for (let i 0; i maxRetries; i) { try { const response await fetch(/api/chat, { method: POST, body: JSON.stringify({ messages, stream: true }) }); return await processStream(response); } catch (e) { if (i maxRetries - 1) throw e; // 把已收到的內(nèi)容加入上下文繼續(xù)請(qǐng)求 messages.push({ role: assistant, content: partialContent }); messages.push({ role: user, content: 請(qǐng)繼續(xù) }); } } }4.3 密鑰與權(quán)限的常見(jiàn)錯(cuò)誤配置網(wǎng)關(guān)時(shí)密鑰相關(guān)的錯(cuò)誤特別多。最常見(jiàn)的兩類(lèi)第一類(lèi)環(huán)境變量沒(méi)生效。報(bào)錯(cuò)長(zhǎng)這樣llm-deepseek: no api key for provider route deepseek-official這通常是配置文件里寫(xiě)了${DEEPSEEK_KEY}但環(huán)境變量沒(méi)導(dǎo)出或者導(dǎo)出在了錯(cuò)誤的 shell 里。排查方法是在網(wǎng)關(guān)啟動(dòng)腳本里加一行env | grep KEY確認(rèn)。第二類(lèi)權(quán)限范圍不匹配。比如某些 API 需要在控制臺(tái)聲明 scope沒(méi)聲明就會(huì)報(bào)choosemedia:fail api scope is not declared in the privacy agreement這類(lèi)問(wèn)題只能去對(duì)應(yīng)平臺(tái)的控制臺(tái)檢查應(yīng)用權(quán)限配置代碼層面無(wú)解。提示所有密鑰統(tǒng)一用密鑰管理服務(wù)如 Vault、KMS管理不要寫(xiě)在配置文件或環(huán)境變量里。環(huán)境變量在容器里容易被docker inspect看到。4.4 Docker 權(quán)限問(wèn)題網(wǎng)關(guān)如果用 Docker 部署經(jīng)常會(huì)遇到permission denied while trying to connect to the docker api這是因?yàn)楫?dāng)前用戶(hù)不在 docker 組里。解決方法是sudo usermod -aG docker $USER然后重新登錄。但生產(chǎn)環(huán)境更推薦用 rootless Docker 或者把網(wǎng)關(guān)跑在 K8s 里避免直接暴露 docker socket。5. 性能與成本的優(yōu)化空間5.1 緩存能省多少錢(qián)大模型調(diào)用里有相當(dāng)比例的請(qǐng)求是重復(fù)或高度相似的。比如 Agent 反復(fù)讀取同一個(gè)文件、反復(fù)問(wèn)同樣的問(wèn)題。加一層語(yǔ)義緩存命中率能到 20%-40%。緩存分兩種精確緩存請(qǐng)求內(nèi)容完全一致才命中。實(shí)現(xiàn)簡(jiǎn)單用 Redis 存hash(prompt) - response即可。語(yǔ)義緩存請(qǐng)求語(yǔ)義相似就命中。需要向量化 prompt做相似度檢索。命中率更高但實(shí)現(xiàn)復(fù)雜。對(duì)大多數(shù)場(chǎng)景精確緩存就夠了。注意緩存要設(shè)置合理的 TTL模型更新后舊緩存要失效。5.2 模型分級(jí)路由不是所有請(qǐng)求都需要最強(qiáng)模型。Agent 的很多步驟比如判斷文件類(lèi)型提取函數(shù)名用便宜的小模型完全夠用。只有關(guān)鍵推理步驟才需要大模型。網(wǎng)關(guān)可以按請(qǐng)求的復(fù)雜度做分級(jí)路由def select_model(request): # 簡(jiǎn)單任務(wù)用小模型 if request.task_type in [classify, extract, format]: return small-model # 復(fù)雜推理用大模型 if request.task_type in [reason, plan, debug]: return large-model return medium-model這個(gè)策略實(shí)測(cè)能省 50% 以上的成本而任務(wù)成功率幾乎不受影響。5.3 并發(fā)與連接池網(wǎng)關(guān)作為所有請(qǐng)求的入口并發(fā)能力是瓶頸。幾個(gè)關(guān)鍵點(diǎn)HTTP 客戶(hù)端要復(fù)用連接不要每次請(qǐng)求都新建。Go 的http.Client默認(rèn)就復(fù)用但要注意MaxIdleConnsPerHost要調(diào)大。上游連接數(shù)要限制避免把模型服務(wù)打掛。用信號(hào)量或連接池控制。流式請(qǐng)求要單獨(dú)管理因?yàn)榱魇竭B接占用時(shí)間長(zhǎng)不能和普通請(qǐng)求共用連接池。transport : http.Transport{ MaxIdleConns: 1000, MaxIdleConnsPerHost: 200, IdleConnTimeout: 90 * time.Second, // 流式請(qǐng)求需要禁用響應(yīng)緩沖 DisableCompression: false, } client : http.Client{ Transport: transport, Timeout: 0, // 流式請(qǐng)求不設(shè)總超時(shí)用 context 控制 }6. 從能跑到好用的幾個(gè)進(jìn)階點(diǎn)6.1 可觀測(cè)性建設(shè)網(wǎng)關(guān)跑起來(lái)后最重要的就是看得見(jiàn)。至少要采集這幾類(lèi)指標(biāo)指標(biāo)類(lèi)型具體指標(biāo)用途請(qǐng)求量QPS、按模型/應(yīng)用分組容量規(guī)劃延遲P50/P95/P99、首 token 延遲體驗(yàn)監(jiān)控錯(cuò)誤錯(cuò)誤率、錯(cuò)誤類(lèi)型分布故障排查成本token 消耗、費(fèi)用成本控制限流觸發(fā)次數(shù)、被限流應(yīng)用配額調(diào)整這些指標(biāo)用 Prometheus 采集Grafana 展示。首 token 延遲這個(gè)指標(biāo)特別重要它直接決定用戶(hù)體感但很多團(tuán)隊(duì)只監(jiān)控總延遲忽略了它。6.2 灰度與回滾模型切換、網(wǎng)關(guān)升級(jí)都要能灰度。做法是給請(qǐng)求打標(biāo)簽按比例分流到新舊版本。比如 10% 流量走新模型觀察指標(biāo)正常后再逐步放大?;貪L要能秒級(jí)完成。配置化的路由讓回滾變成改一行配置的事這是網(wǎng)關(guān)架構(gòu)相比硬編碼的最大優(yōu)勢(shì)。6.3 Agent 的安全邊界Agent 能執(zhí)行命令、讀寫(xiě)文件安全邊界必須劃清楚文件系統(tǒng)隔離Agent 只能訪(fǎng)問(wèn)指定目錄用容器或 chroot 限制命令白名單只允許執(zhí)行預(yù)定義的安全命令禁止rm -rf、curl外網(wǎng)等網(wǎng)絡(luò)隔離Agent 執(zhí)行環(huán)境不能訪(fǎng)問(wèn)外網(wǎng)防止數(shù)據(jù)外泄資源限制CPU、內(nèi)存、執(zhí)行時(shí)間都要設(shè)上限防止死循環(huán)這些限制在網(wǎng)關(guān)層和編排層都要做不能只靠一層。6.4 多租戶(hù)隔離企業(yè)里多個(gè)團(tuán)隊(duì)共用一套平臺(tái)隔離是剛需。隔離維度包括配額隔離每個(gè)團(tuán)隊(duì)有獨(dú)立的 token 配額和 QPS 上限數(shù)據(jù)隔離A 團(tuán)隊(duì)的對(duì)話(huà)歷史 B 團(tuán)隊(duì)看不到密鑰隔離每個(gè)團(tuán)隊(duì)用自己的密鑰便于獨(dú)立計(jì)費(fèi)模型隔離某些高級(jí)模型只對(duì)特定團(tuán)隊(duì)開(kāi)放這些都在網(wǎng)關(guān)的鑒權(quán)環(huán)節(jié)實(shí)現(xiàn)通過(guò)內(nèi)部 token 關(guān)聯(lián)到租戶(hù)信息后續(xù)所有操作都帶上租戶(hù)上下文。7. 一些實(shí)戰(zhàn)中的零碎經(jīng)驗(yàn)最后分享幾個(gè)散落但很實(shí)用的點(diǎn)。關(guān)于 CLI 工具的選擇優(yōu)先選那些有--json輸出選項(xiàng)的。文本輸出解析起來(lái)太脆弱模型稍微換個(gè)格式就崩。JSON 輸出配合 schema 校驗(yàn)穩(wěn)定性高一個(gè)數(shù)量級(jí)。關(guān)于 Agent 的步數(shù)限制不要設(shè)太大。我見(jiàn)過(guò)設(shè) 100 步的結(jié)果 Agent 陷入循環(huán)燒了幾百萬(wàn) token 才發(fā)現(xiàn)。一般任務(wù) 20 步足夠復(fù)雜任務(wù) 50 步封頂超了就報(bào)錯(cuò)讓人介入。關(guān)于網(wǎng)關(guān)的日志請(qǐng)求和響應(yīng)內(nèi)容要脫敏后再存。用戶(hù)可能在里面輸入了敏感信息直接存明文有合規(guī)風(fēng)險(xiǎn)。至少要把身份證、手機(jī)號(hào)、郵箱這類(lèi)模式做正則替換。關(guān)于模型降級(jí)降級(jí)不是簡(jiǎn)單換個(gè)模型就行。不同模型的輸出格式可能不同Agent 的解析邏輯要能兼容。最好在網(wǎng)關(guān)層做輸出格式歸一化讓上層感知不到模型差異。關(guān)于測(cè)試網(wǎng)關(guān)和 Agent 都要有 mock 能力。不能每次測(cè)試都真調(diào)模型又慢又貴。用錄制回放的方式把真實(shí)響應(yīng)錄下來(lái)測(cè)試時(shí)回放既快又穩(wěn)定。關(guān)于版本管理prompt 也要版本化。Agent 的 system prompt 改一個(gè)字行為可能天差地別。把 prompt 納入 Git 管理每次改動(dòng)都有記錄出問(wèn)題能快速定位是哪次改動(dòng)導(dǎo)致的。這套東西我從零搭過(guò)兩遍第一遍踩了無(wú)數(shù)坑第二遍就順多了。核心體會(huì)是網(wǎng)關(guān)這層越早建越好Agent 的能力越晚放越好。網(wǎng)關(guān)是基礎(chǔ)設(shè)施早建早省心Agent 的能力邊界要慢慢放開(kāi)每放開(kāi)一個(gè)權(quán)限都要配套的監(jiān)控和回滾機(jī)制。急著讓 Agent 什么都能干最后往往是收拾爛攤子花的時(shí)間比省下來(lái)的還多。