TRADE-OFFS · @migor/agentia
取舍对照
这一页不列优势。它写的是我们不做什么、那些「不做」的 代价是什么、以及什么场景你该选别人。 选型时真正难判断的从来不是「它有什么」,而是「它的边界在哪、边界外的活谁干」。
定位:它占哪两层
本框架刻意只占两层:运行时(四类能力 + 主 agent 编排 + 宿主导出) 与可观测(trace / 成本 / 指标是一等公民,不是外挂)。 这也是「能不能直接上线」这条主张的全部内容。
其余层 —— 编排器 UI、评估平台、记忆/向量服务、托管与部署产物 —— 一概不在射程内。
判断标准写在仓里:只给缝、不给策略(docs/spec.md 出现 4 次)。
于是「该不该内建」的答案是:引第三方依赖的,一律不进核心 —— 因为核心的卖点是
零运行时依赖(tests/architecture/no-runtime-deps.test.ts 守着,不是口头承诺)。
⚠️ 判别规则只有一条,且写在 docs/usage-guide.md:
「引不引第三方依赖」,而不是「用户想不想要」。
所以 MCP stdio 连接器内置(只用标准库),而 gRPC 之类的宿主集成只能是
配方 + 示例(examples/grpc-host/ 已证「换宿主 = 缝外组合」)。
不适用场景
下面每一条都是「这条路走不通,别选它」,不是「以后会更好」。
| 如果你的情况是… | 为什么不选它 | 那边是谁的主场 |
|---|---|---|
| 要可视化编排 / 低代码:拖拽式流程图、在线改编排 | 本框架是库,编排写在代码里(装饰器 + DI)。没有任何可视化编辑器,也没有这个计划 | LangGraph 的图与状态机、Mastra 的工作流与平台界面 |
| 要Python | TypeScript only。Deno / Bun / edge runtime 未验证(不在 engines 承诺内,也不在 CI 上) | LangGraph(Python 原生)、各家 Python SDK |
| 要托管平台(托管运行、托管记忆、托管评估) | 本框架不提供任何服务。它交付的是「你自己能上线的服务」,不是替你跑的那个平台 | Mastra 那类「框架 + 平台」一体的产品 |
| 要开箱即用的向量检索 / 评估平台 | 0 运行时依赖 ⇒ 不装厂商 SDK。src/ 里 grep -rniE "embedding|vector|retriev" 0 命中是刻意的 | 需要检索服务的一方自行接入(见下节「RAG」) |
需要前端流式 UI 绑定(useChat 那类 React/Vue hook) | 没有客户端 SDK,也没有 React 绑定。服务端是它唯一的形态 | Vercel AI SDK 的 UI 层 |
| 需要1.0 级别的稳定性承诺 | 当前 0.x:minor 可以包含破坏性变更(规矩是「必须留痕」,不是「不会发生」) | 任何已发 1.0 且你愿意接受其体积的方案 |
刻意不做的事(以及空白由谁填)
| 不做 | 理由(仓内真源) | 那块空白怎么补 |
|---|---|---|
| 不装厂商 SDK | 零运行时依赖是卖点 ⇒ 适配器只能手写 + 全局 fetch | 换模型端点用 ANTHROPIC_BASE_URL 指向兼容端点 |
| 不内建日志层 / 采样 / 脱敏 / 存储 / 部署产物 | docs/spec.md §9.3 已锁定(别再提「补上」) | docs/observability.md 的四份配方 + examples/observability/ + grafana-dashboard.json |
| 不内建 RAG | 不是功能缺口:@Prompt 的形状就是「模型可调用、先拉资产再注入」 | 把那个 asset() 换成 search(query) —— src/ 零改动 |
| 不内建 channel / 传输层 | 同上:要引第三方客户端的,不进核心 | examples/grpc-host/ 已证「换宿主 = 缝外组合」,且进 e2e |
| 不提供客户端 SDK / React 绑定 | 不在那两层里 | 服务端直接返回结构化结果,前端自己消费 |
三个 @migor/* 附属包不发 npm | 机制而非疏漏:private: true —— 一条例外都没有(tests/docs/stability.test.ts 守着集合) | 拷目录 / file: 引入;npm i @migor/trace-view 会 404,这是决定不是 bug |
代价清单
选它会付的账,逐条写清(都可自己核实):
- 装配与约定要读文档:装饰器 + DI 是显式的 —— 目录约定、provider 注册、
loadEnvFile()放装配模块而非启动入口(放错会让agentia dev静默读不到.env)。换来的好处是「没有魔法」,代价是第一步要读。 - 可观测的消费面要自己接:出口只有一条缝(
TraceSink.export(trace)), 但往哪存、怎么检索、要不要采样与脱敏是你的事(配方在那,不是默认行为)。 - trace 缺省不记 assistant 文本:要记得显式开
traceContent:'full', 而那是按出参字节付费的(大出参档实测 13.6×,小出参档只差 1.0× —— 见 性能量级)。 /healthz与/metrics不鉴权:生产要由反代限制/metrics的可达性(指标里有能力名、成本等敏感读数)。完整清单见docs/deployment.md。- 0.x:每个 minor 都可能是「这次修的正是某个承诺没兑现的地方」。 规矩是破坏性变更必须留痕(CHANGELOG 带迁移小节),不是「不会有」。
- Node only:唯一碰内置模块的 store 是
SqliteTaskStore(需 Node ≥ 22.5 的node:sqlite),未提供时构造期给可读报错。
什么时候该选它
反过来只有三条,且都可验证:
- 你用 TypeScript / Node,要交付可直接上线的服务(不是 demo)。
- 你把 trace / 成本 / 指标当一等公民 —— 它决定「敢不敢上线」,不是事后补的日志。
- 你在意安装面:
npm i @migor/agentia只放一个包、 零运行时依赖(不装任何厂商 SDK)。
怎么自己核实
这一页的每一条都指向仓内可核的东西 —— 别信这一页,去跑: