CSDN 原文镜像
本文为作者 CSDN 博客的全文镜像,原文发布于 2026-08-26。为适配本站结构,仅补充了站内元数据与来源说明,正文主体保持原文内容。
- 原文链接:https://blog.csdn.net/m0_63309778/article/details/164094876
- 站内分区:Agent / BFF 与 Agent 架构

在很多项目刚开始时,系统架构往往非常简单:
Frontend
|
v
Backend
|
v
Database前端调用后端提供的几个接口,后端查询数据库并返回数据。
这种架构没有什么问题。
但随着业务越来越复杂,后端开始拆成:
用户服务
订单服务
文件服务
权限服务
搜索服务
Agent 服务
RAG 服务
模型服务
观测服务
……前端也从一个简单页面逐渐发展成 Web、App、小程序甚至多个管理后台。
这时候,经常会出现一个问题:
前端为了展示一个页面,需要调用五六个甚至十几个后端服务。
例如一个 Agent 详情页可能需要:
Agent 基本信息
模型配置
知识库
Tools
最近运行记录
Token 消耗
用户权限前端开始不得不理解整个后端微服务体系。
这时候,BFF 就开始变得非常有价值。
BFF,全称:
Backend for Frontend
直译就是:
为前端服务的后端。
它不是一个新的编程框架,也不是某个具体产品,而是一种架构模式。
它真正想解决的问题是:
前端真正需要的数据模型,与后端按照业务领域设计的数据模型,往往不是一回事。
一、为什么会出现 BFF?
假设我们有一个 Agent 平台。
后端已经拆成多个服务:
User Service
Agent Service
RAG Service
Knowledge Service
File Service
Metrics Service
Permission Service现在前端打开 Agent 详情页面。
需要请求:
GET /agents/123
GET /agents/123/model
GET /agents/123/knowledge-bases
GET /agents/123/tools
GET /agents/123/runs
GET /agents/123/metrics
GET /agents/123/permissions为了展示一个页面,浏览器发送了七个请求。
这还只是最简单的情况。
前端接下来还需要:
判断接口有没有失败
↓
处理超时
↓
处理鉴权
↓
合并返回结果
↓
转换字段
↓
转换状态
↓
处理部分服务不可用
↓
决定页面显示什么慢慢地,我们会发现:
前端承担的已经不只是 UI 展示逻辑,而是在做后端服务编排。
更麻烦的是,前端开始知道:
Agent Service 是什么
RAG Service 是什么
Metrics Service 是什么
Knowledge Service 在哪里
哪个接口先调用
哪个接口失败可以忽略
哪个接口失败整个页面不能显示这意味着:
后端微服务架构已经泄漏到了前端。
于是可以增加一层:
Web
|
v
BFF
|
+---------+---------+
| | |
v v v
Agent RAG User
Service Service Service
| |
v v
Metrics Permission前端只调用:
GET /bff/agents/123/detailBFF 内部完成:
查询 Agent
+
查询知识库
+
查询 Tools
+
查询运行记录
+
查询 Metrics
+
查询权限
↓
并发调用
↓
数据聚合
↓
字段转换
↓
返回页面需要的数据最终前端拿到:
<span class="token punctuation">{<!-- --></span>
<span class="token string-property property">"agent"</span><span class="token operator">:</span> <span class="token punctuation">{<!-- --></span><span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token string-property property">"model"</span><span class="token operator">:</span> <span class="token punctuation">{<!-- --></span><span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token string-property property">"knowledgeBases"</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token string-property property">"tools"</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token string-property property">"recentRuns"</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token string-property property">"metrics"</span><span class="token operator">:</span> <span class="token punctuation">{<!-- --></span><span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token string-property property">"permissions"</span><span class="token operator">:</span> <span class="token punctuation">{<!-- --></span><span class="token punctuation">}</span>
<span class="token punctuation">}</span>然后直接渲染页面。
这就是 BFF 最核心的价值。
二、为什么叫 Backend for Frontend?
BFF 这个名字真正重要的不是 Backend。
而是:
for Frontend
传统后端 API 通常站在业务领域的角度设计。
例如用户服务:
User订单服务:
OrderAgent 服务:
Agent
AgentVersion
Run知识库服务:
KnowledgeBase
Document
Chunk所以接口可能是:
GET /users/{id}
GET /orders/{id}
GET /agents/{id}
GET /runs/{id}
GET /knowledge-bases/{id}这些 API 在回答:
我的业务能力是什么?
而 BFF 站在前端页面的角度思考。
比如:
首页
Agent 详情页
Agent 编辑页
Run 详情页
Dashboard所以它可能提供:
GET /bff/home
GET /bff/agents/{id}/detail
GET /bff/agents/{id}/editor
GET /bff/runs/{id}/detail
GET /bff/dashboard注意:
Dashboard本身甚至不是一个真正的业务领域。
后端数据库里通常也不会存在:
dashboard_tableDashboard 只是把:
Agent 数据
+
用户数据
+
运行数据
+
Token 数据
+
费用数据组合成一个前端视图。
这正是 BFF 最擅长处理的问题。
三、BFF 本质上是在做一次“模型转换”
前后端之间存在一个非常重要的问题:
Backend Domain Model
≠
Frontend View Model例如后端可能围绕这些对象设计:
User
Agent
AgentVersion
KnowledgeBase
Document
Run
RunStep
Metric
Tool但前端真正关心的对象可能是:
AgentListItem
AgentDetailPage
RunDetailPage
DashboardCard
ChatMessage后端设计关注的是:
业务领域如何建模。
前端设计关注的是:
页面怎样展示。
因此 BFF 可以理解成:
Domain Model
↓
BFF
↓
View Model它在两个世界之间建立了一层转换。
四、BFF 最核心的四种职责
一个比较健康的 BFF,通常主要负责四件事情。
1. Aggregation:接口聚合
例如:
Frontend
|
v
BFF
|
+------> Agent Service
|
+------> User Service
|
+------> Knowledge Service
|
+------> Metrics Service然后 BFF 将结果聚合后一次返回。
而且这些服务通常可以并发请求:
Agent ──────────┐
Knowledge ──────┤
Metrics ────────┼──→ Merge → Response
Runs ───────────┘而不是串行:
Agent
↓
Knowledge
↓
Metrics
↓
Runs这既降低了前端复杂度,也可能减少页面整体加载时间。
五、Transformation:数据转换
后端 API 往往更接近数据库和领域模型。
例如:
<span class="token punctuation">{<!-- --></span>
<span class="token string-property property">"id"</span><span class="token operator">:</span> <span class="token number">123</span><span class="token punctuation">,</span>
<span class="token string-property property">"status"</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span>
<span class="token string-property property">"owner_id"</span><span class="token operator">:</span> <span class="token number">98</span><span class="token punctuation">,</span>
<span class="token string-property property">"created_at"</span><span class="token operator">:</span> <span class="token string">"2026-08-26T10:00:00Z"</span>
<span class="token punctuation">}</span>但前端真正希望得到的可能是:
<span class="token punctuation">{<!-- --></span>
<span class="token string-property property">"id"</span><span class="token operator">:</span> <span class="token string">"123"</span><span class="token punctuation">,</span>
<span class="token string-property property">"status"</span><span class="token operator">:</span> <span class="token punctuation">{<!-- --></span>
<span class="token string-property property">"code"</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span>
<span class="token string-property property">"label"</span><span class="token operator">:</span> <span class="token string">"运行中"</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token string-property property">"owner"</span><span class="token operator">:</span> <span class="token punctuation">{<!-- --></span>
<span class="token string-property property">"id"</span><span class="token operator">:</span> <span class="token number">98</span><span class="token punctuation">,</span>
<span class="token string-property property">"name"</span><span class="token operator">:</span> <span class="token string">"张三"</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token string-property property">"createdAt"</span><span class="token operator">:</span> <span class="token string">"2026-08-26 18:00"</span>
<span class="token punctuation">}</span>这里涉及:
字段重命名
状态转换
时间转换
对象拼装
字段裁剪
数据补充这些逻辑如果大量散落在 React/Vue Component 里面,前端代码会越来越难维护。
BFF 可以统一完成这层转换。
六、Orchestration:服务编排
BFF 不一定只是简单地:
请求 A
请求 B
Merge有时候一个前端操作可能需要:
先查询用户权限
↓
查询 Agent
↓
获取 AgentVersion
↓
根据 Version 查询 Tools
↓
根据 KnowledgeBase 查询知识库
↓
拼装编辑页面甚至:
A 成功以后调用 B
B 失败以后降级到 C这属于轻量级的:
Orchestration
也就是服务编排。
不过这里要特别注意一个边界:
BFF 可以编排业务能力,但不应该成为业务能力本身。
这个问题后面还会重点讨论。
七、Frontend-specific Logic:前端特有逻辑
还有一些逻辑天然属于某个客户端。
例如:
Web Dashboard 展示哪些字段
App 首页返回多少条数据
小程序是否需要分享信息
Web 是否需要 SEO Metadata
App 是否需要 Deep Link这些内容没有必要进入核心领域服务。
非常适合放到对应 BFF。
于是可以出现:
Backend Services
↑
+----------+----------+
| | |
Web BFF App BFF Mini BFF
↑ ↑ ↑
Web App 小程序这其实也是 BFF 模式最初的思想之一:
不同前端,可以拥有自己的 Backend for Frontend。
八、BFF 和 API Gateway 到底有什么区别?
这是讨论 BFF 时最容易混淆的问题。
很多人会问:
“我已经有 API Gateway 了,为什么还需要 BFF?”
因为它们解决的问题完全不同。
典型架构:
Client
|
v
API Gateway
|
v
BFF
|
+-------- User Service
|
+-------- Agent Service
|
+-------- RAG Service
|
+-------- File ServiceAPI Gateway 更多负责:
统一入口
路由
认证
限流
WAF
负载均衡
IP 黑白名单
TLS
流量治理而 BFF 负责:
数据聚合
接口编排
DTO 转换
前端 ViewModel
客户端特有逻辑可以用一句话区分:
Gateway 管“流量怎样进入系统”,BFF 管“前端需要什么数据”。
例如:
用户请求有没有 Token?更偏 Gateway。
这个 Agent 详情页应该返回哪些信息?更偏 BFF。
当然现实系统的边界并不会永远这么绝对,但从职责设计上应该尽量保持这个方向。
九、BFF 和 Controller 不是一回事
另外一个容易混淆的概念是 Controller。
例如一个典型 Java 服务:
Controller
↓
Service
↓
Repository
↓
Database这里 Controller 只是:
单个服务内部的接口入口层。
而 BFF 是:
BFF
|
+-------+-------+
| | |
v v v
User Agent RAG
Service Service Service它通常运行在多个 Backend Service 上层。
所以:
Controller ≠ BFF但是:
BFF 自己当然也可以有 Controller。
例如:
AgentBffController
↓
AgentDetailFacade
↓
+-------+--------+--------+
| | | |
Agent User RAG Metrics
API API API API十、BFF 和 GraphQL 是什么关系?
GraphQL 也经常和 BFF 一起出现。
但二者同样不是一回事。
GraphQL 是:
API Query Language / Runtime
而 BFF 是:
Architecture Pattern
因此完全可以:
Frontend
|
v
GraphQL BFF
|
+------ User Service
+------ Agent Service
+------ RAG Service前端请求:
query {
agent(id: "123") {
name
model {
name
}
knowledgeBases {
name
}
runs {
status
}
}
}GraphQL BFF 再负责从后端多个服务获取这些数据。
所以:
GraphQL 可以是实现 BFF 的一种技术方案,但 GraphQL 本身不是 BFF。
十一、Next.js 为什么天然适合承担 BFF?
现在很多 React 项目使用 Next.js。
这时:
Route Handler
Server Action
Server Component本身就天然拥有服务器运行环境。
于是架构可以变成:
Browser
|
v
Next.js
|
+------ Java Backend
|
+------ Python Agent Service
|
+------ RAG Service此时 Next.js Server Layer 就可以承担一部分 BFF 职责。
例如:
Cookie / Session 读取
接口聚合
Token 转换
服务端鉴权
DTO 转换
内部服务地址隐藏
SSE 转发
错误转换浏览器完全不需要知道:
agent-service.internal:8000
rag-service.internal:8111
java-api.internal:8080浏览器只访问:
/api/*这是现代 Web 项目中非常常见的一种 BFF 实现方式。
十二、BFF 在 Agent 系统里尤其有价值
随着 Agent 系统逐渐复杂,BFF 的价值会更加明显。
例如:
Web
|
v
Agent BFF
|
+-----------+-----------+
| | |
v v v
Agent Conversation File
Runtime Service Service
|
+-----+-----+
| |
v v
RAG Tools用户发送:
POST /api/chatBFF 内部可能执行:
获取当前 User
↓
验证 Agent 权限
↓
查询 Conversation
↓
处理附件
↓
创建 Agent Run
↓
连接 Agent Runtime
↓
代理 SSE Stream
↓
转换事件
↓
返回浏览器这里有一个特别典型的 Agent 场景:
SSE Event Adapter
Agent Runtime 内部可能产生:
run.created
model.started
model.delta
retrieval.started
retrieval.completed
tool.started
tool.completed
subagent.started
subagent.completed
run.completed但是前端不一定想理解整个 Agent Runtime 协议。
前端真正关心的可能只是:
text_delta
thinking
tool_call
status
done于是:
Agent Runtime Events
↓
BFF
↓
Frontend Event Model这样即使以后底层 Agent Runtime 改了:
LangGraph
→ 自研 Runtime只要 BFF 对外协议不变,前端就不需要全部重写。
这其实也是 BFF 很重要的一层价值:
隔离前端与内部实现细节。
十三、BFF 最大的坑:慢慢变成“第二个业务后端”
BFF 很方便。
也正因为方便,非常容易失控。
最开始:
BFF 调用订单服务后来:
顺手判断一下订单状态。再后来:
顺手判断退款条件。然后:
顺手算一下退款金额。最后甚至:
BFF 直接操作数据库。慢慢变成:
BFF
|
大量业务规则
|
+-------+-------+
| |
DB Backend这时 BFF 实际已经变成:
第二个业务后端。
这是非常危险的架构演化。
十四、BFF 到底应该放什么,不应该放什么?
我比较推荐用下面这个公式理解:
BFF
=
Aggregation
+
Transformation
+
Orchestration
+
Frontend-specific Logic而不是:
BFF
=
Domain Business Logic适合放 BFF
例如:
多个 API 聚合
并发请求多个服务
DTO 转换
ViewModel 拼装
Cookie → Token 转换
SSE 代理
Agent Event 转换
页面级数据裁剪
客户端特有字段
轻量接口降级不应该放 BFF
例如:
退款业务规则
订单金额计算
库存扣减规则
权限核心模型
RAG 检索算法
Agent Runtime 状态机
招投标业务规则
财务规则一个很好判断的方法是:
如果明天没有这个 Web 页面,这段逻辑还应该存在吗?
如果答案是:
应该存在。
那它很可能属于:
Domain Service而不是 BFF。
十五、BFF 什么时候值得引入?
不是所有系统都需要 BFF。
如果你的架构只有:
一个 Web
+
一个 Backend而且:
接口简单
页面不复杂
前端请求数量不多那么:
Frontend → Backend完全够用。
没必要为了:
“架构看起来高级”
再增加一个 BFF。
因为每增加一个服务,就意味着增加:
部署
日志
监控
Trace
超时
重试
容灾
开发成本
维护成本BFF 真正适合下面这些场景。
场景一:前端开始调用很多微服务
例如:
一个页面调用 5~10 个服务。这是非常典型的信号。
场景二:前端大量写数据拼装代码
如果 React/Vue 项目里面开始大量出现:
Promise.all
map
filter
merge
normalize
transform
permissionCheck而且这些逻辑并不是 UI 本身,而是在适配后端数据。
就值得考虑 BFF。
场景三:有多个客户端
例如:
Web
App
小程序
后台管理端而不同客户端的数据需求差异明显。
这正是 BFF 最经典的应用场景。
场景四:微服务内部结构不希望暴露给前端
前端已经开始知道:
User Service
Agent Service
File Service
RAG Service
Metrics Service甚至保存多个:
BASE_URL通常意味着服务边界已经泄漏到客户端。
场景五:Agent / AI 应用
尤其是:
Agent Runtime
RAG
File
Conversation
User
Permission
Observability多个系统共同组成一个 AI 产品时。
BFF 非常适合作为前端与 AI Backend 之间的适配层。
十六、一个比较完整的企业架构
最终系统可能演进成:
Client Layer
Web App Mini Program
| | |
v v v
Web BFF App BFF Mini BFF
\ | /
\ | /
+----------+-----------+
|
API Gateway
|
+-------------+-------------+
| | |
v v v
User Agent File
Service Service Service
|
+-------+-------+
| |
v v
RAG Model
Service Service现实系统也非常常见:
Client
↓
Gateway
↓
BFF
↓
Microservices究竟 Gateway 在 BFF 前还是后,取决于:
网络拓扑
部署方式
Ingress
安全边界
服务治理方案并没有唯一答案。
十七、理解 BFF 最简单的比喻:餐厅服务员
可以把整个系统想象成一家餐厅。
前端:
顾客。
不同微服务:
主食档口
饮料档口
甜品档口
凉菜档口如果没有 BFF:
顾客
↓
跑去主食档点菜
↓
跑去饮料档点饮料
↓
跑去甜品档点甜点
↓
自己拿回来拼成一顿饭这就类似:
Frontend
|
+------ User Service
+------ Agent Service
+------ RAG Service
+------ File Service有 BFF 后:
顾客
↓
服务员
↓
各个厨房档口服务员负责:
理解这一桌要什么
分别找对应档口下单
协调多个请求
把东西整理好
一次性交给顾客这个“服务员”就是:
BFF。
但这里还有一个非常重要的边界:
服务员不会自己去厨房炒菜。
这句话几乎可以帮助我们判断绝大多数 BFF 架构问题。
BFF 可以:
叫菜
协调
组合
整理
交付但是业务服务才真正负责:
做菜。十八、从 BFF 背后真正应该理解的架构思想
BFF 本身并不是最重要的。
更重要的是它体现出的一个架构原则:
不同系统应该面向自己的消费者设计边界。
业务后端面向的是:
业务能力所以围绕:
用户
订单
支付
Agent
知识库设计。
而 BFF 面向的是:
前端体验所以围绕:
首页
详情页
工作台
会话页
Dashboard设计。
这两个视角本来就不应该被强行统一。
因此:
Backend Domain Model和:
Frontend View Model之间拥有一个清晰的适配层,往往反而能让整个系统的边界更加稳定。
结语
BFF 并不是什么复杂的新技术。
它真正解决的是一个随着系统规模扩大几乎必然出现的问题:
前端需要的数据,与后端提供的业务能力之间存在天然差异。
当一个系统从:
Frontend
↓
Backend逐渐演变成:
Frontend
↓
十几个 Microservices如果仍然让浏览器直接理解所有后端服务,前端最终就会逐渐承担:
服务发现
接口聚合
数据转换
异常处理
权限拼装
业务编排系统边界会越来越混乱。
BFF 的意义,就是重新把这层复杂度收回来:
Frontend
↓
BFF
↓
Backend Services所以理解 BFF,可以记住两句话:
Gateway 解决“请求怎么进系统”,BFF 解决“前端需要什么”。
以及:
BFF 可以负责点菜、协调和拼盘,但不要让它自己下厨房炒菜。
对于现代微服务,以及越来越复杂的 Agent / RAG / AI 应用,这种架构思想会越来越有价值。