说个我上周实际遇到的事。一个内部Demo Agent业务逻辑写得挺顺结果一上生产就卡死模型返回了一个看起来合法的“工具调用”但参数JSON里混进了两个换行符和一段Markdown代码块标记我的解析器直接炸了。折腾了一下午才意识到真正让Agent“能跑”、“跑得稳”、“跑得可控”的那套东西根本不在模型本身而在模型外面那层看不见的骨架——也就是Agent Infra智能体基础设施。这两年凡是喊Agent的人大多在聊提示词、在聊编排框架、在聊某个模型多强。但巨头内部争得最凶的恰恰是没人天天挂在嘴边的那层地基工具调用协议、记忆存储、上下文管理、任务路由、评测闭环、权限与审计。这篇文章我就摊开讲讲Agent Infra到底包着哪些东西巨头模式上为什么把它当战场以及最关键的一件事——一个普通工程师怎么在没有大厂资源的情况下拿到属于自己的那张入场券。后半部分我会附一个从零写起的最小Agent运行时你照着敲一遍基本就明白这层基础设施在解决什么问题了。1. Agent Infra到底是什么为什么说它是隐秘战场1.1 从一次翻车现场理解Infra的边界先回到开头那个翻车例子。我用的模型能力不差返回的意图判断完全正确它想调用一个“查询库存”的工具参数是商品ID。问题出在哪呢出在模型吐出来的文本不完全符合工具执行器期望的结构。模型这层属于“智能”的部分而工具执行器、参数解析器、重试策略、错误日志这些统统属于Agent基础设施。你可以这么理解模型是发动机Agent应用是车身而Agent Infra是底盘、变速箱、油路、仪表盘。发动机再猛底盘松散、油路堵塞整车照样跑不起来。过去的业内共识是“模型即一切”现在越来越多人承认模型能力到了同一水平线之后真正拉开差距的是谁的基础设施更扎实谁能把不稳定的模型输出规整成稳定可靠的服务。1.2 拆开看Agent Infra的六大核心组件为了不把这个词搞成玄学我按自己做项目时实际要碰的东西拆一下第一块工具调用与执行层。模型决定“要调用哪个工具、传什么参数”但这只是一个意图真正执行工具、把结果回填给模型、处理执行异常的是基础设施层。它要管工具注册表、参数Schema校验、执行超时、并发限制、错误码归一化。第二块上下文与记忆系统。模型上下文窗口永远不够用。一次任务可能经历几十轮工具调用中间的中间结果、用户偏好、历史决策不能全塞进Prompt也不能全丢掉。需要分层短期工作记忆、长期向量记忆、可压缩的摘要记忆。第三块编排与状态管理。一个复杂任务往往涉及多步决策Agent可能从一个子任务跳到另一个子任务中途还可能中断恢复。基础设施要提供状态持久化、重试机制、任务编排图保证Agent不会因为一次网络抖动就“失忆”甚至死循环。第四块安全与权限隔离。Agent拿到了工具调用能力就等于给模型发了一把能操作真实系统的钥匙。这把钥匙能开哪些门、每个工具允许谁调用、操作日志怎么留痕这是Infra层必须回答的问题。第五块评测体系。模型改了提示词怎么知道Agent整体表现是变好还是变坏了需要一套离线评测集和在线评估指标这是很多人忽略但实际最要命的一块。第六块可观测性。Agent的每个决策链条都要能回溯模型想了什么、选了哪个工具、参数是什么、工具返回了什么、结果是否被接受。没有TraceAgent出问题你连查都没法查。1.3 为什么应用层没壁垒Infra层有壁垒一个Agent应用的核心逻辑可能就是几段提示词加一些工具定义别人看一眼就能抄走这就是应用层没壁垒。但Infra层不一样工具调用的稳定性、记忆策略的合理性、评测数据的积累、错误处理的经验这些是靠一个个线上问题喂出来的是慢功夫也是真壁垒。这也解释了标题里的“隐秘战场”——巨头们不会在发布会上高喊“我们在做Agent Infra”因为这东西用户感知不到但它在决定Agent类产品能不能规模化的上限。谁能把这层做厚谁就能在上面长出别人复制不了的应用生态。2. 巨头们抢的是什么Agent Infra的产业逻辑2.1 模型层的同质化把竞争逼向中间层过去两年的主线是模型能力竞赛但你会发现一个趋势头部模型之间的能力差距在快速收窄同时API调用价格在往地板方向打。模型本身越来越像“水电煤”按Token计费、随取随用。当发电厂不再稀缺时真正的商业价值就转向输配电网络——也就是把模型能力送达具体场景的那层基础设施。对任何一个提供模型服务的厂商来说如果只卖Token那永远拼的是价格和参数规模利润薄且没有黏性。但如果在Token之上提供一套好用的工具调用运行时、记忆服务、Agent编排能力和配套的可观测性工具开发者一旦基于这套设施把业务跑起来迁移成本会非常高。这就是典型的生态锁定。2.2 数据飞轮和工具调用日志的价值还有一个容易被忽略的点Agent基础设施每天处理的工具调用日志本身就是一座金矿。每个Agent任务都是一条更接近真实用户需求的行为轨迹包含用户的模糊意图、模型的中间推理、工具的执行结果、甚至失败后的修正路径。跟传统的搜索日志、推荐日志相比这套数据的密度和信息量高出几个量级。它可以用来微调模型可以用来优化工具路由策略更可以用来训练下一代“会主动使用工具”的智能体。巨头手里握着这些数据等于握着下一轮模型进化的燃料。2.3 三类玩家的不同打法我观察到目前Agent Infra这个战场有三类主要玩家打法差异很大。表格对比一下玩家类型核心优势切入点主要打法模型厂商模型能力、开发者心智统一Agent协议、工具调用SDK用框架绑定模型生态把开发者留在自家API上云厂商算力、存储、既有企业客户托管式Agent运行平台、向量数据库、编排服务把Infra能力当作云服务卖给企业按资源消耗收费开源社区框架中立、透明、无厂商锁定通用编排层、抽象接口靠生态和信任占据工程师的本地开发环境三类玩家之间既有合作也有摩擦。模型厂商希望开发者直接用自家SDK云厂商希望开发者用自家托管服务开源框架则希望成为中间那层“不被任何一方绑架”的抽象层。现在还没到一家独大的时候标准也远未定型这正是普通工程师的机会所在。2.4 投资视角基础设施投资的反常识逻辑按照常理风口来了大家追的是最性感的层——应用层。但在AI赛道过去几年真正拿到稳定回报的往往是布局在基础设施层的项目。原因很简单应用层变化太快今天爆火的产品明天可能就被新模型取代但底层需求不会消失——模型要接入工具、Agent要管理上下文、开发流程要可观测。面向开发者销售的基础设施还有一个好处开发者一旦使用会持续产生调用天然是订阅制、用量制收入现金流模型比项目制健康得多。这也是资本市场愿意给Infra类项目更高估值倍数的原因。当然这不代表随便做一个开发工具就能成功但从产业逻辑上说Agent Infra确实是当前少数既有长期确定性、又有足够成长空间的大方向。3. 普通工程师怎么拿到这张入场券3.1 这个战场对普通人是友好的如果这是一场拼算力、拼GPU库存、拼资本开支的战争那确实跟普通工程师没什么关系。但Agent Infra恰好不是这样它拼的是工程判断力是踩坑经验是设计取舍这些恰恰是普通工程师的日常。现在整个行业还处于“标准未定、方法未熟”的早期。模型厂商的协议各搞一套编排框架一天一个版本评测方法论还在摸索。越是这种时候一个有实战经验、能落地解决问题的工程师就越值钱。等标准统一、框架稳定、最佳实践固化之后反而没有普通人的位置了那时候入场只能当螺丝钉。3.2 需要补齐的知识栈我自己整理过一份Agent Infra相关的能力清单不一定全都要精通但至少得知道每一项解决什么问题LLM API交互细节上下文窗口管理、函数调用参数格式、流式输出处理、Token计费逻辑协议设计能力工具描述Schema的规范化、函数调用的错误返回设计状态管理Agent任务的多步状态机设计、持久化方案选型存储与检索向量数据库、混合检索、上下文摘要压缩策略可观测性Trace埋点、指标采集、日志结构化以及它们背后的分析思路评估体系离线评测集的构建、线上指标的选取、回归测试的运营这些不一定都从零学起。有后端开发经验的人状态管理、协议设计、可观测性本来就熟有数据工程经验的人检索、评测、数据飞轮是手拿把攥。Agent Infra本质上是把已有的工程能力和LLM的特性结合起来交叉点恰好是机会。3.3 五个低成本切入点不用等公司立项也不用等老板点头下面这几个方向我自己都尝试过两三天就能起步第一给自己团队搭一套内部Agent工具箱。团队里一定有人用LLM写脚本、做自动化他们现在大概率是各自为战、重复造轮子。你把它收集起来做成一个统一的工具注册和调用平台先解决内部问题。别嫌小内部工具的锤炼过程就是你理解Infra需求的过程。第二写一个垂直场景的记忆组件。比如专门给“客服知识助手”做一套长期记忆短期记忆分层存储方案用向量库加SQLite就能起步。这个场景小、需求明确、业务价值可衡量。第三参与开源Agent框架的Infra层共建。不一定要写多核心的代码从补充测试用例开始就行。开源社区特别缺“把边界Case测清楚”的人而测试边界Case恰恰是理解系统设计最好的方式。第四建一个公开的Agent评测集。挑一个具体场景比如“多工具调用下的参数传递正确性”攒几十个真实案例附上期望输出。这事不需要任何人的授权做出来就是你在Agent Infra领域的代表作。第五把大模型接入你手头的老系统。找一个现有的内部API给它裹一个LLM可以调用的Schema再做一个简单的路由服务。这本质上是在做“遗留系统与模型之间的适配层”而适配层就是Infra最初级的形态。3.4 一个工程师的“最小入场动作”别想太复杂我建议的最小入场动作是拿一个周末写一个带“工具调用-结果回填-多轮循环”的最小可运行Agent全程不依赖任何重型框架就用模型API加几十行代码。你会在做这件事的过程中亲手撞上上下文膨胀、参数解析失败、循环失控这三个Infra最核心的问题。撞上了说明你看到战场了。下面这章我就把这个最小运行时的代码和设计思路完整拆给你看。4. 实操从0到1写一个轻量级Agent运行时4.1 设计目标与选型我这次写的这个demo目标只有一个跑通“模型决策-调用工具-结果回填-继续决策”的完整循环。外部依赖精简到极致只用一个HTTP请求库所有逻辑都在一个Python文件里。为什么不用现成的Agent框架我不是否定框架而是要你先理解每个环节在干什么。框架帮你藏起来的那些细节恰恰是Infra层真正的价值点。你亲手写完一遍这个循环再去看任何框架一眼就能看懂它的设计意图。先定义这个Agent的任务场景它能处理“查天气”和“算数学”两个工具调用。用户输入一句话模型决定是否调用工具、调用哪个、参数是什么我们负责执行并把结果回填然后模型根据结果生成最终回复。4.2 核心代码工具注册与执行器第一段代码负责工具注册和执行分发。我用一个字典保存工具名到处理函数的映射再用一个统一的Schema来描述工具这个Schema会传给模型让模型知道它能调什么、参数长什么样。import json import os from typing import Any, Callable, Dict, List # 工具注册表名字 - 处理函数 TOOL_REGISTRY: Dict[str, Callable[..., str]] {} def register_tool(name: str): def decorator(func: Callable[..., str]): TOOL_REGISTRY[name] func return func return decorator register_tool(get_weather) def get_weather(city: str, date: str today) - str: # 这里应该是真实API调用demo直接返回模拟数据 return f{city} {date} 天气晴气温 18~26 度 register_tool(calculator) def calculator(expression: str) - str: # 出于安全考虑demo只用白名单表达式求值 safe_chars set(0123456789-*/(). ) if not all(c in safe_chars for c in expression): return error: illegal expression try: result eval(expression) # 仅限可信任环境 return str(result) except Exception as e: return ferror: {e}这个工具注册模式其实就是你现在见到的所有Agent框架里ToolRegistry的雏形。它解决的核心问题是把“模型的输出意图”和“代码里的真实函数”做一个映射。模型不关心你的函数签名长什么样它只看你提供的Schema执行层不关心模型怎么理解它只按名字找函数、按参数调用。安全这块多说一句demo里用eval图省事真实环境绝对不要这么干。真实场景至少要做参数类型校验、表达式解析白名单、执行沙箱化。工具执行器的安全意识应该从你写第一行代码的时候就开始建立。4.3 核心代码模型调用与函数调用Schema下面这段是跟模型API交互的适配层。我没有绑定任何具体的模型服务商只按通用的Chat Completions请求格式来发HTTP请求。你可以把API_BASE换成你自己的模型端点或者换成任意供应商的SDK封装。import httpx API_BASE os.getenv(AGENT_API_BASE, https://your-model-endpoint/v1/chat/completions) API_KEY os.getenv(AGENT_API_KEY, ) TOOL_SCHEMAS [ { type: function, function: { name: get_weather, description: 查询某个城市某天的天气情况, parameters: { type: object, properties: { city: {type: string, description: 城市名}, date: {type: string, description: 日期默认今天} }, required: [city] } } }, { type: function, function: { name: calculator, description: 计算数学表达式的结果, parameters: { type: object, properties: { expression: {type: string, description: 数学表达式} }, required: [expression] } } } ] def call_llm(messages: List[Dict], tools: List[Dict] | None None) - Dict: payload { model: os.getenv(AGENT_MODEL, your-model-name), messages: messages, tools: tools, temperature: 0.2, } headers {Authorization: fBearer {API_KEY}} resp httpx.post(API_BASE, jsonpayload, headersheaders, timeout60) resp.raise_for_status() return resp.json()这里每个工具都要提供JSON Schema格式的参数描述这个描述质量直接决定模型生成的参数对不对。我最初做的时候Schema写得特别随意参数描述都是“一些信息”这种结果模型频繁传错字段。后来把每个参数的描述写成“在什么情况下填什么、不填会怎样”工具调用准确率肉眼可见地上涨。关于temperatureAgent任务我一般设0.2甚至更低。工具调用场景要的是稳定和可复现不是发散创意。温度拉太高模型的JSON格式偶尔会飘这是我踩过坑后才定下来的参数。4.4 核心代码Agent主循环接下来是整台车的变速箱——主循环。它负责把用户消息交给模型解析模型返回的tool_calls逐个执行工具把结果拼成消息回填给模型再让模型继续决策直到模型不再请求工具调用。def extract_tool_calls(response: Dict) - List[Dict]: choice response[choices][0] message choice.get(message, {}) return message.get(tool_calls, []), message.get(content) def run_agent(user_input: str, max_iterations: int 10) - str: messages [{role: user, content: user_input}] for step in range(max_iterations): print(f[step {step}] sending {len(messages)} messages) response call_llm(messages, toolsTOOL_SCHEMAS) tool_calls, content extract_tool_calls(response) if not tool_calls: return content or no response # 把模型的工具请求追加进对话历史 messages.append({ role: assistant, content: content, tool_calls: tool_calls }) # 逐个执行工具 for tc in tool_calls: fn_name tc[function][name] fn_args json.loads(tc[function][arguments]) print(f[step {step}] calling {fn_name} with {fn_args}) result TOOL_REGISTRY[fn_name](**fn_args) messages.append({ role: tool, tool_call_id: tc[id], content: result }) # 本轮工具结果已回填让模型继续决策 return error: max iterations reached这个循环看着简单但它已经包含了Agent运行时最核心的四个机制迭代上限、消息历史维护、工具调用解析、结果回填。max_iterations那个参数尤其重要没有它Agent一旦陷入“反复调用同一个工具但参数有偏差”的死循环你的成本会以肉眼可见的速度烧掉。我本地跑出来的效果大致是这样用户问“北京今天适合穿什么出门”——模型先调用get_weather拿到天气然后自己根据天气信息生成穿衣建议整个过程两次模型调用、一次工具调用逻辑跑得很顺。4.5 给它加一个“记忆”模块上面这个循环是典型的无状态Agent每次请求都把所有历史消息重新发给模型上下文窗口一满就会炸。我们可以加一个最简记忆模块用SQLite存“用户ID-对话片段-摘要向量”但为了让demo保持轻量我先用最简单的方案——只缓存最后的摘要文本。# 简版记忆token数超限时把最早的消息压缩成摘要 def compress_messages(messages: List[Dict], max_messages: int 20) - List[Dict]: if len(messages) max_messages: return messages keep messages[:1] messages[-10:] # 实际场景调用一个小模型把被丢弃的部分生成摘要插入system message print([memory] compressed old messages) return keep这个方案当然很粗糙但它的设计思路是真实且重要的记忆的本质是“在不动用无限上下文的情况下保留决策所需的关键信息”。真实产品里会用向量检索找出与当前问题最相关的历史片段也会用摘要模型对过期对话做分层压缩。这些都属于Agent Infra里最活跃的探索方向。4.6 观察点你应该从运行日志里看到什么跑完这个demo不要只满足于“它能工作”。我再强调一下Agent可观测性的价值主循环里埋的那几个print就是最原始的Trace。日志里要能看到每一轮模型返回了什么、选择了哪个工具、传了什么参数、工具执行结果是什么、最终回答是什么。当Agent复杂到一定程度没有这种全链路日志排查问题就是大海捞针。我见过一个线上Agent每周都会偶发一次“答非所问”团队查了两周没定位到最后是靠翻Trace日志发现模型偶尔会把上一个任务的工具参数错带到这个任务里。记录每个决策节点再把这些记录接入统一日志系统这事越早做越省心。5. 实战踩坑Agent系统跑起来之后的五个难关5.1 不同模型的工具调用格式不兼容我最早写适配层的时候天真地以为各家模型Follow的都是同一个函数调用标准结果被现实教育了。有的模型返回的tool_calls放在message里有的放在单独的字段参数名有的叫arguments有的叫parameters连工具执行的返回格式都不一致。对策就是做Adapter层把不同供应商的返回统一转成内部结构屏蔽下游差异。千万别在业务代码里到处写判断分支。接口的兼容层要做得越薄越好能转标准格式的部分都在Adapter里解决。5.2 JSON解析地狱模型返回的function arguments应该是JSON字符串但实际经常出现三种情况被Markdown代码块包裹、参数名带引号和单引号混用、JSON里有非法尾逗号。每次解析失败Agent就卡死在那里。我现在的做法是双解析策略先用json.loads直接解析失败后先剥离Markdown围栏再用正则把单引号替换成双引号最后再试一次。真实生产环境我建议在后面加一层“模型自我修复”——把解析错误信息回传给模型让它自己修正格式。虽然多一次调用但比直接任务失败强得多。5.3 上下文无限膨胀工具调用的返回结果可能非常大。比如查询一个订单列表返回几千条记录你会忍不住把所有内容都塞给模型让它总结。短期内Agent“感觉聪明”了但Token账单和响应延迟会让你很快就后悔。解决方案一般是三层工具返回之前先做结果精简只保留核心字段精简不了就分页截断只把第一页给模型让模型决定要不要翻页继续更复杂一点的做法是把大块文本存入外部存储只给模型一个检索ID按需取用。第三条是从RAG系统里借鉴来的思路效果很好。5.4 循环失控与成本失控上面demo里有max_iterations10我建议你实际跑一下把这个值改成50看看会发生什么。模型在一个复杂任务里反复尝试同一种失败的调用方式迭代次数和费用会迅猛增长。真实场景除了迭代上限还应该有单次任务成本上限、工具调用失败次数上限、以及“重复调用同一工具同样参数”的熔断。我还习惯在每次Agent运行结束后打一个成本标记消耗了多少Token、调用了多少次模型、耗时多久。把这些数据累计下来你就能分析出哪个业务环节的Agent特别贵、为什么不正常这是Agent FinOps的早期雏形。5.5 不做评测等于裸奔最后这条是我最想强调的。很多人改Agent的提示词或者工具定义属于“改了就跑跑通就觉得成功”。问题是Agent的行为是非确定性的这次跑通不代表下次跑通换一个用户表达方式可能就崩了。我现在给自己立的一个规矩是任何Agent项目先攒够一份20个案例的回归测试集再改代码。这些案例要覆盖正常路径、边界情况、模型胡言乱语的情况。每次改完跑一遍比感觉靠谱得多。评测集的做法不复杂就是把输入、期望工具调用序列、期望最终输出存成JSON写个脚本自动跑。难的不是技术是坚持维护这套测试集。6. 写在最后入场之后我从写下第一版Agent运行时到现在最大的感受是Agent这个词听起来很高深拆到底就是“模型加循环加工具加记忆”这几件事难的是把每一件事做到生产可用。而那些把生产可用这件事做好的公司构建的正是Agent Infra这个隐秘战场。金字塔尖的资源游戏和我们无关但这层基础设施的砖瓦恰恰是要一块一块由工程师砌起来的。我个人建议如果你真想入场别从读论文开始从模仿上面那个demo开始然后换一个你自己业务里真实遇到的场景把它变成一个有工具、有记忆、有日志的小系统。跑通之后你自然会看到无数可以改进的细节那些细节就是你的入场券变成职业壁垒的过程。等你在这些细节里积累出几个属于自己的解决方案那时候你就不是在场外看热闹的人了。