乐于分享
好东西不私藏

Spring AI Alibaba 生产级落地指南:从消息契约、状态编排到多 Agent 体系化建设

Spring AI Alibaba 生产级落地指南:从消息契约、状态编排到多 Agent 体系化建设

Spring AI Alibaba 生产级落地指南:从消息契约、状态编排到多 Agent 体系化建设

面向 Java 技术栈的 AI 应用,真正困难的部分从来不是“把模型调通”,而是把一个会思考、会调用工具、会维护上下文、会跨服务协作的 Agent 系统,做成一个可治理、可扩展、可观测、可回放、可恢复的生产平台。
Spring AI Alibaba 的价值,也不在于“再封装一次大模型 API”,而在于它试图把 AI 应用从 Demo 代码提升为工程系统。


目录

  1. 1. 为什么很多 AI Demo 一上线就失控
  2. 2. 理解 Spring AI Alibaba:不是 SDK,而是一套生产框架
  3. 3. 先抓住主线:Message 才是 AI 应用的基础设施
  4. 4. 核心原理:ReAct、StateGraph 与可恢复执行
  5. 5. 生产架构设计:协议层、治理层、状态层三层拆解
  6. 6. 实战案例:构建一个生产级电商智能客服与履约协同系统
  7. 7. 代码骨架:从单 Agent 到可扩展工作流
  8. 8. 高并发与可扩展设计:真正决定系统上限的部分
  9. 9. 多 Agent 架构:什么时候该拆,怎么拆,拆完如何治理
  10. 10. 上下文工程:不是保存聊天记录,而是控制推理成本
  11. 11. 工具治理与安全护栏:避免 Agent 从“聪明”变成“危险”
  12. 12. 可观测、压测与故障演练:生产系统的生命线
  13. 13. 部署落地:Kubernetes、Redis、Nacos、消息队列如何协同
  14. 14. 常见误区与架构建议
  15. 15. 演进路线:从单体 AI 能力到企业级 Agent 平台
  16. 16. 总结

1. 为什么很多 AI Demo 一上线就失控

一个 AI Demo 从“能回答问题”走到“能承担业务”,中间隔着一整套工程鸿沟。很多团队在第一阶段进展很快:

  • • 接一个模型 SDK
  • • 拼一个 Prompt
  • • 注册几个工具
  • • 暴露一个聊天接口

本地效果通常不错,甚至看起来已经具备“智能客服”“智能助手”“流程自动化”的雏形。但只要开始接真实流量,问题会立刻暴露:

  • • 上下文越来越长,响应越来越慢,成本越来越高
  • • 工具调用不可控,模型偶发误用高风险操作
  • • 多轮对话中状态丢失,用户上一轮说过的话下一轮忘掉
  • • 服务重启后流程中断,退款审批、工单流转无法恢复
  • • 多实例部署后会话分散,某个请求打到新 Pod 就像“失忆”
  • • 流式输出链路不稳定,前端经常收到半截响应
  • • 高峰期模型限流、外部工具超时、重试风暴相互放大
  • • 日志只看到一堆 HTTP 请求,看不到一次 Agent 决策到底做了什么

本质上,这类系统失败的原因不是模型不够强,而是把一个具备状态、决策、工具、副作用、协作关系的复杂系统,当成了普通 HTTP 接口来设计。

所以我们要先统一一个认知:

生产级 AI 应用不是“模型调用系统”,而是“以模型为决策核心的状态化分布式应用”。

这个认知一旦立住,就能理解为什么 Spring AI Alibaba 值得认真看。它提供的不是几个便捷 API,而是一套让 Java 团队可以把 AI 应用纳入熟悉工程范式的基础设施。


2. 理解 Spring AI Alibaba:不是 SDK,而是一套生产框架

如果只从表面看,Spring AI Alibaba 似乎只是围绕 Spring AI 做了一层增强封装。但从生产落地角度看,它真正解决的是四类问题:

  1. 1. 统一模型与工具抽象
    让 ChatModel、Tool、Prompt、Memory、Message 等对象成为标准组件,而不是散落在业务代码里的临时拼装。
  2. 2. 统一 Agent 运行时
    不再把 Agent 理解成一个黑箱函数,而是理解为一个可编排、可中断、可恢复、可观测的状态机。
  3. 3. 统一工程集成方式
    把 AI 能力接入 Spring Boot、配置中心、服务发现、缓存、消息队列、可观测栈、Kubernetes。
  4. 4. 统一生产治理能力
    包括上下文控制、人工审批、工具权限、分布式会话、流式输出、指标埋点、失败恢复、成本治理。

从架构视角,可以把 Spring AI Alibaba 理解为下面这张图:

+-----------------------------------------------------------------------------------+
|                                 Business Applications                             |
|            智能客服 / 企业知识助手 / 工单助手 / 数据分析助手 / 流程协同            |
+-------------------------------------------+---------------------------------------+
|            Agent / Workflow Layer         |         Platform / Governance          |
|  ReactAgent / Sequential / Parallel       |  Observation / Eval / Admin / Studio   |
|  Routing / Supervisor / Loop / Graph      |  Prompt Ops / Policy / Human Review    |
+-------------------------------------------+---------------------------------------+
|                     Spring AI Alibaba Runtime & Integration                        |
|  Message / Tool / Hook / Saver / Memory / A2A / MCP / Streaming / StateGraph      |
+-----------------------------------------------------------------------------------+
|                            Spring AI Core Abstractions                             |
|               ChatModel / Embedding / VectorStore / Advisor / Tool                 |
+-----------------------------------------------------------------------------------+
|                     Model Providers & Enterprise Infrastructure                    |
|    DashScope / OpenAI / DeepSeek / Ollama / Redis / MQ / Nacos / K8s / OTEL       |
+-----------------------------------------------------------------------------------+

这套分层意味着一个重要事实:

Spring AI Alibaba 的最佳使用方式不是“在 Controller 里直接调 Agent”,而是把它当成 AI 运行时内核,再围绕业务域构建应用层架构。


3. 先抓住主线:Message 才是 AI 应用的基础设施

很多文章讲 Spring AI Alibaba,会从 Agent、Tool Calling、多 Agent 开始。但如果站在资深架构师视角,我更建议先抓住 Message

因为对生产系统而言,Message 不是“聊天消息 DTO”,而是三件事的统一载体:

  • • 协议载体:承载 user、assistant、system、tool 等角色语义
  • • 状态载体:承载一轮或多轮推理过程中的上下文快照
  • • 治理载体:承载审计、脱敏、回放、归档、成本统计、风险判定所需元数据

如果 Message 设计得太薄,后面所有能力都会变成散乱补丁。
如果 Message 设计得足够强,它就能支撑整套 AI 工程体系。

3.1 Message 为什么不是普通聊天记录

在一个生产级 Agent 系统里,一条消息往往至少包含以下信息:

维度
示例
作用
角色
system/user/assistant/tool
区分消息语义
文本内容
用户提问、模型回复、工具结果
构成推理上下文
结构化片段
tool call、thinking、JSON 输出
支撑流程编排
线程标识
sessionId/threadId
关联一次对话或工作流
幂等标识
messageId/requestId
防止重复处理
时间信息
创建时间、过期时间
生命周期管理
风险标签
PII、敏感指令、高风险工具
安全治理
追踪信息
traceId、spanId
链路观测
成本信息
token、模型名、时延
成本与性能分析
可见性标记
用户可见/系统可见
控制前端展示与内部决策

也就是说,Message 更像“AI 时代的事件对象”,而不仅仅是“聊天气泡”。

3.2 把 Message 看成协议层

所谓协议层,重点不是类名,而是边界清晰:

  • • 用户输入如何进入系统
  • • System Prompt 如何注入
  • • Tool Result 如何回写模型上下文
  • • 多 Agent 之间如何交换结果
  • • 前端如何消费流式 Token
  • • 审计系统如何复盘一次决策链路

如果协议不统一,就会出现几个典型问题:

  • • 某些工具返回的是自然语言,某些工具返回 JSON,模型无法稳定消费
  • • 多 Agent 交接时字段命名随意,路由逻辑越来越脆弱
  • • 流式响应和非流式响应不是同一种消息模型,前后端协议分裂
  • • 审批节点、回放节点、重试节点各自维护一套“上下文格式”

所以在项目一开始,就应该为消息建立明确契约。

3.3 一个生产可用的消息对象骨架

下面给一个工程里常见的消息对象设计骨架。它不依赖特定版本 API,重点是表达设计原则:

public record AiMessageEnvelope(
        String messageId,
        String sessionId,
        String traceId,
        MessageRole role,
        String model,
        String content,
        List<ContentBlock> blocks,
        Map<String, Object> metadata,
        Instant createdAt
)
 {
}

public
 enum MessageRole {
    SYSTEM,
    USER,
    ASSISTANT,
    TOOL
}

public
 sealed interface ContentBlock
        permits
 TextBlock, ToolCallBlock, ToolResultBlock, ReasoningBlock, JsonBlock {
}

public
 record TextBlock(String text) implements ContentBlock {
}

public
 record ToolCallBlock(
        String callId,
        String toolName,
        String argumentsJson
)
 implements ContentBlock {
}

public
 record ToolResultBlock(
        String callId,
        String toolName,
        String resultJson,
        boolean
 success
)
 implements ContentBlock {
}

public
 record ReasoningBlock(String summary) implements ContentBlock {
}

public
 record JsonBlock(String json) implements ContentBlock {
}

这个模型的关键点不在“字段够不够多”,而在以下几个能力:

  • • 内容与元数据分离
  • • 文本块与工具块分离
  • • 对前端展示内容与内部治理内容分别建模
  • • 为回放、审计、脱敏、幂等等非功能需求预留空间

3.4 Message 为什么决定系统可治理性

后续所有能力,本质都依赖 Message:

  • • 上下文压缩:对哪些消息做摘要、保留哪些消息,依赖 Message 分类
  • • Tool Calling:模型输出工具调用结构,依赖 Message block 解析
  • • Human-in-the-Loop:中断前的待审批动作,需要作为消息或状态持久化
  • • 多 Agent 编排:一个 Agent 的输出,要能成为另一个 Agent 的输入
  • • SSE 流式输出:增量 Token 需要映射为前端可消费的事件消息
  • • 审计与合规:敏感词、敏感字段、敏感工具,都要能挂接到消息维度

因此,理解 Spring AI Alibaba,真正应该从 Message 开始。
它是协议层、治理层、状态层的共同基底。


4. 核心原理:ReAct、StateGraph 与可恢复执行

4.1 ReAct 并不是“让模型自己循环”

ReAct 的表面形式是:

Thought -> Action -> Observation -> Thought -> ...

但在工程上,它不能只是 while(true) 调模型。
真正可上线的 ReAct 必须具备四个约束:

  • • 有明确的停止条件
  • • 有状态持久化能力
  • • 有工具调用边界控制
  • • 有异常恢复与人工接管机制

因此,ReAct 在生产里更适合被理解成一个有状态的条件图

4.2 StateGraph 的价值:把 Agent 变成可编排状态机

无论是单 Agent、审批流、专家协作,还是多阶段推理,本质上都可以抽象成:

  • • 节点:一次模型调用、一次工具调用、一次规则判断、一次人工审批
  • • 边:节点之间的转移关系
  • • 状态:节点运行过程中的上下文数据

这就是 Graph 运行时的价值。它带来的不是“画图更好看”,而是以下工程收益:

  • • 可以中断:某个节点前暂停,等待人工审批
  • • 可以恢复:进程重启后,从中断点继续
  • • 可以分流:根据状态条件走不同分支
  • • 可以回放:重建某次流程的执行轨迹
  • • 可以并行:多个子任务同时执行并合并结果

4.3 为什么生产系统必须支持可恢复执行

以退款助手为例,一次请求并不是“用户问一句,模型答一句”这么简单,它可能经历:

  1. 1. 意图识别
  2. 2. 订单查询
  3. 3. 退款资格校验
  4. 4. 风险判断
  5. 5. 人工审批
  6. 6. 发起退款
  7. 7. 发送通知

其中任何一步失败,都不应该让整条流程完全丢失。
如果系统无法恢复,只能让用户重新发起一遍,会造成:

  • • 体验差
  • • 数据不一致
  • • 重复副作用
  • • 审计链断裂

所以真正的生产级 Agent,必须具备“长流程、可中断、可恢复、可幂等”能力。

4.4 一个典型 StateGraph 工作流骨架

@Configuration
public
 class RefundWorkflowConfiguration {

    @Bean

    public
 CompiledGraph refundWorkflow(
            KeyStrategyFactory keyStrategyFactory,
            RefundIntentNode refundIntentNode,
            EligibilityNode eligibilityNode,
            RiskReviewNode riskReviewNode,
            HumanReviewNode humanReviewNode,
            SubmitRefundNode submitRefundNode,
            NotifyNode notifyNode
    )
 {
        StateGraph
 graph = new StateGraph(keyStrategyFactory)
                .addNode("intent", node_async(refundIntentNode))
                .addNode("eligibility", node_async(eligibilityNode))
                .addNode("risk_review", node_async(riskReviewNode))
                .addNode("human_review", node_async(humanReviewNode))
                .addNode("submit_refund", node_async(submitRefundNode))
                .addNode("notify", node_async(notifyNode))
                .addEdge(START, "intent")
                .addEdge("intent", "eligibility")
                .addEdge("eligibility", "risk_review")
                .addConditionalEdges(
                        "risk_review"
,
                        edge_async(state -> {
                            boolean
 needHumanReview = (boolean) state.value("needHumanReview").orElse(false);
                            return
 needHumanReview ? "manual" : "auto";
                        }),
                        Map.of(
                                "manual"
, "human_review",
                                "auto"
, "submit_refund"
                        )
                )
                .addEdge("human_review", "submit_refund")
                .addEdge("submit_refund", "notify")
                .addEdge("notify", END);

        return
 graph.compile(CompileConfig.builder()
                .interruptBefore("human_review")
                .build());
    }
}

注意,真正让这个图具备生产能力的,不是 addNode 这些 API,而是下面这些约束:

  • • 每个节点输入输出都可结构化
  • • 每个状态字段有合并策略
  • • 中断点可持久化
  • • 副作用节点有幂等保护
  • • 失败节点可重试或转人工

4.5 KeyStrategy 的工程意义

状态图一旦复杂,最容易出问题的不是路由,而是状态合并。

例如:

  • • messages 应该追加,而不是覆盖
  • • riskScore 应该覆盖,而不是累加
  • • toolResults 可能需要按 key 合并
  • • auditTrail 需要 append

一个常见设计如下:

@Bean
public
 KeyStrategyFactory keyStrategyFactory() {
    return
 () -> {
        Map<String, KeyStrategy> strategies = new HashMap<>();
        strategies.put("messages", new AppendStrategy());
        strategies.put("toolResults", new MergeStrategy());
        strategies.put("riskScore", new ReplaceStrategy());
        strategies.put("approved", new ReplaceStrategy());
        strategies.put("auditTrail", new AppendStrategy());
        strategies.put("costSnapshot", new ReplaceStrategy());
        return
 strategies;
    };
}

这实际上是在做一件非常重要的事:

把 AI 运行时里的“共享内存写入规则”显式化。

这能极大降低并发分支、长流程和多 Agent 协作下的数据混乱风险。


5. 生产架构设计:协议层、治理层、状态层三层拆解

围绕 Spring AI Alibaba 落地企业级系统时,我建议把架构拆成三层:

5.1 协议层:解决“怎么说”

协议层负责统一表达:

  • • 用户消息如何封装
  • • 模型消息如何落库
  • • 工具调用如何描述
  • • 工具返回如何结构化
  • • SSE 如何推送增量事件
  • • 多 Agent 如何交换上下文

协议层最重要的原则是:

  • • 不把自然语言字符串当作唯一边界
  • • 对 tool call、tool result、risk signal、summary、event 等建立结构化契约
  • • 让前端、后端、模型、工具、审计系统都面向同一套消息语义

5.2 治理层:解决“能不能放行”

治理层负责控制:

  • • 哪些工具能被调用
  • • 哪些参数需要脱敏
  • • 哪些操作必须人工审批
  • • 哪些请求需要降级
  • • 哪些会话应做摘要
  • • 哪些输出不能直接回用户

治理层本质上是在给模型自由度上“护栏”。
这层如果缺失,模型越强,风险反而越大。

治理层常见能力包括:

  • • 工具白名单与黑名单
  • • 按租户/角色/环境控制工具可见性
  • • Prompt 模板版本管理
  • • Token 预算与成本限额
  • • 输出 JSON Schema 校验
  • • 高风险动作审批
  • • 敏感信息脱敏与回显控制

5.3 状态层:解决“记住什么、何时恢复”

状态层是 AI 应用最容易被低估的部分。它不仅要记忆对话,还要维护:

  • • 当前流程进行到哪个节点
  • • 工具调用过哪些外部系统
  • • 哪些副作用已经提交
  • • 哪些消息已摘要
  • • 当前风险评分是多少
  • • 当前是否处于人工审批等待中
  • • 当前线程是否可以重入

一个成熟的状态层通常会区分三类状态:

状态类型
说明
存储建议
短期会话状态
最近消息、临时工具结果、流式输出缓存
Redis
长流程状态
工作流节点、审批状态、恢复点
Redis + DB
审计归档状态
完整消息链、工具入参与结果、风险动作
OLTP/日志系统/对象存储

5.4 三层之间的关系

用户请求
  ->
协议层:消息标准化、角色标注、事件封装
  ->
治理层:权限校验、工具筛选、预算控制、风险评估
  ->
状态层:加载线程上下文、恢复中断点、写回执行状态
  ->
Agent / Graph Runtime 执行
  ->
治理层:输出审查、脱敏、合规过滤
  ->
协议层:转为 SSE/HTTP/A2A 响应

这三层拆开后,系统会明显更稳:

  • • 协议问题不污染业务逻辑
  • • 治理逻辑不散落在每个 Tool 里
  • • 状态恢复不耦合 Controller

这就是从 Demo 进入工程系统的关键一步。


6. 实战案例:构建一个生产级电商智能客服与履约协同系统

为了把上面的原理落到地上,我们用一个真实感较强的案例贯穿全文。

6.1 业务目标

我们要做的不是一个“回答 FAQ 的聊天机器人”,而是一个具备以下能力的智能客服系统:

  • • 查询订单、物流、退款、发票、优惠券
  • • 基于知识库回答售前售后问题
  • • 能判断问题是否超出权限并转人工
  • • 对退款、改地址、补偿发券等动作走风险控制
  • • 与订单、支付、物流、会员、工单等服务协同
  • • 支持 Web/App/H5 多端流式会话
  • • 支持高峰活动期间扩容与降级

6.2 领域拆分

从领域上,我们不建议把所有能力都堆进一个大 Agent,而是至少拆成以下职责:

组件
职责
Conversation Gateway
接收会话请求,维护线程、鉴权、限流、SSE
Customer Service Agent
处理对话、解释、澄清、工具选择
Knowledge Agent
面向知识库检索与答案生成
Order Tool Service
查询订单、履约、发票等只读能力
Refund Workflow
有状态退款流程,含审批与幂等控制
Risk Engine
风险评分、策略判定、黑白名单
Audit Service
存储消息链、工具调用链、审批记录
Ops Platform
观测、回放、评估、灰度、Prompt 管理

6.3 参考部署拓扑

Client(Web/App)
    |
API Gateway / Ingress
    |
Conversation Gateway
    |
+-------------------------------+------------------------------+
|                               |                              |
|                        Customer Service Agent                |
|                               |                              |
|             +-----------------+-----------------+            |
|             |                                   |            |
|      Knowledge Agent                     Refund Workflow     |
|             |                                   |            |
|       Vector Store / KB              Risk Engine / Human Ops |
|                                                            |
+-------------------------------+------------------------------+
    |             |                |                |
 Order Service  Payment Service  Logistics Service  Ticket Service
    |
 Redis Cluster / MQ / Nacos / Observability / Audit Store

这个拓扑体现了两个原则:

  • • 对话与副作用分离
  • • 决策与执行分离

也就是说,Agent 可以负责理解与决策,但真正的业务副作用最好交给受控工作流和业务服务去完成。


7. 代码骨架:从单 Agent 到可扩展工作流

下面开始给出更偏生产骨架的示例。
示例重点不是追求“最少代码”,而是体现可扩展性。

7.1 Maven 依赖建议

<dependencyManagement>
    <dependencies>

        <dependency>

            <groupId>
com.alibaba.cloud.ai</groupId>
            <artifactId>
spring-ai-alibaba-bom</artifactId>
            <version>
${spring-ai-alibaba.version}</version>
            <type>
pom</type>
            <scope>
import</scope>
        </dependency>

    </dependencies>

</dependencyManagement>


<dependencies>

    <dependency>

        <groupId>
com.alibaba.cloud.ai</groupId>
        <artifactId>
spring-ai-alibaba-agent-framework</artifactId>
    </dependency>


    <dependency>

        <groupId>
com.alibaba.cloud.ai</groupId>
        <artifactId>
spring-ai-alibaba-graph-core</artifactId>
    </dependency>


    <dependency>

        <groupId>
com.alibaba.cloud.ai</groupId>
        <artifactId>
spring-ai-alibaba-starter-dashscope</artifactId>
    </dependency>


    <dependency>

        <groupId>
com.alibaba.cloud.ai</groupId>
        <artifactId>
spring-ai-alibaba-observation-extension</artifactId>
    </dependency>


    <dependency>

        <groupId>
org.springframework.boot</groupId>
        <artifactId>
spring-boot-starter-webflux</artifactId>
    </dependency>


    <dependency>

        <groupId>
org.springframework.boot</groupId>
        <artifactId>
spring-boot-starter-data-redis</artifactId>
    </dependency>


    <dependency>

        <groupId>
org.springframework.boot</groupId>
        <artifactId>
spring-boot-starter-validation</artifactId>
    </dependency>


    <dependency>

        <groupId>
io.github.resilience4j</groupId>
        <artifactId>
resilience4j-spring-boot3</artifactId>
    </dependency>


    <dependency>

        <groupId>
io.micrometer</groupId>
        <artifactId>
micrometer-tracing-bridge-otel</artifactId>
    </dependency>

</dependencies>

建议额外补齐:

  • • 向量检索相关依赖
  • • MQ 客户端
  • • 审计存储访问层
  • • 数据库访问组件

7.2 配置基线

server:
  port:
 8080

spring:

  application:

    name:
 customer-service-agent

  ai:

    dashscope:

      api-key:
 ${AI_DASHSCOPE_API_KEY}
      chat:

        options:

          model:
 qwen-max
          temperature:
 0.2
          top-p:
 0.8

  data:

    redis:

      timeout:
 2s
      lettuce:

        pool:

          max-active:
 128
          max-idle:
 32
          min-idle:
 8
      cluster:

        nodes:

          -
 redis-0:6379
          -
 redis-1:6379
          -
 redis-2:6379

resilience4j:

  circuitbreaker:

    instances:

      llmProvider:

        sliding-window-type:
 count_based
        sliding-window-size:
 20
        failure-rate-threshold:
 50
        wait-duration-in-open-state:
 30s
      toolRefund:

        sliding-window-size:
 20
        failure-rate-threshold:
 40
  timelimiter:

    instances:

      llmProvider:

        timeout-duration:
 25s
      toolRefund:

        timeout-duration:
 5s

management:

  endpoints:

    web:

      exposure:

        include:
 health,info,prometheus,metrics
  tracing:

    sampling:

      probability:
 1.0

7.3 会话请求模型

public record ChatRequest(
        @NotBlank String sessionId,
        @NotBlank String userId,
        @NotBlank String tenantId,
        @NotBlank String message,
        String channel,
        Map<String, Object> ext
)
 {
}

public
 record ChatResponse(
        String sessionId,
        String traceId,
        String answer,
        boolean
 escalatedToHuman
)
 {
}

7.4 工具接口不要直接暴露业务服务

很多项目第一版会这样写:

@Tool
public
 RefundResult refund(String orderId, BigDecimal amount) {
    return
 refundService.refund(orderId, amount);
}

这在生产里风险很高,因为工具边界过于粗暴。更好的方式是引入工具门面层:

@Component
public
 class RefundToolFacade {

    private
 final RefundEligibilityService eligibilityService;
    private
 final RefundCommandService refundCommandService;
    private
 final RiskFacade riskFacade;

    public
 RefundToolFacade(
            RefundEligibilityService eligibilityService,
            RefundCommandService refundCommandService,
            RiskFacade riskFacade
    )
 {
        this
.eligibilityService = eligibilityService;
        this
.refundCommandService = refundCommandService;
        this
.riskFacade = riskFacade;
    }

    @Tool(name = "check_refund_eligibility", description = """
            校验订单是否满足退款条件。
            当用户明确表达退款意图时调用。
            输入订单号,返回是否满足退款、原因、可退金额、是否需要人工审批。
            该工具不会执行实际退款。
            """)

    public
 RefundEligibilityResult checkEligibility(
            @ToolParam(description = "订单号")
 String orderId,
            ToolExecutionContext context
    )
 {
        UserPrincipal
 user = context.get(UserPrincipal.class);
        RefundEligibilityResult
 result = eligibilityService.check(user.userId(), orderId);
        RiskDecision
 riskDecision = riskFacade.evaluate(orderId, user.userId(), result.refundableAmount());
        return
 result.withRisk(riskDecision.level(), riskDecision.needHumanReview());
    }

    @Tool(name = "create_refund_ticket", description = """
            创建退款申请单,不直接执行打款。
            仅在用户确认后调用。
            返回退款申请单号与后续处理状态。
            """)

    public
 RefundTicketResult createRefundTicket(
            @ToolParam(description = "订单号")
 String orderId,
            @ToolParam(description = "退款原因")
 String reason,
            ToolExecutionContext context
    )
 {
        UserPrincipal
 user = context.get(UserPrincipal.class);
        return
 refundCommandService.createTicket(user.userId(), orderId, reason);
    }
}

这个设计的意义是:

  • • 读操作与写操作分离
  • • 风险判断前置
  • • 真正副作用动作从“直接退款”降级为“创建工单/申请单”
  • • 模型可调用的工具能力更加安全

7.5 Agent 装配时要把治理能力前置

@Configuration
public
 class CustomerServiceAgentConfiguration {

    @Bean

    public
 ReactAgent customerServiceAgent(
            ChatModel chatModel,
            ToolCallbackProvider toolCallbackProvider,
            RedisAgentStateStore redisAgentStateStore,
            HumanReviewPolicy humanReviewPolicy,
            ToolVisibilityPolicy toolVisibilityPolicy
    )
 {
        return
 ReactAgent.builder()
                .name("customer-service-agent")
                .model(chatModel)
                .systemPrompt("""
                        你是电商平台的生产级客服助手。
                        你的目标是优先帮助用户解决问题,但不得绕过业务规则。

                        规则如下:
                        1. 查询类请求可直接调用只读工具。
                        2. 对退款、改地址、补偿发券、账户信息修改等高风险动作,必须先确认并进入审批流程。
                        3. 对不确定信息不得编造,优先调用工具或知识库。
                        4. 如果工具失败,应向用户解释系统繁忙,并给出明确下一步,而不是重复无效调用。
                        5. 不得向用户暴露内部风险分或内部审核策略细节。
                        """
)
                .tools(toolCallbackProvider.getToolCallbacks())
                .toolSelectionStrategy(context ->
                        toolVisibilityPolicy.selectTools(
                                (String) context.get("tenantId"),
                                (String) context.get("intent"),
                                (String) context.get("riskLevel")
                        )
                )
                .hooks(
                        new
 SummarizationHook(SummarizationConfig.builder()
                                .maxMessages(24)
                                .compressionThreshold(6000)
                                .build()),
                        new
 HumanInTheLoopHook(HumanInTheLoopConfig.builder()
                                .sensitiveTools(
                                        "create_refund_ticket"
,
                                        "modify_address"
,
                                        "grant_coupon"

                                )
                                .build()),
                        new
 TokenBudgetHook(15000),
                        new
 OutputSchemaGuardHook()
                )
                .saver(redisAgentStateStore)
                .maxIterations(12)
                .build();
    }
}

这里真正体现“生产级”的点有四个:

  • • 不是把工具全部暴露给模型,而是可见性可控
  • • 不是等风险发生后拦截,而是在 Agent 层预设行为边界
  • • 不是只记录消息,而是显式配置状态存储
  • • 不是任由模型无限循环,而是限制迭代次数与预算

7.6 用应用服务而不是 Controller 直接驱动 Agent

@Service
public
 class ConversationApplicationService {

    private
 final ReactAgent customerServiceAgent;
    private
 final ConversationStateRepository conversationStateRepository;
    private
 final AuditService auditService;

    public
 ConversationApplicationService(
            ReactAgent customerServiceAgent,
            ConversationStateRepository conversationStateRepository,
            AuditService auditService
    )
 {
        this
.customerServiceAgent = customerServiceAgent;
        this
.conversationStateRepository = conversationStateRepository;
        this
.auditService = auditService;
    }

    public
 Flux<ChatEvent> stream(ChatRequest request) {
        String
 traceId = UUID.randomUUID().toString();

        RunnableConfig
 config = RunnableConfig.builder()
                .threadId(request.sessionId())
                .metadata(Map.of(
                        "tenantId"
, request.tenantId(),
                        "userId"
, request.userId(),
                        "traceId"
, traceId,
                        "channel"
, Objects.toString(request.channel(), "web")
                ))
                .build();

        conversationStateRepository.touch(request.sessionId(), request.userId(), traceId);
        auditService.recordUserInput(request.sessionId(), request.userId(), request.message(), traceId);

        return
 customerServiceAgent.stream(request.message(), config)
                .map(output -> ChatEventMapper.toEvent(output, traceId))
                .doOnNext(event -> auditService.recordEvent(request.sessionId(), traceId, event))
                .doOnError(ex -> auditService.recordFailure(request.sessionId(), traceId, ex))
                .doOnComplete(() -> conversationStateRepository.finishTurn(request.sessionId(), traceId));
    }
}

这种写法的好处是:

  • • Controller 只负责协议转换
  • • Agent 生命周期、审计、状态持久化由应用服务统一控制
  • • 方便后续接 WebSocket、SSE、A2A、MQ 等多个入口

7.7 SSE 接口要支持事件分型

@RestController
@RequestMapping("/api/ai/conversations")

public
 class ConversationController {

    private
 final ConversationApplicationService applicationService;

    public
 ConversationController(ConversationApplicationService applicationService) {
        this
.applicationService = applicationService;
    }

    @PostMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)

    public
 Flux<ServerSentEvent<String>> stream(@Valid @RequestBody ChatRequest request) {
        return
 applicationService.stream(request)
                .map(event -> ServerSentEvent.<String>builder()
                        .event(event.type())
                        .id(event.eventId())
                        .data(event.payload())
                        .build())
                .timeout(Duration.ofSeconds(90));
    }
}

建议至少区分这些事件:

  • • token:流式文本片段
  • • tool_call:模型发起工具调用
  • • tool_result:工具返回结果
  • • approval_required:进入人工审批
  • • complete:本轮完成
  • • error:发生异常

这样前端、客服工作台、审计平台都能消费同一条事件流,而不是只拿到一串字符串。


8. 高并发与可扩展设计:真正决定系统上限的部分

AI 系统一旦进入生产,高并发与可扩展设计的重要性通常会迅速超过 Prompt 调优。

8.1 性能瓶颈一般不止在模型

一次完整对话的时延,通常来自以下几个部分:

环节
典型问题
鉴权与线程加载
Redis 热点、线程状态读取慢
Prompt 构造
上下文膨胀、摘要不及时
模型调用
Provider 限流、首 Token 延迟高
工具调用
下游服务超时、串行调用过多
结果编排
JSON 解析和状态合并开销
流式输出
网关缓存、Nginx 超时、客户端断连
审计写入
同步落库放大 RT

因此,优化不能只盯模型。

8.2 先区分三类请求

高并发设计里,我建议先把流量按性质拆开:

  1. 1. 纯问答类
    无副作用、只读工具为主,可以追求低延迟。
  2. 2. 检索增强类
    需要知识库召回、重排、生成,重点优化召回链路与上下文压缩。
  3. 3. 事务协同类
    涉及退款、改地址、工单流转等副作用,重点是可靠性与幂等,不要盲目追求极低延迟。

不同类型请求不能用同一套 SLA 和资源池去管理。

8.3 并发模型建议:入口非阻塞,工具隔离,副作用异步化

一个比较稳妥的方案是:

  • • 网关层使用 WebFlux/SSE,减少连接阻塞
  • • 模型调用使用隔离线程池或虚拟线程
  • • 外部工具调用按域隔离线程池
  • • 耗时副作用流程通过 MQ 异步化
  • • 人工审批流程天然异步,不与用户对话线程强绑定

示意如下:

HTTP/SSE Request
  -> Reactive Gateway
  -> Agent Runtime
      -> LLM Pool
      -> Query Tool Pool
      -> Risk Tool Pool
      -> Approval Queue
      -> Async Workflow Queue

8.4 Redis 设计不要只存聊天记录

很多团队使用 Redis 时,只做一件事:存消息列表。
生产里远远不够。

更合理的 Redis Key 设计示例:

Key
用途
TTL
ai:session:{sessionId}:messages
最近 N 轮消息
24h
ai:session:{sessionId}:summary
摘要结果
24h
ai:workflow:{threadId}:state
Graph 状态快照
7d
ai:workflow:{threadId}:lock
并发执行锁
5min
ai:request:{requestId}:dedup
请求去重
10min
ai:tool:{toolCallId}:result
工具调用缓存
1h
ai:budget:{tenantId}:{day}
Token/费用预算
1d

这背后体现的是:
Redis 在 AI 系统里既是会话存储,也是流程状态缓存、幂等辅助、限流辅助、预算辅助。

8.5 幂等性是高并发下的第一原则

涉及工具副作用时,必须把幂等设计做在模型之外。

例如退款申请:

  • • 用户可能重复点击
  • • 网关可能超时重试
  • • Agent 可能重复推理
  • • 下游服务可能响应丢失

如果没有幂等保护,就会重复创建工单,甚至重复退款。

推荐方案:

public class IdempotentRefundCommandService {

    private
 final RefundTicketRepository refundTicketRepository;

    public
 RefundTicketResult createTicket(String userId, String orderId, String reason, String requestId) {
        return
 refundTicketRepository.findByRequestId(requestId)
                .orElseGet(() -> {
                    RefundTicket
 ticket = RefundTicket.create(userId, orderId, reason, requestId);
                    refundTicketRepository.save(ticket);
                    return
 RefundTicketResult.from(ticket);
                });
    }
}

关键点:

  • • 幂等键来自请求或工具调用 ID
  • • 幂等控制放在业务服务/数据库,不依赖模型“别重复调用”
  • • 审批前后都要考虑重复提交

8.6 缓存策略要做“语义层”和“工具层”分离

在 AI 应用里,缓存一般有三层:

  1. 1. 工具结果缓存
    例如物流轨迹、商品详情、运费规则等短时变化不大的只读数据。
  2. 2. 检索结果缓存
    对热门 FAQ 或常见意图的知识检索结果缓存。
  3. 3. 生成结果缓存
    只适合强模板、强约束、低个性化场景,不适合复杂个性化回复。

不要一上来就做“模型回答全量缓存”,否则命中率低、风险高、解释性差。

8.7 限流不能只做在 API Gateway

AI 系统至少要有四层限流:

  • • 用户级限流:防止单用户滥用
  • • 租户级限流:保护整体资源池
  • • 模型级限流:适配 Provider QPS/TPS 配额
  • • 工具级限流:保护内部核心系统

尤其是工具级限流非常重要。
否则大模型可能在高峰期把订单、物流、支付接口放大成压力源。

8.8 成本治理必须内建

高并发下,AI 成本问题本质上不是“单次调用贵”,而是:

  • • 多轮对话导致 token 指数放大
  • • 冗余工具描述拖长 prompt
  • • 低价值请求用了高阶模型
  • • 工具失败导致无意义重试
  • • 多 Agent 场景中多模型并行调用

建议至少内建以下能力:

  • • 按意图路由模型
  • • 按渠道设置预算
  • • 摘要与裁剪策略
  • • 工具动态筛选
  • • Prompt 模板去冗余
  • • 长尾低价值请求降级

9. 多 Agent 架构:什么时候该拆,怎么拆,拆完如何治理

9.1 不是任务一复杂就该上多 Agent

多 Agent 很容易被过度设计。
在不少场景下,一个设计良好的单 Agent + 工具集合就足够。

只有满足以下情况时,才建议拆分:

  • • 领域边界明显不同,例如售后、物流、财务、法务
  • • 工具集差异明显,全部暴露会造成模型混淆
  • • 不同子任务需要不同模型、不同 SLA、不同治理策略
  • • 需要跨团队独立演进和发布

9.2 六类常见协作模式

模式
适用场景
优势
风险
单 Agent
能力边界明确
简单直接
工具集合易膨胀
Sequential
固定处理流水线
可控性高
灵活性低
Parallel
并行取数/多路检索
延迟更优
结果合并复杂
Routing
根据意图路由专家
成本可控
路由错判会误分流
Supervisor
复杂任务拆解与协调
适合复杂推理
调度开销大
Graph
高定制、多条件流程
可恢复、强治理
工程复杂度高

9.3 一个更实用的原则:先领域化,再 Agent 化

不要先问“我有几个 Agent”。
应该先问:

  • • 我有哪些领域边界
  • • 哪些能力是解释型,哪些是事务型
  • • 哪些副作用必须走强规则
  • • 哪些组件需要独立扩缩容

通常更稳妥的演进路径是:

  1. 1. 先按领域拆工具与服务
  2. 2. 再把高复杂度领域演化为独立 Agent
  3. 3. 最后把长流程统一收敛到 Graph/Workflow

9.4 多 Agent 拆分后的治理重点

多 Agent 一旦拆出来,最容易失控的不是模型质量,而是“系统间协议不一致”。

必须统一的内容包括:

  • • 消息契约
  • • traceId 与 threadId 传递
  • • 工具与子 Agent 权限边界
  • • 统一错误码与恢复动作
  • • 统一审计字段
  • • 统一超时与重试原则

如果这些不统一,多 Agent 只会把复杂度从单进程扩散到整个系统。


10. 上下文工程:不是保存聊天记录,而是控制推理成本

很多人把上下文工程理解成“把聊天记录塞给模型”。
这只是最原始、也是最昂贵的做法。

10.1 生产里的上下文应该分层

建议至少拆成四层:

  1. 1. 会话层
    最近几轮用户与助手对话。
  2. 2. 任务层
    当前工作流状态、待确认动作、工具中间结果。
  3. 3. 记忆层
    用户画像、长期偏好、历史关键事实摘要。
  4. 4. 知识层
    外部知识库召回结果、规则说明、业务文档。

这四层不能简单拼成一个大 prompt,而应按场景装配。

10.2 摘要不是压缩文本,而是压缩状态

一个好的摘要策略,不只是“把历史消息变短”,而是保留后续推理真正需要的信息:

  • • 用户目标
  • • 已确认事实
  • • 已完成动作
  • • 未完成动作
  • • 风险决策结果
  • • 当前约束条件

例如:

public record ConversationSummary(
        String userGoal,
        List<String> confirmedFacts,
        List<String> pendingActions,
        List<String> riskNotes,
        Instant updatedAt
)
 {
}

这类结构化摘要,对后续推理远比自然语言长段总结更稳定。

10.3 上下文装配策略建议

一个常见的装配流程如下:

用户输入
  ->
意图识别
  ->
加载最近消息
  ->
加载结构化摘要
  ->
如果需要,加载用户长期记忆
  ->
如果需要,做知识检索
  ->
根据工具可见性筛选工具描述
  ->
构造最终 Prompt

这里最关键的能力不是“存”,而是“选”。
上下文工程本质上是一个装配与裁剪问题。

10.4 长对话下的实用建议

  • • 最近消息只保留必要窗口,不要无限追加
  • • 对工具返回做结构化摘要,而不是原样拼接
  • • 高频固定规则放 system prompt,不要轮轮重复拼接
  • • 对知识库结果先重排再注入
  • • 对跨天会话优先加载摘要,不直接加载全量历史

11. 工具治理与安全护栏:避免 Agent 从“聪明”变成“危险”

11.1 工具设计的第一原则:模型负责决策,不负责越权

大模型非常擅长“决定下一步可能是什么”,但它不应该直接拥有无限业务执行权限。

因此在企业系统中,我们一般会把工具分成三类:

类型
示例
原则
查询类工具
订单查询、物流查询、FAQ 检索
可相对开放
建议类工具
推荐优惠方案、生成工单草稿
可开放,但需校验输出
执行类工具
退款、改地址、发券、删账户
必须强约束

11.2 建议使用“意图识别 + 权限判断 + 工具可见性”三段式

public interface ToolVisibilityPolicy {
    List<ToolCallback> selectTools(String tenantId, String intent, String riskLevel);
}

@Component

public
 class DefaultToolVisibilityPolicy implements ToolVisibilityPolicy {

    private
 final ToolRegistry toolRegistry;

    public
 DefaultToolVisibilityPolicy(ToolRegistry toolRegistry) {
        this
.toolRegistry = toolRegistry;
    }

    @Override

    public
 List<ToolCallback> selectTools(String tenantId, String intent, String riskLevel) {
        return
 toolRegistry.list().stream()
                .filter(tool -> tool.supportsIntent(intent))
                .filter(tool -> tool.supportsTenant(tenantId))
                .filter(tool -> tool.allowForRiskLevel(riskLevel))
                .map(RegisteredTool::callback)
                .toList();
    }
}

这样做的价值非常大:

  • • 降低 prompt 体积
  • • 降低工具误选率
  • • 避免高风险工具暴露给不该用的请求

11.3 Human-in-the-Loop 不该只是一句“请人工确认”

人工审批真正要解决的是:

  • • 暂停在哪个节点
  • • 给审核员看到哪些上下文
  • • 审核超时怎么办
  • • 审核拒绝后如何回退
  • • 审核通过后如何恢复执行

因此,一套完整的人审链路至少应包含:

  • • 审批任务 ID
  • • 待审批动作摘要
  • • 风险标签
  • • 审批 SLA
  • • 审批结果回写接口
  • • 流程恢复机制

11.4 输出也要治理

很多团队只拦工具,不拦输出。
这同样危险。

需要治理的输出包括:

  • • 泄露内部策略
  • • 泄露其他用户信息
  • • 承诺超出公司政策的赔付
  • • 输出未校验的结构化数据
  • • 伪造工具执行结果

因此建议在最终输出前增加:

  • • 敏感词与敏感字段检查
  • • JSON Schema 验证
  • • 关键业务承诺规则校验
  • • 用户可见信息脱敏

12. 可观测、压测与故障演练:生产系统的生命线

一个没有观测的 Agent 系统,本质上不可运维。

12.1 至少观测四条链路

  1. 1. 对话链路
    用户输入、模型响应、流式事件、完成状态。
  2. 2. 工具链路
    哪个工具被调用、入参是什么、耗时多久、是否失败。
  3. 3. 工作流链路
    当前节点、状态变更、分支决策、中断恢复。
  4. 4. 成本链路
    用了哪个模型、多少 token、多少钱、失败重试次数。

12.2 推荐的指标体系

指标
含义
ai_requests_total
总请求数
ai_request_duration_seconds
请求耗时分布
ai_stream_first_token_seconds
首 Token 时延
ai_model_calls_total
模型调用次数
ai_model_errors_total
模型调用失败数
ai_tool_calls_total
工具调用次数
ai_tool_timeout_total
工具超时数
ai_human_review_total
进入人工审批次数
ai_workflow_resume_total
流程恢复次数
ai_token_input_total
输入 token 总量
ai_token_output_total
输出 token 总量
ai_cost_total
估算费用

12.3 Trace 才是排障关键

一次用户请求最好贯穿以下组件共享同一个 traceId

  • • 网关
  • • Agent Runtime
  • • Tool Service
  • • Graph Workflow
  • • 审批系统
  • • 审计系统

这样在排查“为什么这次退款失败”时,才能看到完整链路:

用户请求
  -> Agent 判定退款意图
  -> 调用资格校验工具
  -> 风险评分过高
  -> 进入人工审批
  -> 审批超时
  -> 返回用户稍后通知

没有链路追踪时,这些信息会散落在多个日志系统里,基本无法复盘。

12.4 压测不能只测 HTTP QPS

AI 系统压测至少要覆盖:

  • • 普通问答压测
  • • 知识检索压测
  • • 工具调用压测
  • • 流式连接数压测
  • • 审批中断恢复压测
  • • Provider 限流场景压测
  • • 下游服务超时场景压测

尤其要模拟这些异常:

  • • 模型 429/5xx
  • • Redis 短时抖动
  • • 工具服务 3s 到 10s 延迟飙升
  • • SSE 客户端主动断连
  • • Graph 恢复点读取失败
  • • 审批系统回调重复投递

12.5 故障演练要从第一天开始

建议建立最基础的故障演练清单:

  • • 模型超时后是否降级到低阶模型或人工兜底
  • • 工具调用失败后是否给出明确用户提示
  • • 重启后是否能恢复待审批流程
  • • Redis 故障时是否能切换只读能力
  • • 审批超时后是否能关闭流程并归档

AI 系统的可靠性不是写出来的,是演练出来的。


13. 部署落地:Kubernetes、Redis、Nacos、消息队列如何协同

13.1 K8s 部署基线

apiVersion: apps/v1
kind:
 Deployment
metadata:

  name:
 customer-service-agent
spec:

  replicas:
 4
  selector:

    matchLabels:

      app:
 customer-service-agent
  template:

    metadata:

      labels:

        app:
 customer-service-agent
      annotations:

        prometheus.io/scrape:
 "true"
        prometheus.io/port:
 "8080"
    spec:

      containers:

        -
 name: app
          image:
 registry.example.com/ai/customer-service-agent:1.0.0
          ports:

            -
 containerPort: 8080
          env:

            -
 name: AI_DASHSCOPE_API_KEY
              valueFrom:

                secretKeyRef:

                  name:
 ai-secrets
                  key:
 dashscope-api-key
            -
 name: SPRING_DATA_REDIS_CLUSTER_NODES
              value:
 redis-0:6379,redis-1:6379,redis-2:6379
            -
 name: SPRING_CLOUD_NACOS_DISCOVERY_SERVER_ADDR
              value:
 nacos-headless:8848
          resources:

            requests:

              cpu:
 "2"
              memory:
 "2Gi"
            limits:

              cpu:
 "4"
              memory:
 "4Gi"
          readinessProbe:

            httpGet:

              path:
 /actuator/health/readiness
              port:
 8080
          livenessProbe:

            httpGet:

              path:
 /actuator/health/liveness
              port:
 8080

几点建议:

  • • AI 服务不要把资源申请压得过低,否则高峰期 GC 和线程争用会非常明显
  • • SSE 场景要特别关注连接数上限和网关超时
  • • readiness 一定要覆盖关键依赖的可用性检查

13.2 Redis 在架构里的角色

Redis 通常承担:

  • • 会话上下文缓存
  • • 工作流状态恢复
  • • 去重锁与并发锁
  • • Token 预算与限流辅助
  • • 热点工具结果缓存

因此 Redis 对 AI 系统往往是核心依赖,而不是“可有可无的优化组件”。

13.3 Nacos 与 A2A 的价值

当多 Agent 或领域服务拆分后,Nacos 这类注册发现组件开始发挥价值:

  • • 发现不同 Agent 服务实例
  • • 动态路由到不同领域能力
  • • 支持按版本灰度
  • • 支持环境隔离

如果再结合 A2A 通讯能力,多 Agent 间调用可以更加标准化,而不是到处手写 HTTP Client。

13.4 MQ 不是为了炫架构,而是为了隔离副作用

以下场景建议天然异步化:

  • • 用户会话结束后的审计归档
  • • 长耗时知识处理
  • • 工单创建后的后续通知
  • • 风险复核回调
  • • 人工审批后的流程恢复事件

这样可以把对话链路 RT 和副作用链路解耦开。

13.5 Nginx 与 SSE 的配置注意点

很多流式问题不在应用,而在代理层:

location /api/ai/conversations/stream {
    proxy_http_version
 1.1;
    proxy_set_header
 Connection "";
    proxy_buffering
 off;
    proxy_cache
 off;
    proxy_read_timeout
 3600s;
    proxy_send_timeout
 3600s;
    chunked_transfer_encoding
 on;
}

关键点:

  • • 关闭 buffering
  • • 保持长连接
  • • 放宽读写超时

否则本地能流式,线上经常只剩“攒一坨再吐给前端”。


14. 常见误区与架构建议

14.1 误区一:把 Agent 当成 Service 方法

错误做法:

  • • Controller 直接调 Agent
  • • Agent 直接调数据库
  • • Tool 直接做副作用

后果是边界混乱,无法治理,无法恢复,无法审计。

建议:

  • • Agent 负责决策
  • • 应用服务负责编排
  • • 领域服务负责业务规则
  • • Workflow 负责长流程与恢复

14.2 误区二:把长对话历史全量喂给模型

后果:

  • • 成本失控
  • • 延迟升高
  • • 噪声信息干扰推理

建议:

  • • 结构化摘要
  • • 分层记忆
  • • 按意图装配上下文

14.3 误区三:看到多 Agent 就兴奋

后果:

  • • 系统拆得太早
  • • 观测、协议、审计跟不上
  • • 实际收益不如单 Agent + Graph

建议:

  • • 先单 Agent 做稳
  • • 再按领域与 SLA 拆分

14.4 误区四:让模型直接操作核心交易

后果:

  • • 风险不可控
  • • 副作用重复
  • • 审计链断裂

建议:

  • • 通过工具门面层隔离
  • • 高风险动作审批
  • • 副作用动作幂等

14.5 误区五:只有日志,没有回放

很多 AI 问题单看日志定位不了,因为模型推理、工具调用、状态流转是一个复合过程。

建议:

  • • 保留消息链
  • • 保留工具入参与结果摘要
  • • 保留工作流节点轨迹
  • • 建立最小化回放能力

15. 演进路线:从单体 AI 能力到企业级 Agent 平台

阶段一:能力验证期

目标:

  • • 快速验证用户价值
  • • 建立最小工具集合
  • • 跑通基础流式会话

架构特征:

  • • 单体 Spring Boot
  • • 单 Agent
  • • Redis 做基础会话缓存

阶段二:生产接入期

目标:

  • • 接业务真实流量
  • • 建立审计、限流、回放、降级
  • • 引入摘要与成本治理

架构特征:

  • • Agent + 应用服务分层
  • • Tool 门面层
  • • SSE + Redis 状态共享
  • • 基础观测与告警

阶段三:流程化协同期

目标:

  • • 把高风险、高价值动作流程化
  • • 建立审批与恢复能力
  • • 控制副作用与幂等

架构特征:

  • • 引入 StateGraph
  • • 引入人工审批与任务恢复
  • • 引入 MQ 异步事件

阶段四:多 Agent 平台期

目标:

  • • 按领域拆分能力
  • • 按团队独立演进
  • • 建立统一协议、观测、治理平台

架构特征:

  • • 多 Agent / A2A
  • • 注册发现
  • • Prompt Ops、Eval、灰度发布
  • • 统一策略中心与审计中心

16. 总结

Spring AI Alibaba 真正值得企业团队重视的地方,不是它把 Tool Calling、多 Agent、Graph、SSE 这些关键词堆在了一起,而是它给 Java 体系提供了一条更像“工程建设”而不是“脚本拼装”的 AI 落地路径。

如果要把全文压缩成一句话,我会这样总结:

Spring AI Alibaba 的核心价值,是把 AI 应用从“模型调用代码”提升为“有消息契约、有状态编排、有治理护栏、有恢复能力”的生产系统。

真正的生产级落地,建议你重点抓住以下几件事:

  1. 1. 先把 Message 当成基础设施来设计,而不是聊天记录
  2. 2. 用协议层、治理层、状态层拆开 AI 系统复杂度
  3. 3. 让 Agent 负责决策,让工作流负责副作用和恢复
  4. 4. 把高并发、幂等、预算、限流、观测当成第一天就要建设的能力
  5. 5. 多 Agent 不要为了概念而拆,而要为了领域边界、SLA 和治理边界而拆

最后再强调一次,AI 应用的难点并不是“模型会不会回答”,而是:

  • • 回答是否可信
  • • 工具是否安全
  • • 状态是否可恢复
  • • 成本是否可控
  • • 系统是否经得住高峰和故障

如果你的目标不是做一个 Demo,而是做一个能进入生产、能承担真实业务责任的 AI 系统,那么 Spring AI Alibaba 的正确打开方式一定不是“从 Prompt 开始”,而是“从架构开始”。


附:生产落地检查清单

在项目上线前,建议至少逐项确认以下内容:

架构与边界

  • • 是否区分了协议层、治理层、状态层
  • • 是否区分了对话决策与业务副作用
  • • 是否避免 Controller 直接驱动复杂 Agent 逻辑

消息与状态

  • • 是否有统一 Message 契约
  • • 是否支持会话状态共享
  • • 是否支持长流程中断与恢复
  • • 是否对关键动作做了幂等控制

工具与安全

  • • 是否有工具白名单/可见性控制
  • • 是否对高风险工具做审批或规则保护
  • • 是否对最终输出做脱敏与合规校验

性能与成本

  • • 是否做上下文裁剪与摘要
  • • 是否做用户级、租户级、模型级、工具级限流
  • • 是否有模型路由与降级策略
  • • 是否有 Token/费用预算控制

可观测与运维

  • • 是否有模型、工具、流程、成本四类指标
  • • 是否有全链路 traceId
  • • 是否可回放典型会话与工作流
  • • 是否做过限流、超时、断连、恢复等故障演练

这份清单做完,才算真正进入“生产级”。

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-06-04 11:21:37 HTTP/1.1 GET : https://www.yeyulingfeng.com/a/702319.html
  2. 运行时间 : 0.260456s [ 吞吐率:3.84req/s ] 内存消耗:4,939.09kb 文件加载:145
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=641cfd7dfa92e2b9d2ab3984f498a96e
  1. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/autoload_static.php ( 6.05 KB )
  7. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/ralouphie/getallheaders/src/getallheaders.php ( 1.60 KB )
  10. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  11. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  12. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  13. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  14. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  15. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  16. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  17. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  18. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  19. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/guzzlehttp/guzzle/src/functions_include.php ( 0.16 KB )
  21. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/guzzlehttp/guzzle/src/functions.php ( 5.54 KB )
  22. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  23. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  24. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  25. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/provider.php ( 0.19 KB )
  26. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  27. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  28. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  29. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/common.php ( 0.03 KB )
  30. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  32. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/alipay.php ( 3.59 KB )
  33. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  34. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/app.php ( 0.95 KB )
  35. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/cache.php ( 0.78 KB )
  36. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/console.php ( 0.23 KB )
  37. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/cookie.php ( 0.56 KB )
  38. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/database.php ( 2.48 KB )
  39. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/filesystem.php ( 0.61 KB )
  40. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/lang.php ( 0.91 KB )
  41. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/log.php ( 1.35 KB )
  42. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/middleware.php ( 0.19 KB )
  43. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/route.php ( 1.89 KB )
  44. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/session.php ( 0.57 KB )
  45. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/trace.php ( 0.34 KB )
  46. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/view.php ( 0.82 KB )
  47. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/event.php ( 0.25 KB )
  48. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  49. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/service.php ( 0.13 KB )
  50. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/AppService.php ( 0.26 KB )
  51. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  52. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  53. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  54. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  55. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  56. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/services.php ( 0.14 KB )
  57. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  58. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  59. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  60. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  61. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  62. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  63. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  64. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  65. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  66. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  67. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  68. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  69. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  70. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  71. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  72. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  73. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  74. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  75. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  76. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  77. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  78. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  79. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  80. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  81. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  82. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  83. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  84. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  85. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  86. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  87. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/Request.php ( 0.09 KB )
  88. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  89. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/middleware.php ( 0.25 KB )
  90. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  91. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  92. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  93. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  94. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  95. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  96. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  97. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  98. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  99. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  100. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  101. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  102. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  103. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/route/app.php ( 3.94 KB )
  104. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  105. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  106. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/controller/Index.php ( 9.87 KB )
  108. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/BaseController.php ( 2.05 KB )
  109. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  110. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  111. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  112. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  113. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  114. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  115. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  116. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  117. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  118. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  119. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  120. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  121. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  122. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  123. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  124. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  125. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  126. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  127. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  128. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  129. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  130. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  131. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  132. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  133. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  134. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  135. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/controller/Es.php ( 3.30 KB )
  136. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  137. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  138. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  139. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  140. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  141. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  142. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  143. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  144. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/runtime/temp/c935550e3e8a3a4c27dd94e439343fdf.php ( 31.50 KB )
  145. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.001136s ] mysql:host=127.0.0.1;port=3306;dbname=wenku;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.001626s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000736s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000680s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.001382s ]
  6. SELECT * FROM `set` [ RunTime:0.000608s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.001555s ]
  8. SELECT * FROM `article` WHERE `id` = 702319 LIMIT 1 [ RunTime:0.005913s ]
  9. UPDATE `article` SET `lasttime` = 1780543297 WHERE `id` = 702319 [ RunTime:0.064881s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 64 LIMIT 1 [ RunTime:0.004031s ]
  11. SELECT * FROM `article` WHERE `id` < 702319 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.001297s ]
  12. SELECT * FROM `article` WHERE `id` > 702319 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.031572s ]
  13. SELECT * FROM `article` WHERE `id` < 702319 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.014879s ]
  14. SELECT * FROM `article` WHERE `id` < 702319 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.008147s ]
  15. SELECT * FROM `article` WHERE `id` < 702319 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.004767s ]
0.262164s