目标:把十个后端 Agent 项目统一接入一个可视化管理台,让读者不是只看代码,而是能在浏览器里真实操作、观察、验证。
对应代码:frontend/、backend/main.py
13.1 十个黑盒的烦恼
话说这一路跑下来,你已经攒了十个项目。客服、知识库、代码审查、数据分析……每一个都能在命令行里跑通,输出一段漂亮的答案。你很得意,把命令贴给同事看。
同事看了一眼,问了一句让你卡壳的话:“它中间到底干了什么?”
你愣住了。是啊——它调了哪个工具?检索了哪几段文档?走了哪条分支?有没有偷偷幻觉?在命令行里,这些全都看不见。你给同事的,只是一个黑盒的最终输出。
更糟的是,十个项目散在十个目录里,十条命令各跑各的。你想给同事演示一遍,得来回切窗口、贴命令、解释“这个先别管,那个等一下”。演示到一半,对方已经走神了。
💡 顿悟时刻:Agent 工程的真正门槛,往往不是“让它能跑”,而是“让它能被看见”。一个看不见内部的过程,既没法学习,也没法排障,更没法交付。
于是这一章,我们要给这十个黑盒开一扇窗——一个统一的前端管理平台。它要解决三件事:
- 统一入口:所有项目在一个页面里选择和运行,不再满屏切窗口。
- 执行可视化:不只看最终答案,还能看到 Agent 节点、工具调用、错误事件——把黑盒打开给你看。
- 学习验证:你可以边读书边在前端输入不同案例,亲手验证书里的设计。
13.2 画个样子:它该长啥样
先想清楚这个平台长什么样。读者打开浏览器,看到的不是十个命令行,而是一个“项目总览页”——十个卡片整整齐齐排开,点哪张进哪个。
%%{init: {'theme':'base','flowchart':{'useMaxWidth':true,'htmlLabels':true}}}%%
graph TD
Home["项目总览页"] --> Card["10 个项目卡片"]
Card --> Panel["交互面板"]
Panel --> Input["输入任务"]
Panel --> Run["运行 Agent"]
Run --> Trace["执行过程可视化"]
Run --> Result["最终结果"]
classDef p fill:#e3f2fd,stroke:#1976d2,stroke-width:2px,color:#0d47a1
classDef a fill:#ede7f6,stroke:#5e35b1,stroke-width:2px,color:#311b92
classDef o fill:#e8f5e9,stroke:#43a047,stroke-width:2px,color:#1b5e20
class Home,Card,Panel p
class Input,Run,Trace a
class Result o
功能列表
| 功能 | 说明 |
|---|---|
| 项目卡片 | 展示项目名称、描述、能力标签 |
| 交互输入 | 输入自然语言任务 |
| 流式执行 | 调用 /api/projects/{id}/stream |
| 事件面板 | 显示 LangGraph updates / 工具调用信息 |
| 能力标签 | Tool / RAG / MCP / Multi-Agent / Memory 等 |
这里有个设计取舍值得多说一句:我们没有给每个项目单独做一个页面,而是让所有项目共用同一套交互面板,靠后端注册来区分。这样读者换项目时心智负担很小——左边换张卡片,右边照常输入、运行、看过程。
13.3 拆开看:怎么造出来
13.3.1 前后端接口
后端对外只暴露这么几个接口:
| 接口 | 作用 |
|---|---|
GET /api/projects |
项目列表 |
POST /api/projects/{id}/run |
一次性运行 |
POST /api/projects/{id}/stream |
流式运行 |
GET /api/health |
健康检查 |
GET /api/metrics |
全局指标 |
注意这里藏着一个“解耦”的小心机:前端只依赖这几个接口,因此后续新增项目不需要改前端业务逻辑,只需要后端注册新项目。换句话说,前端这层是“项目无关”的——你以后做出第 11、第 12 个项目,前端一行代码都不用动。
⚠️ 避坑:很多团队喜欢给每个项目单独写一套前端,结果项目一多,前端就成了“每个项目都要改一遍”的债坑。统一接口是这个坑的解药。
13.3.2 流式事件:给 Agent 装一台行车记录仪
这一节是整章的灵魂。我们要把“执行过程可视化”讲透。
先打个比方。你在高速上开车,车上装了行车记录仪。你不需要每秒盯着它,但它一直在录。一旦出了事——追尾、刮蹭、莫名其妙的熄火——你回放录像,就能看清到底哪一秒出了问题。
Agent 也是一样。它跑起来之后,内部会发出一连串事件:进入某个节点了、调了某个工具了、工具返回结果了、报错了。如果这些事件只闷在后台跑,你就等于开着一辆没有行车记录仪的车——出了问题只能靠猜。而如果把这些事件流式地推到前端,你就拥有了一面透视镜:Agent 每一步在干什么,看得清清楚楚。
这件事的价值是双重的:
- 对学习者:你能亲眼看见“一个 Agent 到底是怎么一步步思考的”。这是看书读代码永远替代不了的体验——代码是静态的,执行是动态的,只有看到动态过程,那些抽象的“节点”“工具”“状态”才真正活过来。
- 对生产者:出了 bug,你能秒级定位是哪一步崩的;性能差,你能看出卡在哪个工具;回答不对,你能倒查它检索了什么、调用了什么。这比事后翻日志高效得多。
后端使用 SSE(Server-Sent Events)返回事件。前端通过 ReadableStream 逐段解析:
1 | const reader = resp.body.getReader() |
为什么用 SSE 而不用 WebSocket?因为 Agent 执行过程是单向推送——服务端往前端推事件,前端不需要反向发消息。SSE 比 WebSocket 轻量得多,浏览器原生支持,断线还能自动重连,正好对口。
💡 顿悟时刻:可视化不是“好看”,而是“可调试”。一个能被看见的系统,才能被信任、被改进。
13.4 动手写:搭起管理台
核心文件:
frontend/src/App.jsxfrontend/src/styles.cssfrontend/vite.config.js
13.4.1 项目列表
页面一加载,先拉项目列表:
1 | useEffect(() => { |
13.4.2 流式执行
用户输入任务、点运行,前端发起流式请求:
1 | const resp = await fetch(`/api/projects/${active.id}/stream`, { |
13.4.3 可视化事件
当前版本用 JSON 面板直接展示事件,已经足够把“黑盒”打开一条缝。但这只是起点,生产版本还可以做得更“透视”:
- 节点图动画:看着状态在节点之间跳转,像看电路通断电。
- 工具调用卡片:每个工具一张卡,输入输出都摆出来。
- RAG 检索片段高亮:直接看到模型到底“读”了文档的哪几段。
- Token/成本统计:每一步烧了多少钱,一目了然。
⚠️ 避坑:可视化面板别只顾着炫。它真正的使命是“帮你定位问题”,所以信息要按“事件流”的时序组织,而不是按“看起来漂亮”的布局组织。
13.5 送上线:让它上班
前端本地开发:
1 | cd frontend |
Docker 部署:
1 | docker compose up -d frontend backend |
13.6 回头看:学到了什么
回到开头那个卡壳的瞬间。同事问“它中间到底干了什么”,现在你可以把浏览器转过去,点一下运行,让事件的流一条条滚过去:“你看,它先检索了这三段,然后调了工具,工具返回了这个,最后它基于这些生成了答案。”
统一前端不是装饰,而是学习和生产都需要的观测窗口。Agent 系统最大的问题之一是黑盒;可视化管理台让黑盒透明化,让读者能看见每个项目背后的实际运行过程。
金句:给 Agent 装一台行车记录仪,黑盒就变成了玻璃盒。能被看见,才能被理解;能被理解,才能被信任。
如果您喜欢此博客或发现它对您有用,则欢迎对此发表评论。 也欢迎您共享此博客,以便更多人可以参与。 如果博客中使用的图像侵犯了您的版权,请与作者联系以将其删除。 谢谢 !