在实际企业级 AI 应用开发中我们正面临一个关键转折点。传统的单体 AI 模型调用或简单的 API 集成已经难以支撑日益复杂的业务智能体AI Agent场景。当智能体需要处理多轮对话、记忆管理、工具调用、安全合规检查以及自动化工作流时一个松散的、临时拼凑的技术栈会迅速成为开发和维护的噩梦。无论是招聘平台上涌现的“智能体工程师”岗位还是社区中基于 LangGraph、Ollama 构建本地智能体的尝试都指向同一个核心诉求我们需要一个专为 AI 智能体服务设计的新架构。这种新架构的核心目标是解决智能体服务的可靠性、可观测性、可编排性和安全性。它不是一个具体的框架而是一套设计原则和组件规范。本文将从一个工程实践者的视角探讨如何从零开始基于主流技术栈以 Spring AI 和 Golang 为例设计和实现一个面向生产环境的企业级 AI 智能体服务架构。我们将重点关注架构分层、核心组件实现、安全合规的自动化检测以及如何利用 LangGraph 的思想进行工作流编排最终构建一个既灵活又健壮的智能体服务平台。1. 理解 AI 智能体服务与传统 AI 调用的本质区别在深入架构之前必须厘清“AI 智能体服务”与“一次性 AI 模型调用”的根本不同。这决定了架构设计的出发点。1.1 智能体是有状态的会话实体一次简单的模型调用如 ChatGPT API通常是无状态的输入问题获取回答交互结束。而智能体是一个有状态的会话实体。它需要维护对话历史记忆理解上下文并在多轮交互中逐步达成目标。例如一个订票智能体需要记住用户的出发地、目的地、时间偏好并在后续对话中引用这些信息。技术映射这意味着服务层必须提供会话Session管理和记忆Memory存储能力。记忆又可分为短期记忆当前对话窗口和长期记忆向量数据库存储的持久化知识。1.2 智能体具备规划与执行能力智能体不应只是“问答机”它应能根据目标制定计划Plan并调用工具Tools执行具体动作。例如用户说“帮我总结上周销售报告并发邮件给经理”智能体需要分解为1. 鉴权2. 从数据库获取销售数据3. 调用总结模型4. 调用邮件发送 API。技术映射这要求架构中有明确的规划器Planner和工具执行器Tool Executor组件。规划器解析用户意图并生成执行计划可能是一个有向无环图执行器则负责安全、可靠地调用内部或外部工具。1.3 智能体服务需应对复杂工作流许多业务场景是线性的“问答-执行”无法覆盖的需要基于状态的条件分支、循环和并行处理。这正是 LangGraph 等框架解决的问题将智能体行为定义为一张图Graph节点是状态或动作边是流转条件。技术映射架构需要支持工作流引擎或状态机能够定义、持久化和执行复杂的智能体工作流。这对于实现自动化客服、合规审核等场景至关重要。1.4 企业级智能体的核心约束安全与合规在企业环境下智能体不能“信口开河”。其输出必须符合公司政策、行业法规和数据安全要求。这包括但不限于防止敏感信息泄露PII、过滤不当内容、确保工具调用的权限可控、审计所有操作日志。技术映射必须在架构的输入/输出层和工具调用层嵌入强大的安全合规中间件。例如所有用户输入和模型输出都需经过内容安全过滤所有工具调用前需进行权限校验所有交互过程需被完整审计。2. 设计分层架构从概念到组件基于以上理解我们提出一个通用的四层 AI 智能体服务架构。这个架构清晰分离了关注点便于团队协作和独立演进。[ 客户端 ] - [ 网关/接入层 ] - [ 智能体服务层 ] - [ 能力支撑层 ] | [ 基础设施层 ]2.1 网关/接入层这是流量的统一入口负责协议转换、认证鉴权、限流熔断、日志收集等非业务功能。关键组件API Gateway处理 HTTP/WebSocket 请求路由到不同的智能体服务。认证鉴权验证用户身份Token、SSO并将身份信息传递给下游。限流与熔断防止单个智能体或模型被过度调用保障系统稳定性。请求/响应日志记录原始交互数据用于审计和调试。2.2 智能体服务层这是架构的核心承载智能体的“大脑”。它本身可以再细分为多个子模块。关键组件会话管理器创建、维护、销毁会话。每个会话关联唯一的会话 ID 和记忆存储。记忆模块短期记忆通常保存在内存或 Redis 中存储最近的对话轮次。长期记忆使用向量数据库如 Milvus, Pinecone, pgvector存储和检索相关知识片段。规划与编排引擎意图识别解析用户输入判断其意图是问答、执行任务还是闲聊。规划器根据意图和上下文生成执行计划。计划可以是一个简单的工具调用序列也可以是一个复杂的工作流图。工作流引擎执行由规划器生成的复杂工作流。可以使用 LangGraph 的核心思想进行实现管理状态流转。工具执行器安全地执行规划中指定的工具。工具可以是内部函数、REST API、数据库查询等。模型网关统一对接不同的 AI 模型提供商如 OpenAI, Anthropic, 本地部署的 Llama 等提供降级、重试、负载均衡策略。2.3 能力支撑层为智能体服务层提供通用的、可复用的能力。关键组件工具库所有可被智能体调用的工具在此注册和管理。每个工具需明确定义输入输出 Schema、所需权限、执行方法。知识库管理向量的嵌入、存储和检索逻辑为长期记忆提供支持。安全合规中间件内容安全集成敏感词过滤、Prompt 注入检测、输出内容合规性检查。权限校验在工具调用前校验当前会话用户是否有权执行该操作。审计服务记录所有关键操作会话创建、工具调用、模型请求、安全拦截满足合规审计要求。2.4 基础设施层提供底层的存储、计算和通信能力。关键组件数据库会话、审计日志、缓存短期记忆、向量数据库、消息队列异步任务、对象存储文件处理。3. 核心实现基于 Spring AI 与 Golang 的混合实践不同的技术栈在架构中各有所长。Spring AI 生态成熟适合快速构建 Java 侧的智能体服务Golang 则以高性能和并发能力见长适合实现安全合规中间件、工具执行器等对性能要求高的组件。下面我们看一些关键组件的实现示例。3.1 使用 Spring AI 构建智能体服务核心Spring AI 提供了对 AI 模型和智能体范式的抽象是快速实现服务层的不错选择。第一步环境与依赖准备创建一个 Spring Boot 3.x 项目引入必要依赖。!-- pom.xml 片段 -- dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-openai-spring-boot-starter/artifactId !-- 使用最新稳定版本 -- /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-data-redis/artifactId /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency第二步定义会话与记忆实体// Session.java Data Entity public class Session { Id private String sessionId; private String userId; private LocalDateTime createdAt; private LocalDateTime lastActiveAt; Transient private ListMessage conversationHistory; // 短期记忆可从Redis加载 } // Message.java Data public class Message { private String role; // user, assistant, system, tool private String content; private MapString, Object properties; // 可存储工具调用ID等元数据 }第三步实现一个基础的对话智能体服务Service public class BasicChatAgentService { private final ChatClient chatClient; // Spring AI 注入的模型客户端 private final RedisTemplateString, Object redisTemplate; private final SessionRepository sessionRepo; private static final String CONVERSATION_KEY_PREFIX conv:; public AgentResponse chat(String sessionId, String userInput) { // 1. 获取或创建会话 Session session sessionRepo.findById(sessionId).orElse(createNewSession(sessionId)); // 2. 从Redis加载短期记忆最近10轮对话 ListMessage history loadConversationHistory(sessionId); history.add(new Message(user, userInput)); // 3. 构建Prompt包含系统指令和历史 Prompt prompt new Prompt(new SystemPrompt(你是一个有帮助的助手。), history); // 4. 调用模型 ChatResponse response chatClient.call(prompt); // 5. 处理响应保存到记忆 String assistantReply response.getResult().getOutput().getContent(); history.add(new Message(assistant, assistantReply)); saveConversationHistory(sessionId, history); // 6. 更新会话活跃时间 session.setLastActiveAt(LocalDateTime.now()); sessionRepo.save(session); return new AgentResponse(assistantReply, sessionId); } private ListMessage loadConversationHistory(String sessionId) { // 从Redis反序列化List return (ListMessage) redisTemplate.opsForValue().get(CONVERSATION_KEY_PREFIX sessionId); } }3.2 使用 Golang 实现安全合规自动化检测系统对于安全合规这种对性能和实时性要求高的模块Golang 是更佳选择。我们实现一个独立的安全服务。第一步定义检测规则与审计结构// security/types.go package security type CheckType string const ( CheckTypeSensitiveWord CheckType SENSITIVE_WORD CheckTypePII CheckType PII CheckTypePromptInject CheckType PROMPT_INJECTION ) type SecurityCheckRequest struct { SessionID string json:session_id Content string json:content Direction string json:direction // INPUT or OUTPUT UserID string json:user_id } type SecurityCheckResult struct { Passed bool json:passed CheckType CheckType json:check_type,omitempty RiskLevel string json:risk_level,omitempty // HIGH, MEDIUM, LOW Details string json:details,omitempty Suggestion string json:suggestion,omitempty }第二步实现核心检测引擎// security/engine.go package security import ( regexp strings sync ) type Engine struct { sensitiveWords []string piiPatterns []*regexp.Regexp mu sync.RWMutex } func NewEngine() *Engine { e : Engine{} // 初始化敏感词库可从数据库或文件加载 e.sensitiveWords []string{违规词A, 违规词B} // 编译PII正则表达式身份证、手机号、邮箱等 e.piiPatterns []*regexp.Regexp{ regexp.MustCompile(\b\d{17}[\dXx]\b), // 简化版身份证 regexp.MustCompile(\b1[3-9]\d{9}\b), // 手机号 } return e } func (e *Engine) CheckInput(req SecurityCheckRequest) ([]SecurityCheckResult, bool) { var results []SecurityCheckResult allPassed : true // 1. 敏感词检测 if result : e.checkSensitiveWord(req.Content); !result.Passed { results append(results, result) allPassed false } // 2. PII检测仅对输入或特定场景的输出做 if req.Direction INPUT { if result : e.checkPII(req.Content); !result.Passed { results append(results, result) allPassed false } } // 3. Prompt注入检测简化示例 if e.isPotentialPromptInjection(req.Content) { results append(results, SecurityCheckResult{ Passed: false, CheckType: CheckTypePromptInject, RiskLevel: HIGH, Details: 检测到可能的Prompt注入模式, }) allPassed false } return results, allPassed } func (e *Engine) checkSensitiveWord(content string) SecurityCheckResult { e.mu.RLock() defer e.mu.RUnlock() lowerContent : strings.ToLower(content) for _, word : range e.sensitiveWords { if strings.Contains(lowerContent, strings.ToLower(word)) { return SecurityCheckResult{ Passed: false, CheckType: CheckTypeSensitiveWord, RiskLevel: HIGH, Details: 包含敏感词: word, Suggestion: 请修改表述, } } } return SecurityCheckResult{Passed: true} }第三步提供 gRPC/HTTP 服务供智能体服务层调用// server/main.go package main import ( encoding/json log net/http your-project/security ) func main() { engine : security.NewEngine() http.HandleFunc(/api/v1/security/check, func(w http.ResponseWriter, r *http.Request) { var req security.SecurityCheckRequest if err : json.NewDecoder(r.Body).Decode(req); err ! nil { http.Error(w, err.Error(), http.StatusBadRequest) return } results, passed : engine.CheckInput(req) resp : map[string]interface{}{ passed: passed, results: results, } w.Header().Set(Content-Type, application/json) json.NewEncoder(w).Encode(resp) // 异步记录审计日志 go auditLog(req, results, passed) }) log.Fatal(http.ListenAndServe(:8081, nil)) }3.3 集成 LangGraph 思想实现工作流编排LangGraph 的核心是将智能体行为建模为状态图。我们可以借鉴其思想用代码定义工作流。定义状态和节点// WorkflowState.java - 代表工作流的全局状态 Data public class WorkflowState { private String sessionId; private String userInput; private String currentStep; private MapString, Object context; // 存储中间结果如工具调用结果 private boolean isComplete; private String finalOutput; } // WorkflowNode.java - 代表图中的一个节点一个步骤 public interface WorkflowNode { String getName(); WorkflowState execute(WorkflowState state) throws Exception; }实现具体节点// 工具调用节点 Component public class ToolCallNode implements WorkflowNode { Autowired private ToolExecutor toolExecutor; Override public String getName() { return call_tool; } Override public WorkflowState execute(WorkflowState state) { String toolName (String) state.getContext().get(next_tool); Object toolInput state.getContext().get(tool_input); // 调用Golang安全服务进行检查同步HTTP调用或异步消息 // SecurityCheckResult result securityClient.check(state.getUserInput()); // if (!result.isPassed()) { ... 处理违规 ... } Object toolOutput toolExecutor.execute(toolName, toolInput); state.getContext().put(tool_output, toolOutput); state.setCurrentStep(process_result); return state; } } // 条件判断节点 Component public class ConditionalNode implements WorkflowNode { Override public String getName() { return check_condition; } Override public WorkflowState execute(WorkflowState state) { boolean conditionMet evaluateCondition(state); String nextStep conditionMet ? step_a : step_b; state.setCurrentStep(nextStep); return state; } }定义工作流图并执行Service public class WorkflowEngine { private MapString, WorkflowNode nodes; private MapString, ListString edges; // 图结构key:节点名value:下一个可能节点列表 PostConstruct public void init() { // 初始化节点和边可以配置在数据库中 nodes Map.of( start, new StartNode(), call_tool, new ToolCallNode(), check_condition, new ConditionalNode(), step_a, new StepANode(), step_b, new StepBNode(), end, new EndNode() ); edges Map.of( start, List.of(call_tool), call_tool, List.of(check_condition), check_condition, List.of(step_a, step_b), step_a, List.of(end), step_b, List.of(end) ); } public WorkflowState executeWorkflow(String workflowName, WorkflowState initialState) { WorkflowState currentState initialState; String currentNode start; while (!end.equals(currentNode) !currentState.isComplete()) { WorkflowNode node nodes.get(currentNode); if (node null) { throw new RuntimeException(Unknown node: currentNode); } currentState node.execute(currentState); // 根据当前状态和业务逻辑决定下一个节点简化版 // 实际应根据节点执行结果和边定义进行路由 currentNode decideNextNode(currentNode, currentState); } return currentState; } }4. 关键配置与部署考量4.1 配置管理智能体服务涉及大量配置模型 API Key、向量数据库连接、工具端点、安全规则等。必须将这些配置外置。# application.yml (Spring Boot) spring: ai: openai: api-key: ${OPENAI_API_KEY} chat: options: model: gpt-4-turbo-preview redis: host: ${REDIS_HOST:localhost} port: 6379 agent: memory: short-term: max-turns: 10 long-term: vector-db: type: milvus host: ${MILVUS_HOST} collection: agent_memory security: service-endpoint: http://security-service:8081/api/v1/security/check enable-input-check: true enable-output-check: true4.2 服务间通信Spring AI 服务与 Golang 安全服务之间通过 RESTful API 或 gRPC 通信。生产环境需考虑超时、重试和熔断。// 使用 Resilience4j 实现熔断和重试 Bean public CircuitBreaker securityServiceCircuitBreaker() { CircuitBreakerConfig config CircuitBreakerConfig.custom() .failureRateThreshold(50) .waitDurationInOpenState(Duration.ofMillis(1000)) .slidingWindowSize(2) .build(); return CircuitBreaker.of(securityService, config); } CircuitBreaker(name securityService, fallbackMethod securityCheckFallback) public SecurityCheckResult callSecurityService(SecurityCheckRequest request) { // 调用Golang安全服务 return webClient.post() .uri(securityEndpoint) .bodyValue(request) .retrieve() .bodyToMono(SecurityCheckResult.class) .block(); } private SecurityCheckResult securityCheckFallback(SecurityCheckRequest request, Throwable t) { // 降级策略记录日志返回一个“通过”但标记为降级的结果或根据业务决定拒绝 log.error(Security service call failed, using fallback, t); return new SecurityCheckResult(true, FALLBACK, LOW, Security check bypassed due to service failure); }5. 运行验证与排查清单5.1 端到端验证流程启动服务依次启动基础设施Redis、数据库、Golang 安全服务、Spring AI 智能体服务。创建会话调用POST /api/sessions创建新会话获取sessionId。发送消息调用POST /api/chat带上sessionId和用户消息。观察链路检查智能体服务日志确认收到请求、加载记忆、调用模型。检查安全服务日志确认输入内容被检测。检查 Redis确认对话历史被保存。检查数据库确认审计日志被记录。触发工具调用发送需要工具调用的指令如“查询北京天气”观察工具执行器日志和返回结果。触发安全拦截发送包含敏感词的输入观察响应是否被安全服务拦截并返回合规提示。5.2 核心排查清单当智能体服务出现异常时可按以下顺序排查问题现象可能原因检查点解决方案请求返回“服务不可用”或超时1. 网关/负载均衡故障2. 智能体服务进程挂掉3. 依赖的基础设施Redis、DB不可用1. 检查服务健康端点/actuator/health2. 查看服务进程状态和日志3. 检查 Redis、数据库连接状态1. 重启故障服务2. 检查资源使用率CPU、内存3. 检查网络连通性对话没有历史上下文失忆1. 会话 ID 传递错误或丢失2. Redis 连接失败或内存已满3. 记忆存储/读取逻辑有 Bug1. 确认请求头/参数中的sessionId正确2. 检查 Redis 监控尝试直接读写测试 Key3. 在记忆读写方法中加入调试日志1. 修复客户端传参2. 清理 Redis 或扩容3. 修复代码逻辑确保序列化正确工具调用失败1. 工具未正确注册或初始化2. 工具执行时网络/权限错误3. 工具输入参数不符合 Schema1. 检查工具执行器的初始化日志2. 查看工具调用时的详细错误日志网络异常、403等3. 对比工具期望的 Schema 和实际传入的参数1. 检查工具配置和依赖2. 检查网络策略和认证信息3. 在规划阶段增加参数校验安全合规检查误拦截或漏拦截1. 敏感词库未更新2. 安全服务调用失败导致降级通过3. 检测规则有误1. 检查安全服务的规则加载日志2. 查看熔断器状态确认是否触发了降级3. 用测试用例验证规则准确性1. 更新词库和规则2. 调整熔断策略或修复安全服务3. 优化检测算法和正则表达式工作流卡在某个节点1. 节点执行抛出未处理异常2. 状态流转逻辑有误进入死循环3. 上下文数据丢失或格式错误1. 查看工作流引擎的异常日志2. 打印每个节点执行前后的状态3. 检查上下文Map中的关键数据1. 修复节点代码的异常处理2. 调试状态流转逻辑增加边界条件判断3. 确保上下文数据的序列化/反序列化正确6. 生产环境最佳实践与扩展方向6.1 稳定性与性能异步化将耗时的操作如向量检索、复杂工具调用异步化通过消息队列如 Kafka处理避免阻塞主请求线程。缓存策略对频繁访问且变化不频繁的数据如工具元信息、安全规则进行多级缓存。限流与降级在网关和模型网关层实施严格的限流并为非核心功能如高级记忆检索配置降级策略。监控与告警对关键指标进行监控会话 QPS、平均响应时间、模型调用错误率、工具调用成功率、安全拦截率。设置告警阈值。6.2 安全与合规深化动态规则加载安全规则应支持热更新无需重启服务即可生效。审计日志全链路追踪确保从用户输入到最终输出的每一个环节包括内部模型调用、工具调用都有唯一的追踪 ID便于事后审计和问题复现。数据脱敏在日志和审计记录中对敏感信息如手机号、邮箱进行脱敏处理。权限最小化每个工具应定义清晰的权限标签智能体在执行前必须通过统一的权限服务校验。6.3 智能体能力扩展技能Skills市场参考“人工智能skills怎么安装到ai智能体上”的社区需求可以设计一个技能注册中心。开发者可以将封装好的工具技能发布到市场智能体管理员可以像安装插件一样为智能体启用技能。多智能体协作架构可以扩展为支持多个智能体协同工作。例如一个负责理解需求一个负责专业查询一个负责生成报告通过消息总线进行协作。持续学习与优化将智能体与用户的交互数据经脱敏和授权后用于微调模型或优化工作流路径形成闭环。6.4 架构演进思考服务网格集成在微服务架构下可以考虑使用服务网格如 Istio来管理智能体服务与其他服务间的通信获得更细粒度的流量控制、可观测性和安全策略。Serverless 化对于波动性大的智能体场景可以将无状态的模型调用、工具执行函数部署为 Serverless 函数按需伸缩降低成本。标准化与开源逐步将核心组件如安全中间件、工作流引擎、模型网关抽象成标准模块考虑开源以吸收社区反馈并推动技术标准化。构建企业级 AI 智能体服务是一个系统工程其难点不在于调用某个最新的模型 API而在于如何将分散的能力对话、记忆、规划、工具、安全有机整合形成一个稳定、可靠、可管理、可进化的服务架构。本文提供的分层设计、混合技术栈实现和工程化实践旨在为此提供一个坚实的起点。在实际落地时务必从最简单的核心链路开始逐步验证和叠加复杂度并始终将系统的可观测性和安全性置于优先考虑的位置。