ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

AI Native架构实战:从零搭建LLM网关与Agent编排系统

AI Native架构实战:从零搭建LLM网关与Agent编排系统 1. 为什么现在必须重新思考系统架构过去两年我参与过三个从零起步的 AI 项目也接手过两个“传统系统加个 LLM 接口”的改造项目。这两类项目的结局差异非常大前者上线三个月后迭代速度依然很快后者则在第四个月开始陷入“改一个 Prompt 崩三个接口”的泥潭。问题不在于模型选得好不好而在于架构从第一天起就没有把 AI 当作核心组件来对待。AI Native 架构这个词现在被用得很泛但我的理解很具体系统的核心链路、数据流向、状态管理、错误处理、扩展方式全部围绕模型推理和 Agent 执行来设计而不是把模型当成一个外挂的“智能接口”。传统架构里业务逻辑是确定的数据库是唯一事实来源AI Native 架构里模型输出是不确定的上下文和记忆才是事实来源数据库反而变成了辅助存储。这篇文章适合三类人看正在规划 AI 产品从零搭建的技术负责人、准备把现有系统做 AI 化改造的工程师、以及想理解 Agent 和 LLM 在真实系统里怎么落地的开发者。我会从架构设计思路、核心组件拆解、实操搭建过程、常见问题排查四个维度展开尽量把每个决策背后的“为什么”讲清楚而不是只给一堆名词。提示本文讨论的架构方案基于当前主流 LLM 能力和 Agent 框架的常见实践具体选型需要根据你的团队规模、预算和业务场景做调整不要照搬。2. AI Native 架构的整体设计思路拆解2.1 从“模型外挂”到“模型内核”的思维转变传统系统加 AI 的典型做法是业务系统照常运转在需要“智能”的地方调一次模型 API拿到结果后继续走原来的流程。这种模式在简单场景下能用比如文本分类、摘要生成。但一旦涉及多轮对话、工具调用、状态保持问题就暴露了模型没有记忆每次调用都是无状态的业务系统不知道模型什么时候会失败错误处理全靠 try-catchPrompt 散落在各个业务代码里改一处忘一处。AI Native 的思路是把模型和 Agent 放到架构的中心位置。具体来说系统的主流程不再是“接收请求→查数据库→返回结果”而是“接收请求→构建上下文→Agent 决策→执行工具→更新记忆→返回结果”。数据库从“唯一事实来源”降级为“工具之一”真正的状态存在于对话历史、向量记忆和 Agent 的执行轨迹中。这个转变带来的最大好处是可扩展性。当你想加一个新能力时不需要改主流程只需要给 Agent 注册一个新工具或者在记忆里增加一类上下文。我实测下来这种架构下增加一个新业务功能的平均时间从原来的两三天缩短到半天左右。2.2 核心组件选型与职责划分一个完整的 AI Native 系统通常包含以下核心组件每个组件的选型和职责边界需要提前想清楚组件核心职责常见选型选型考量LLM 网关统一模型调用、限流、降级、日志自建网关或开源方案需要支持多模型切换和 Token 计量Agent 编排层决策、工具调用、多步执行主流 Agent 框架关注工具注册的灵活性和执行轨迹可观测性记忆系统短期对话、长期向量记忆向量库加关系库注意写入放大和检索延迟工具层封装外部能力供 Agent 调用函数注册机制每个工具要有清晰的入参出参和错误定义可观测层追踪、评估、告警链路追踪加评估集没有评估集的 AI 系统等于盲飞这里重点说LLM 网关。很多人觉得直接调模型 API 就行为什么要加一层网关我的经验是当你有超过两个模型供应商、超过三个业务线在用模型时没有网关会非常痛苦。网关要解决的核心问题包括统一鉴权和配额、请求重试和降级、Token 消耗统计、Prompt 版本管理、敏感内容过滤。这些能力如果散落在业务代码里维护成本会指数级上升。Agent 编排层的选型是最容易踩坑的地方。我的建议是如果你的业务场景是固定的几步流程用工作流引擎加 LLM 节点就够了不需要上完整的 Agent 框架。只有当你需要模型自主决定调用哪些工具、执行多少步时才需要引入 Agent 编排。过度设计是 AI Native 项目最常见的死因之一。2.3 零信任原则在 AI 架构中的落地零信任这个词在安全领域很常见但在 AI 架构里同样适用。核心思想是不要信任模型的任何输出。模型可能产生幻觉、可能被提示注入攻击、可能返回格式错误的内容。所以架构上要做到模型输出必须经过校验层才能进入业务逻辑工具调用必须有权限检查和参数校验敏感操作必须有人工确认或二次验证所有模型调用链路必须可追溯我在一个项目里吃过亏Agent 调用了一个“发送邮件”的工具结果模型把收件人参数填成了一个不存在的地址导致业务方收到大量退信。后来我们在工具层加了参数白名单校验才解决了这个问题。这个教训说明零信任不是口号是要落到每个工具、每个输出上的具体检查。3. 核心细节解析与实操要点3.1 LLM 网关的搭建与关键配置搭建 LLM 网关的第一步是定义统一的请求和响应格式。不管底层接的是哪家模型对上层的接口应该是一致的。我通常定义一个这样的结构{ model: default, messages: [ {role: system, content: ...}, {role: user, content: ...} ], tools: [], temperature: 0.7, max_tokens: 2048, trace_id: uuid }网关内部要做的事情包括根据 model 字段路由到不同的供应商适配器、检查配额、记录 Token 消耗、对请求和响应做脱敏日志。这里有个细节trace_id 必须贯穿整个链路从网关到 Agent 到工具调用这样才能在排查问题时把一次完整请求的所有环节串起来。限流策略我建议按业务线加模型维度做两级限流。业务线级别控制总预算模型级别控制并发数。降级策略要提前配置好当主模型超时或报错时自动切换到备用模型同时记录降级事件。我一般会配置一个“降级开关”在模型服务不稳定时可以手动切到更稳定的模型牺牲一点效果换可用性。注意Token 计量一定要在网关层做不要依赖模型供应商的账单。供应商的统计有延迟而且不同供应商的计量口径可能不一致。自己在网关层按请求记录才能做到实时准确。3.2 Agent 编排层的工具注册与执行机制Agent 的核心能力是调用工具。工具注册的设计直接决定了后续扩展的难易程度。我推荐的做法是每个工具定义为一个独立的模块包含四个部分工具描述、参数 Schema、执行函数、错误处理。工具描述要写得让模型能理解什么时候该用这个工具。我见过很多项目工具描述写得很随意导致模型该调用的时候不调用不该调用的时候乱调用。一个好的工具描述应该包含这个工具做什么、什么场景下使用、输入参数的含义、返回值的结构。参数 Schema 用 JSON Schema 定义这样既能给模型看也能用于参数校验。执行函数要保证幂等性因为 Agent 可能会重试。错误处理要区分“可重试错误”和“不可重试错误”前者返回给模型让它决定是否重试后者直接中断并上报。执行机制上我建议采用“计划-执行-观察”的循环模式。Agent 先根据当前上下文生成一个执行计划然后逐步执行每执行一步就把结果加入上下文再决定下一步。这个循环要有最大步数限制防止 Agent 陷入死循环。我一般设置最大 10 步超过就中断并返回当前结果。3.3 记忆系统的分层设计与检索优化记忆系统是 AI Native 架构里最容易被低估的部分。很多项目只做了简单的对话历史拼接结果就是上下文越来越长Token 消耗越来越大模型注意力还被稀释。我的做法是把记忆分成三层第一层是工作记忆就是当前对话的最近几轮消息直接拼在 Prompt 里。这一层控制长度一般保留最近 5 到 10 轮。第二层是会话记忆把整个会话的历史做摘要压缩存成一段简短的背景描述。当工作记忆不够用时把会话摘要加进去。第三层是长期记忆把重要的信息抽取出来存入向量库需要时通过语义检索召回。这一层的关键是“什么信息值得存”。我的经验是存三类用户偏好、事实性知识、历史决策记录。检索优化方面纯向量检索在很多时候不够准。我通常采用“向量检索加关键词检索”的混合策略先用向量召回一批候选再用关键词做精排。另外检索结果要加时间衰减越新的记忆权重越高。实测下来这套组合比单纯向量检索的准确率提升明显。3.4 可观测性与评估体系的搭建没有评估体系的 AI 系统就是在盲飞。我建议从项目第一天就搭建三个东西调用链路追踪、效果评估集、线上告警。调用链路追踪记录每次请求的完整轨迹输入是什么、模型返回什么、调用了哪些工具、每步耗时多少、最终结果是什么。这些数据一方面用于排查问题另一方面用于分析模型行为模式。效果评估集是一批标注好的测试用例覆盖主要业务场景。每次修改 Prompt、换模型、调整工具定义后都要跑一遍评估集看效果是提升还是下降。评估指标根据场景定分类任务看准确率生成任务看人工评分或自动评分。线上告警要关注几个关键指标模型调用失败率、平均响应延迟、Token 消耗异常、工具调用错误率。这些指标异常时能第一时间发现。4. 从零搭建的完整实操过程4.1 环境准备与基础依赖安装假设我们从零开始搭建一个 AI Native 的客服助手系统。基础环境需要Python 3.10 以上、一个向量数据库、一个关系数据库、一个 Redis 用于缓存和队列。# 创建项目目录结构 mkdir ai-native-cs cd ai-native-cs mkdir -p gateway agent memory tools observability config # 安装核心依赖 pip install fastapi uvicorn httpx pydantic pip install openai anthropic # 模型 SDK pip install chromadb # 向量库开发阶段用 pip install redis sqlalchemy psycopg2-binary pip install opentelemetry-api opentelemetry-sdk # 链路追踪目录结构的设计逻辑是gateway 放网关代码agent 放编排逻辑memory 放记忆系统tools 放工具定义observability 放追踪和评估config 放配置文件。每个目录职责单一方便后续拆分服务。配置文件我建议用 YAML 加环境变量覆盖的方式。敏感信息如 API Key 走环境变量其他配置走 YAML。这样本地开发和线上部署可以用同一套代码只换环境变量。4.2 LLM 网关的核心代码实现网关的核心是一个 FastAPI 应用对外暴露统一的 chat 接口。关键代码如下from fastapi import FastAPI, HTTPException from pydantic import BaseModel import httpx, time, uuid app FastAPI() class ChatRequest(BaseModel): model: str default messages: list tools: list [] temperature: float 0.7 max_tokens: int 2048 trace_id: str app.post(/v1/chat) async def chat(req: ChatRequest): trace_id req.trace_id or str(uuid.uuid4()) start time.time() # 配额检查 if not check_quota(req.model): raise HTTPException(429, quota exceeded) # 路由到供应商适配器 adapter get_adapter(req.model) try: result await adapter.call(req, trace_id) except TimeoutError: result await fallback_adapter.call(req, trace_id) # 记录 Token 消耗和耗时 record_metrics(trace_id, req.model, result.usage, time.time() - start) return result这里的关键设计是适配器模式。每个模型供应商实现一个适配器把统一请求格式转成供应商格式再把响应转回统一格式。这样增加新供应商时只需要加一个适配器不用改主流程。配额检查我一般用 Redis 做滑动窗口计数。每个业务线每分钟、每小时、每天的调用次数和 Token 数都做限制。超限时返回 429同时记录事件用于分析。4.3 Agent 编排与工具调用的落地Agent 编排的核心是一个循环构建上下文、调用模型、解析工具调用、执行工具、更新上下文。代码骨架如下async def run_agent(user_input, session_id, max_steps10): context build_context(user_input, session_id) for step in range(max_steps): response await llm_gateway.chat( messagescontext, toolsget_tool_schemas() ) if response.tool_calls: for call in response.tool_calls: tool get_tool(call.name) # 参数校验 validated tool.schema.validate(call.arguments) # 权限检查 check_permission(session_id, tool.name) # 执行 result await tool.execute(validated) context.append({ role: tool, tool_call_id: call.id, content: result }) else: # 没有工具调用返回最终结果 save_memory(session_id, context) return response.content return 达到最大步数限制请简化您的问题工具定义我推荐用装饰器注册的方式这样代码简洁且不容易漏注册register_tool( namequery_order, description根据订单号查询订单状态当用户询问订单进度时使用, schema{ type: object, properties: { order_id: {type: string, description: 订单号} }, required: [order_id] } ) async def query_order(order_id: str): # 实际查询逻辑 return {status: shipped, eta: 2026-01-15}4.4 记忆系统的实现与调优记忆系统的实现分三部分。工作记忆直接维护在会话上下文里每次请求时取最近 N 轮。会话记忆用一个后台任务定期做摘要把长对话压缩成短文本。长期记忆在每轮对话结束后抽取关键信息存入向量库。async def save_memory(session_id, context): # 抽取关键信息 facts await extract_facts(context) for fact in facts: embedding await get_embedding(fact) vector_store.add( idstr(uuid.uuid4()), embeddingembedding, metadata{session_id: session_id, fact: fact, ts: time.time()} ) # 更新会话摘要 summary await summarize(context) redis.set(fsession:{session_id}:summary, summary)检索时我一般取工作记忆加会话摘要加向量检索结果三部分拼接。向量检索的 top_k 设 5 到 10再加一个相似度阈值过滤低于阈值的不要。时间衰减用指数衰减半衰期设 7 天左右这样一周前的记忆权重降到一半。调优的关键是观察召回结果的质量。我会定期抽样检查检索出来的记忆是否真的和当前问题相关不相关的就调整抽取策略或检索参数。这个工作没有捷径就是持续观察和调整。5. 常见问题与排查技巧实录5.1 模型输出格式错误的排查思路这是最常见的问题。模型返回的 JSON 格式不对、工具调用参数缺失、返回内容包含多余的解释文字。排查思路是分三步先看 Prompt 里有没有明确要求格式再看模型能力是否匹配任务复杂度最后看有没有加输出校验和重试。我的经验是对于格式要求严格的场景不要指望模型一次就对。要在网关层加一个“格式校验加自动重试”的机制校验失败时把错误信息拼回 Prompt 让模型重新生成最多重试两次。实测下来加了重试后格式错误率从 8% 降到 1% 以下。注意重试时要控制 Token 消耗重试请求的 max_tokens 可以设小一点因为只需要修正格式不需要重新生成全部内容。5.2 Agent 陷入循环或调用错误工具的解决Agent 循环调用同一个工具、或者反复调用不存在的工具通常有三个原因工具描述不清晰、上下文里缺少必要信息、最大步数设置过大。排查时先看执行轨迹确认是在哪一步开始跑偏的。如果是工具描述问题就优化描述明确使用场景和参数含义。如果是上下文问题就在系统 Prompt 里补充背景信息。如果是步数问题就把 max_steps 调小强制 Agent 在有限步数内给出结果。我遇到过一个典型案例Agent 反复调用“查询用户信息”工具因为用户 ID 一直没拿到。后来发现是上一个工具返回的用户 ID 字段名和下一个工具要求的入参名不一致。这种问题在工具多了以后很常见解决办法是统一命名规范或者在工具层加字段映射。5.3 性能瓶颈的定位与优化AI Native 系统的性能瓶颈通常不在模型推理本身而在上下文构建和记忆检索。我做过一次性能分析一个请求的总耗时里模型推理占 40%上下文构建占 25%记忆检索占 20%工具执行占 15%。所以优化要从上下文和记忆入手。上下文构建的优化方向是减少不必要的拼接。比如工作记忆不要每次都全量拼接可以只拼最近几轮加摘要。记忆检索的优化方向是加缓存相同或相似的查询结果缓存起来避免重复检索。还有一个容易被忽略的点是并发控制。Agent 执行过程中可能有多个工具可以并行调用但很多实现是串行的。把无依赖的工具调用改成并行能显著降低总耗时。我用 asyncio.gather 做过这个优化平均响应时间下降了 30% 左右。5.4 常见问题速查表问题现象可能原因排查方法解决方案模型返回格式错误Prompt 不明确或模型能力不足检查 Prompt 和模型选型加格式校验和自动重试Agent 循环调用工具描述不清或上下文缺失查看执行轨迹优化描述或补充上下文响应延迟高上下文过长或检索慢分段计时压缩上下文或加缓存Token 消耗异常上下文膨胀或重试过多查看 Token 统计限制上下文长度和重试次数工具调用失败参数校验不通过或权限不足查看工具日志修正参数或调整权限记忆召回不准抽取质量差或检索参数不当抽样检查召回结果调整抽取策略和检索参数6. 一些实操后的个人体会这套架构我在两个项目里完整落地过最大的体会是AI Native 不是把模型加进系统而是把系统重新围绕模型来设计。这个转变最难的不是技术而是思维习惯。团队里做传统后端的同学一开始总想把模型输出转成确定的数据结构再走原有流程结果就是处处别扭。后来我们统一了认识模型输出就是不确定的系统要围绕这个不确定性来设计容错和校验而不是试图消除它。另一个体会是评估体系要尽早建。我第一个项目前两个月没做评估集全靠人工试用结果改 Prompt 改了两周效果时好时坏根本不知道是改好了还是改坏了。后来补了评估集每次改动跑一遍心里才有底。评估集不需要很大覆盖主要场景的几十条用例就够关键是要持续维护。最后分享一个小技巧给 Agent 加一个“思考日志”。让模型在调用工具前先输出一段简短的思考说明为什么要调用这个工具。这段思考不返回给用户只记录在日志里。排查问题时看这段思考能快速定位 Agent 的决策逻辑哪里出了问题。这个技巧帮我省了很多调试时间。
返回列表