项目索引
前置:写过服务端代码。四篇各自独立,不需要按顺序读。
这里的四篇不是项目介绍 —— 想知道某个项目是干什么的、怎么跑起来,看它的 README 更快。这四篇写的是 README 里不会写的那部分:当时卡在哪、试过哪些走不通的做法、最后为什么选了现在这条路。
四个项目
| 项目 | 定位 | 主技术栈 | 沉淀重点 |
|---|---|---|---|
| RAG Agent Platform | 多租户智能体 SaaS 平台 | Spring Boot 3 · LangChain4j · PGVector · RabbitMQ | 异步文档流水线、召回+精排、知识库版本化 |
| Lobster0 | 自托管个人 Agent | Python · SQLite · Playwright · Electron | 权限分层、参数绑定审批、Markdown 记忆 |
| mini-ray | 单机版 Ray 运行时 | C++17 · pybind11 · POSIX 共享内存 | 任务调度、ObjectRef、Python/C++ 边界 |
| EvalHub | LLM/Agent 评测平台 | Python · FastAPI · React · Ollama | 持久化 DAG、可复现指纹、过程证据 |
一篇工程范式沉淀
| 文章 | 主题 | 沉淀重点 |
|---|---|---|
| 对话助手 Agent 工程 | 联网取数 + 工具调用 + 长期记忆的对话式 Agent 参考架构 | 上下文注入顺序与 token 预算、记忆三层读写时机、统一工具协议、Deep Research 状态编排、离线数据飞轮 |
和上面四个项目不同,这篇不对应某个具体代码库,写的是多个 Agent 系统里反复出现的同一组设计问题:上下文由谁装配、记忆在什么时机进出、工具列表由谁裁剪。八张架构图可以脱离具体实现单独读。
它们之间的关系
四个项目不是孤立的,正好覆盖了 LLM 应用栈的四层:
- 做应用(RAG Agent Platform / Lobster0)会逼你回答:检索质量怎么保证?工具执行怎么 才安全?
- 做评测(EvalHub)会逼你回答:怎么证明它真的变好了?
- 做基础设施(mini-ray)会逼你回答:这些框架底下到底在干什么?
四条换个场景还成立的经验
1. 异步流水线按「失败域」切分,不按「步骤」切分。(来自 RAG Agent Platform)
一份 PDF 进来要先 OCR、再切块、再向量化。最自然的做法是三个步骤三个队列。但真跑起来会发现:OCR 失败通常是这份文件本身有问题,重试多少次都一样,而且它贵;向量化失败通常是下游服务抖了一下,重试一次就好,而且它便宜。把这两类塞进同一套重试策略,要么白烧钱,要么该重试的没重试。所以该问的不是「这是第几步」,而是「这一步会怎么失败、失败了值不值得重来」。
2. 模型提议,系统裁决。(来自 Lobster0)
模型说要调 run_command,这句话的地位应该等同于「用户点了一个按钮」,而不是「管理员下了一道命令」。校验、鉴权、审批、执行、审计全都得在系统侧再做一遍。而且硬边界和权限模式要分成两层 —— 用户可以把模式调到最松,但不能因此越过硬边界,否则「最松的模式」就成了后门。
3. 跨语言边界只传字节,不传语义。(来自 mini-ray)
C++ 那一侧一旦开始理解「这是个 Python 的 dict」,就会一路滑到要在 C++ 里实现半个 CPython。让它只做二进制搬运,什么都不懂,反而稳。
4.「跑失败」和「做错了」必须分开记录。(来自 EvalHub)
一次评测跑挂了,可能是模型答错了,也可能是机器 OOM 了。把后者也记成 0 分,你会得出「这版模型变差了」的结论,然后去调一个根本没问题的模型。这条在监控、告警、AB 实验里是同一件事。