02 总体架构:一套应用两副面孔

第 2 / 13 章
02 总体架构:一套应用两副面孔

第二章讲架构。这一章回答三个问题:模块怎么分层、评估监控为什么不碰主链路、一套代码怎么同时伺候「笔记本演示」和「客户内网生产」。

四层结构

自底向上分四层,边界刻意切得很硬:

接入层    API 网关(SpringBoot):鉴权、限流、输入校验、SSE 流式输出
业务层    biz-platform(自研闭源)
          ├─ RAG 模块:ingestion、语义分块、多路检索、RRF 重排
          ├─ 业务工具:SQL 沙箱、文件导出、kb_search
          ├─ 评估模块:Runner、测试集、LLM-as-judge、坏例沉淀
          ├─ 权限审计:RBAC、多租户、审计日志
          └─ 可观测:事件埋点、指标上报
底座层    AgentScope-Java:ReAct 编排、Tool/MCP、事件流、模型适配
设施层    PostgreSQL / Redis / Milvus / OpenSearch

划分原则一句话:底座管「Agent 怎么跑」,业务层管「企业要什么」。所有带业务语义的东西——租户、权限、成本、评估——都落在 biz-platform,上游源码一行不动。这保证了底座升级时我只需要拉版本合并,不用重做冲突仲裁。

关键决策一:评估走旁路

最容易做错的架构点是评估和监控。直觉做法是在 Agent 执行代码里到处插桩,结果就是主链路被埋点淹没,性能和可读性双输。

我的做法:Agent 的所有生命周期事件(思考、工具调用、异常、token 用量)由底座的事件流统一抛出,biz-platform 里做一个事件订阅者旁路消费:

  • AgentEventPublisher / AgentEventListener:订阅事件,喂给评估与监控模块;
  • MetricCollector:异步聚合 calls、token、p95,不阻塞主链路;
  • AuditLogger:只记录关键动作(agent.chat、tool.kb_search),带租户、用户、耗时。

实测效果:主链路对埋点零感知,GET /api/metrics/summary 拿到的 calls/token/p95 全部来自旁路聚合。这个模式是后面第 11 章的基础。

关键决策二:Profile 双态

企业平台最难伺候的是两个场景的落差:给客户演示要「零依赖秒起」,生产交付要「真组件真持久化」。我的解法是 Spring Profile 双态,一套代码两副面孔:

组件demo profilemilvus/prod profile
数据库H2 内存PostgreSQL
会话记忆InMemoryChatMemoryRedisChatMemory(TTL 1 天)
检索InMemoryRetriever(BM25 简化)MilvusHybridRetriever(向量+BM25+RRF)
向量库无Milvus standalone

以检索器为例,切换只靠一个注解:

@Profile({"prod-milvus", "milvus"})
@Component
public class MilvusHybridRetriever implements Retriever { ... }

两个实现共用 Retriever 接口,上层 RagService 对此完全无感知。demo 态下笔记本上 mvn spring-boot:run 就能跑通全部 API;milvus 态下换成真实向量检索,业务代码零改动。接口先行 + Profile 切换,是这套架构里性价比最高的一个决定。

一次 chat 的完整旅程

把数据流串起来看:

POST /api/agent/chat
  → JWT 认证 + RBAC 鉴权(403/401 在这一层拦)
  → TenantInterceptor 解析租户,塞进 RuntimeContext
  → 构建 Agent,history 从 ChatMemory 拉出拼接
  → ReAct 循环:思考 → 调工具(kb_search / SQL 沙箱)→ 继续推理
  → 事件流旁路:审计落一条 agent.chat(cost=毫秒数),指标聚合
  → 答案返回,本轮 user/assistant 写回会话记忆

实测一轮真实对话:tokenIn=888, tokenOut=89, latency=2768ms,审计行同步落库留痕。这条链路上每一个箭头,后面各章会逐个拆开讲透。

代码地图

biz-platform 的包结构对应上面的分层,找代码按图索骥:

com.agent.biz
├─ agent/    AgentFactory、AgentServiceImpl、BizTools、ChatMemory 体系
├─ gateway/  ChatController(同步+SSE)、SecurityConfig
├─ rag/      RagService、Chunker/SemanticChunker、MilvusHybridRetriever
├─ eval/     EvalRunService、EvalJudge、LlmJudge、BadCaseRepository
├─ auth/     JwtUtil、AuthInterceptor、TenantInterceptor
├─ audit/    AuditLogger
└─ metrics/  MetricsStore、MetricsSubscriber、MetricCollector

下一篇进 RAG:文档从 PDF 到可检索向量,中间的分块与去重是怎么做的。


  • 本章对应源码:com.agent.biz 全包
  • 配套文档:docs/02_系统架构.md