尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

企业级 Agent 中台建设方案:从架构设计到代码实战

发布时间:2026/9/24 23:43:26

资讯中心
01
ARTICLE

企业级 Agent 中台建设方案:从架构设计到代码实战

企业级 Agent 中台建设方案:从架构设计到代码实战
一、为什么企业需要 Agent 中台大模型出现之后很多团队第一时间做的事情是把 LLM 包装成一个接口然后让各业务线直接调用。这个做法在 Demo 阶段没问题但一旦进入企业级落地问题会迅速暴露出来。最典型的问题包括每个业务系统各自维护 Prompt、各自接模型、各自实现工具调用导致模型调用成本不可控、Prompt 质量参差不齐、知识库和权限无法统一管理、安全合规无法落地。更麻烦的是当一个业务方踩坑之后其他团队往往还在重复踩同样的坑。Agent 中台要解决的核心问题本质上不是「把模型能力开放出去」而是把「如何安全、稳定、可观测、可复用地使用大模型与工具」这件事沉淀成一套平台能力。它的定位可以概括为四点统一接入屏蔽底层模型供应商差异统一模型路由、计费、限流和降级策略。能力复用把工具、知识库、提示词、记忆等能力沉淀为可组装的标准组件。安全合规统一权限、审计、敏感信息拦截和企业策略管控。工程闭环为 Agent 提供可观测、可评估、可回滚的运行环境而不是让 Agent 成为「黑盒脚本」。下面我会从总体架构出发逐步展开领域模型、模型网关、Agent 运行时、工具管理、记忆管理、知识库接入以及可观测性建设并给出可直接落地的 Java Spring Boot 代码实战。文中代码基于 JDK 17 与 Spring Boot 3 编写关键部分可以直接复用到企业项目中。二、总体架构设计企业级 Agent 中台通常划分为控制面、数据面和运行面三大部分。控制面负责 Agent 配置、工具注册、权限授权与发布审批数据面承接模型网关、记忆、知识库与可观测数据运行面则是真正执行 Agent 推理循环的部分。一个可落地的整体架构如下。flowchart TB subgraph Access[接入层] A1[业务系统 / 工作流引擎] A2[对话应用 / 客服系统] A3[运营管理后台] end subgraph Control[控制面] B1[Agent 配置中心] B2[工具注册中心] B3[权限与审批] B4[提示词与版本管理] end subgraph Runtime[运行面] C1[Agent 运行时] C2[模型网关] C3[工具执行器] C4[知识库服务] C5[记忆与会话服务] end subgraph Infra[基础设施] D1[LLM 供应商] D2[企业内部 API] D3[向量数据库] D4[Redis] D5[MySQL] D6[可观测性平台] end A1 -- C1 A2 -- C1 A3 -- B1 B1 -- C1 B2 -- C3 B3 -- C1 B4 -- B1 C1 -- C2 C1 -- C3 C1 -- C4 C1 -- C5 C2 -- D1 C3 -- D2 C4 -- D3 C5 -- D4 B1 -- D5 C1 -- D6 C2 -- D6架构上有一条重要原则业务系统不直接对接模型和工具而是统一经过 Agent 运行时的编排。这样权限校验、审计记录、模型降级、成本统计等横切能力才能在同一个点收敛。模型供应商的替换、企业内部 API 的变更都不会影响业务方的接入契约。三、核心领域模型设计领域模型是中台的地基。建议从 Agent、Tool、Session、Memory 四个核心概念切入建模。下面给出最精简但足以支撑生产环境扩展的核心实体定义。public class Agent { private String agentId; private String name; private String systemPrompt; private String modelId; private ListString toolIds; private Integer maxSteps; private Double temperature; private MemoryConfig memoryConfig; // getter / setter 省略 } public class MemoryConfig { private Integer recentMessageLimit; private boolean enableSummary; private Integer summaryThresholdTokens; } public class Session { private String sessionId; private String agentId; private String userId; private String status; }其中Agent是「一个可发布的智能体配置」Session对应一次用户会话MemoryConfig控制记忆策略。把 Agent 与 Session 分离是为了让同一个 Agent 可以被多个用户、多个会话复用同时记忆与状态又互不污染。四、模型网关统一接入、路由与降级模型网关是中台的第一个关键组件。它需要屏蔽 OpenAI、Azure、通义、DeepSeek 等不同供应商的协议差异同时提供统一的路由、超时、重试、限流和降级能力。核心抽象是一个统一的客户端接口。public interface ChatModelClient { ChatResponse chat(ChatRequest request); } public record ChatRequest( ListMessage messages, Double temperature, Integer maxTokens ) { public static ChatRequest of(ListMessage messages) { return new ChatRequest(messages, 0.7, 2048); } } public record ChatResponse( Message message, Usage usage, String model, Long latencyMs ) { } public record Usage(int promptTokens, int completionTokens) { }为了统一不同供应商的结构内部消息模型需要同时支持普通文本和工具调用。下面是一个兼顾多轮对话与 function calling 的消息模型。public class Message { private String role; private String content; private String toolCallId; private ListToolCall toolCalls; public static Message system(String content) { return new Message(system, content, null, List.of()); } public static Message user(String content) { return new Message(user, content, null, List.of()); } public static Message assistant(String content, ListToolCall toolCalls) { return new Message(assistant, content, null, toolCalls); } public static Message tool(String toolCallId, String result) { return new Message(tool, result, toolCallId, List.of()); } public Message() { } public Message(String role, String content, String toolCallId, ListToolCall toolCalls) { this.role role; this.content content; this.toolCallId toolCallId; this.toolCalls toolCalls; } public String getRole() { return role; } public String getContent() { return content; } public String getToolCallId() { return toolCallId; } public ListToolCall getToolCalls() { return toolCalls; } } public class ToolCall { private String id; private String name; private String arguments; public ToolCall() { } public ToolCall(String id, String name, String arguments) { this.id id; this.name name; this.arguments arguments; } public String getId() { return id; } public String getName() { return name; } public String getArguments() { return arguments; } }网关本身的实现依赖于配置驱动的路由表。模型 ID 对应到具体供应商实现这样在代码层面只需要维护一个 Map新增供应商不需要改动业务逻辑。Component public class ModelGateway { private final MapString, ChatModelClient clients; private final ModelRouteProperties routeProperties; public ModelGateway(ListChatModelClient clientList, ModelRouteProperties routeProperties) { this.routeProperties routeProperties; this.clients new HashMap(); for (ChatModelClient client : clientList) { clients.put(client.supplier(), client); } } public ChatResponse route(String modelId, ChatRequest request) { ModelRoute route routeProperties.route(modelId); if (route null) { throw new IllegalArgumentException(unknown model: modelId); } ChatModelClient client clients.get(route.supplier()); if (client null) { throw new IllegalStateException(no client for supplier: route.supplier()); } long start System.currentTimeMillis(); try { ChatResponse response client.chat(request); return new ChatResponse( response.message(), response.usage(), modelId, System.currentTimeMillis() - start ); } catch (ModelTimeoutException ex) { ModelRoute fallback route.fallback(); if (fallback ! null) { return route(fallback.modelId(), request); } throw ex; } } }这里的关键点是降级逻辑发生在网关层而不是 Agent 运行时层。Agent 只需要声明自己使用哪个模型 ID至于这个模型背后是哪个供应商、超时后是否切到备用模型都由网关统一处理。配合限流器可以在成本激增时快速保护预算。五、Agent 运行时ReAct 循环与工具调用Agent 运行时是整个中台的心脏。大多数生产环境采用 ReAct 模式即「思考—行动—观察」循环用一个最大步数上限避免无限执行。下面是核心循环的完整实现。Component public class AgentRuntime { private final ModelGateway modelGateway; private final ToolExecutor toolExecutor; public AgentRuntime(ModelGateway modelGateway, ToolExecutor toolExecutor) { this.modelGateway modelGateway; this.toolExecutor toolExecutor; } public AgentResult run(Agent agent, String userInput, String sessionId) { ListMessage messages new ArrayList(); messages.add(Message.system(agent.getSystemPrompt())); messages.add(Message.user(userInput)); int maxSteps agent.getMaxSteps() null ? 10 : agent.getMaxSteps(); for (int step 0; step maxSteps; step) { ChatRequest request new ChatRequest( messages, agent.getTemperature(), 4096 ); ChatResponse response modelGateway.route(agent.getModelId(), request); Message assistantMessage response.message(); messages.add(assistantMessage); if (assistantMessage.getToolCalls() null || assistantMessage.getToolCalls().isEmpty()) { return AgentResult.success( assistantMessage.getContent(), messages, step 1 ); } for (ToolCall call : assistantMessage.getToolCalls()) { String toolResult toolExecutor.execute( agent.getAgentId(), call.getName(), call.getArguments() ); messages.add(Message.tool(call.getId(), toolResult)); } } throw new AgentStoppedException( agent exceeded max steps: maxSteps ); } }这段代码是 Agent 运行时的最小闭环。需要注意几点生产化细节其一每一轮都把完整消息历史回传给模型短期可用、长期要配合记忆压缩其二工具调用必须串行执行多个工具调用之间通常存在数据依赖直接并行会破坏因果链其三最大步数是硬性兜底同时还应辅以 token 预算和成本预算。public record AgentResult( String answer, ListMessage messages, int steps ) { public static AgentResult success(String answer, ListMessage messages, int steps) { return new AgentResult(answer, messages, steps); } } public class AgentStoppedException extends RuntimeException { public AgentStoppedException(String message) { super(message); } }为了让工具调用能够在异步场景下被取消可以把循环中的阻塞点改为可中断的 Future但这属于进阶优化。对于大多数企业内部 Agent上面这段同步循环配合线程池已经足够稳定。六、工具管理注册、鉴权与限流工具是 Agent 的「手脚」也是安全风险最高的地方。一个企业级中台不能允许 Agent 随意调用任意接口必须经过严格的注册、鉴权与限流。首先定义统一的工具契约。public interface Tool { String name(); String description(); String inputSchema(); String execute(MapString, Object arguments); }工具注册中心除了保存工具实现还要维护「Agent 与工具的绑定关系」。一个 Agent 只能用被显式授权的工具这是最小权限原则的落地方式。Component public class ToolRegistry { private final MapString, Tool tools new ConcurrentHashMap(); public void register(Tool tool) { tools.put(tool.name(), tool); } public Tool get(String name) { Tool tool tools.get(name); if (tool null) { throw new ToolNotFoundException(unknown tool: name); } return tool; } public ListTool resolveForAgent(Agent agent) { return agent.getToolIds().stream() .map(this::get) .toList(); } }鉴权是工具执行的前置步骤。下面用一个执行器在真正调用工具前完成「Agent 是否有权调用」「当前用户是否有权调用」「该工具是否被限流」三重校验。Component public class ToolExecutor { private final ToolRegistry toolRegistry; private final ToolPermissionService permissionService; private final RateLimiter rateLimiter; public ToolExecutor(ToolRegistry toolRegistry, ToolPermissionService permissionService, RateLimiter rateLimiter) { this.toolRegistry toolRegistry; this.permissionService permissionService; this.rateLimiter rateLimiter; } public String execute(String agentId, String toolName, String arguments) { Tool tool toolRegistry.get(toolName); if (!permissionService.canAgentUse(agentId, toolName)) { return forbidden(toolName); } if (!rateLimiter.tryAcquire(toolName)) { return rateLimited(toolName); } MapString, Object args JsonUtils.parseMap(arguments); try { String result tool.execute(args); if (result.length() 8000) { result result.substring(0, 8000); } return result; } catch (Exception ex) { return tool execution failed: ex.getMessage(); } } private String forbidden(String toolName) { return {\error\:\tool not allowed: toolName \}; } private String rateLimited(String toolName) { return {\error\:\tool rate limited: toolName \}; } }这里有一个容易被忽略的细节工具执行异常不应该让整个 Agent 崩溃。把异常转成结构化文本回传给模型模型可以据此调整下一步行动。同时对返回结果做长度截断防止单个工具返回超大内容撑爆上下文窗口。下面给出一个真实的业务工具示例演示如何把企业内部订单查询接口封装成标准 Tool。Component public class OrderQueryTool implements Tool { private final OrderService orderService; public OrderQueryTool(OrderService orderService) { this.orderService orderService; } Override public String name() { return query_order; } Override public String description() { return 根据订单号查询订单状态与物流信息; } Override public String inputSchema() { return { type: object, properties: { orderId: {type: string, description: 订单号} }, required: [orderId] } ; } Override public String execute(MapString, Object arguments) { String orderId (String) arguments.get(orderId); Order order orderService.findByOrderId(orderId); return JsonUtils.toJson(order); } }七、记忆与会话管理记忆能力决定了一个 Agent 能否在多轮对话中保持连贯以及能否在长期运行中积累上下文。生产环境中不建议把全部历史无脑塞给模型而是要区分短期工作记忆与长期语义记忆。短期记忆以 Redis 为核心保存最近 N 条消息当消息长度超过阈值时触发摘要压缩把早期对话压缩成一段摘要继续参与后续推理。Component public class MemoryService { private final StringRedisTemplate redisTemplate; private final MessageCompressor compressor; public MemoryService(StringRedisTemplate redisTemplate, MessageCompressor compressor) { this.redisTemplate redisTemplate; this.compressor compressor; } public void append(String sessionId, Message message) { String key sessionKey(sessionId); redisTemplate.opsForList().rightPush(key, JsonUtils.toJson(message)); } public ListMessage recent(String sessionId, int limit) { String key sessionKey(sessionId); ListString values redisTemplate.opsForList().range(key, -limit, -1); if (values null || values.isEmpty()) { return List.of(); } return values.stream() .map(v - JsonUtils.parse(v, Message.class)) .toList(); } public void maybeCompress(String sessionId, int thresholdTokens) { ListMessage all recent(sessionId, 200); int totalTokens all.stream().mapToInt(this::countTokens).sum(); if (totalTokens thresholdTokens) { String summary compressor.summarize(all.subList(0, all.size() / 2)); redisTemplate.delete(sessionKey(sessionId)); redisTemplate.opsForList().rightPush(sessionKey(sessionId), JsonUtils.toJson(Message.system(对话摘要 summary))); } } private String sessionKey(String sessionId) { return agent:memory: sessionId; } private int countTokens(Message message) { return message.getContent() null ? 0 : message.getContent().length() / 4; } }长期记忆则通常落入向量库把值得记住的事实、用户偏好做向量化存储后续通过语义检索注入上下文。关于这块内容下一节知识库会给出检索侧的核心实现。八、知识库与 RAG 接入企业 Agent 的很多问题必须基于内部文档回答而模型预训练数据里没有这些内容所以 RAG 是中台的标准能力。一个可用的知识库服务至少包含「切片—向量化—召回—重排」四个环节。下面是检索侧的核心实现。Service public class KnowledgeBaseService { private final EmbeddingClient embeddingClient; private final VectorStore vectorStore; private final Reranker reranker; public KnowledgeBaseService(EmbeddingClient embeddingClient, VectorStore vectorStore, Reranker reranker) { this.embeddingClient embeddingClient; this.vectorStore vectorStore; this.reranker reranker; } public ListChunk search(String collection, String query, int topK) { float[] queryVector embeddingClient.embed(query); ListChunk candidates vectorStore.search(collection, queryVector, topK * 3); ListChunk ranked reranker.rerank(query, candidates); return ranked.stream().limit(topK).toList(); } public String buildContext(String collection, String query, int topK) { ListChunk chunks search(collection, query, topK); StringBuilder context new StringBuilder(); for (int i 0; i chunks.size(); i) { context.append(【资料 ).append(i 1).append(】) .append(chunks.get(i).content()) .append(\n); } return context.toString(); } }召回之后还需要一个「组装提示词」的环节把检索结果和用户问题一起交给模型。这里的关键是明确告诉模型「只能基于给定资料回答资料不足时说明无法回答」从而降低幻觉。Component public class RagPromptBuilder { public String build(String systemPrompt, String context, String userQuestion) { return %s 以下是检索到的参考资料 %s 请基于上述参考资料回答用户问题。如果资料中没有足够信息请明确说明无法回答不要编造事实。 用户问题%s .formatted(systemPrompt, context, userQuestion); } }为了让知识库对 Agent 透明通常会把知识库检索也封装成一个 Tool。这样 Agent 可以在需要时主动调用search_knowledge_base工具而不是每轮都强制注入全部上下文成本和准确率都能兼顾。九、可观测性与评估体系Agent 比普通接口更难排障因为它的行为是非确定性的。一个生产级中台必须能回答三个问题这条请求走了哪条工具链、每一步花了多少时间、最终答案的质量如何。建议从链路追踪、指标统计与质量评估三个维度建设。一次 Agent 执行对应一条 Trace内部每个推理步、每次工具调用都是一个 Span。下面给出核心埋点数据结构的定义方式。public record AgentSpan( String traceId, String agentId, String sessionId, String spanType, String name, long startTimeMs, long latencyMs, int promptTokens, int completionTokens, String status ) { } Component public class ObservabilityService { private final MeterRegistry meterRegistry; public ObservabilityService(MeterRegistry meterRegistry) { this.meterRegistry meterRegistry; } public void recordAgentRun(AgentSpan span) { meterRegistry.timer(agent.run.duration, agentId, span.agentId(), status, span.status()) .record(span.latencyMs(), TimeUnit.MILLISECONDS); meterRegistry.counter(agent.run.tokens, type, prompt, agentId, span.agentId()) .increment(span.promptTokens()); meterRegistry.counter(agent.run.tokens, type, completion, agentId, span.agentId()) .increment(span.completionTokens()); } }指标之外还要建立离线评估集。把真实业务问题整理成「问题—参考答案—评估要点」的数据集每次 Agent 配置变更后自动跑一遍统计答案准确率、工具调用正确率和首轮解决率。评估不是一次性的动作而是中台发布流程的一部分应该和代码 CI 一样常态化运行。建议在企业内部建立一张评估维度表至少覆盖以下六项任务成功率Agent 是否在最大步数内完成目标。工具调用准确率调用的工具名称和参数是否正确。幻觉率是否编造了资料中不存在的事实。首轮正确率是否需要人工介入才得到正确结果。平均步数与成本是否存在明显的推理浪费。延迟分布P95、P99 是否满足业务 SLA。十、工程落地与演进路线建设 Agent 中台不建议一开始就追求大而全。更稳妥的方式是沿着「统一接入 — 标准化运行时 — 能力沉淀 — 智能编排」四步演进。第一阶段统一模型网关。先解决模型接入和成本控制问题让所有团队通过统一 API 使用模型这是收益最快、风险最低的一步。第二阶段标准化 Agent 运行时。沉淀 ReAct 循环、工具调用、会话管理的标准实现业务方只需要配置 Prompt 和工具清单。第三阶段能力组件化。把知识库、记忆、工具权限做成可插拔组件让不同 Agent 按需组合。第四阶段智能编排与自主决策。引入多 Agent 协作、任务规划与自动评估这一步依赖前三步的工程基础不能跳级。有四个实践原则值得反复强调权限永远前置Agent 能调用的工具、能访问的知识库范围必须在执行前校验而不是事后审计。成本必须可观测每一步的 token 消耗、工具调用次数都要记录否则中台很快会被成本反噬。一切皆可降级模型超时降级、工具失败降级、知识库不可用降级都要有明确策略不能让 Agent 整体不可用。评估进入发布流程没有评估集的 Agent 配置不允许直接上线评估应和代码审查同等重要。十一、总结企业级 Agent 中台的本质是把大模型和工具能力从「项目里的散装胶水代码」升级为「可治理、可复用、可观测的平台能力」。它的建设难点不在单点技术而在于把模型网关、Agent 运行时、工具权限、记忆系统、知识库和可观测性串成一个稳定的闭环。本文给出的代码覆盖了核心主链路模型网关负责统一路由与降级Agent 运行时承载 ReAct 循环工具执行器完成鉴权与限流记忆服务管理短期上下文知识库服务提供 RAG 能力可观测服务记录链路与指标。把这些组件逐步落地并接入评估流程就能支撑起一个真正生产可用的 Agent 中台。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。