本节摘要:规则引擎是大脑、上下文是记忆、依赖注入是把零件接上神经的方式。对照硬编码
new满天飞的对话原型,以及某些通用 Agent 「全家桶单例」难以测试,Parlant 用容器按生命周期装配日志、模型服务、网关、审计。换模型、换环境、写单测,改的是绑定,不是业务指南。
阅读完本节,你应当能够:
Parlant 要同时对付多模型、工具网关、审计、规则编译、缓存、安全校验。A 直接创建 B,B 再创建 C,模型一换、日志一换,全图抖动。通用 Agent 脚本经常在入口把客户端写死;规则引擎老服务则是配置文件加静态工厂,测试仍难隔离。
依赖注入的核心就一句:对象不自己创建依赖,由容器在运行时注入。依赖从代码挪到配置。原文列举的依赖类型包括:各家模型服务实例、上下文管理器、规则编译器、缓存策略、审计记录器。它们还互相依赖——规则引擎要上下文,还要网关验权。没有统一管理,调用网就是面。
# 概念:用类型声明依赖,而不是在组件内部创建日志器 def __init__(self, logger: Logger) -> None: self.logger = logger
原文写的是自研轻量容器,而不是直接搬某家企业级 DI 框架。选择理由:性能、可控、以及 AI 工作负载的异步。启动时注册,运行时按图解析。
运行时高层组件被请求,容器递归装配。异步初始化可被等待,避免把远程模型客户端的握手卡在同步构造里。这是和传统同步 DI 在 AI 场景里的差别。
| 生命周期 | 典型组件 | 若用错会怎样 | 对照通用 Agent 常见写法 |
|---|---|---|---|
| 单例 | 日志、审计 | 做成瞬态则日志配置分裂 | 模块级全局客户端 |
| 作用域 | 上下文管理器 | 做成单例则会话串话 | 很少有会话级容器 |
| 瞬态 | 某些结构化生成器 | 做成单例则请求状态泄漏 | 每次手写 new |
⚠️ 常见坑:把上下文管理器做成进程级单例。并发会话会串状态,这比模型幻觉更难查,因为日志看起来「模型胡了」,其实是隔壁用户的槽位。
💡 关键直觉:交通调度里信号机是城市级单例,一辆车的导航状态必须是该车作用域。混用层级就是对向车道共用一个方向盘。
合规客服的响应校验依赖规则集与审计日志。测试注入内存规则和内存日志;生产注入加密规则库与分布式审计。业务代码不改。医疗助手依赖授权网关,网关再依赖患者上下文;患者上下文设为作用域,同一会话共享,跨会话不泄漏。多模型迁移:注册新的模型服务实现,改绑定,上层示意图生成不必改。这是插件,不是分支。
优点:解耦、可测、可配置、可扩展。代价:IoC 有学习曲线;解析失败堆栈可能绕;微秒级解析开销在极端并发要评估。原文提到部署前校验依赖图、审计记录解析耗时——具体命令以当时工具链为准,不把某条 CLI 写成保证永远存在的产品开关。
自适应 DI(高负载换轻缓存、敏感查询强制加密日志)被写成研究向,甚至提到强化学习和声明式依赖描述。那是演化,不是你今天必须配置的强化学习环。先把生命周期用对,比先上「智能绑定」重要。
金融、医疗、法律落地案例背后,常常是一张安静的依赖图在换零件。指南写的是业务,DI 写的是工程纪律。两条线别拧成一股:别让业务专家去理解容器,也别让容器配置承担业务口径。
DI 对不熟悉控制反转的人像多余。规范写短些:会话相关状态禁止进程级单例;日志与审计默认单例;每请求的结构化生成器默认瞬态;远程模型客户端的握手要异步。代码评审只抓这四条,就能挡住串话和泄漏。容器实现可以自研也可以借鉴,原则比品牌重要。原文选择自研轻量容器,是为了异步与可控,不是为了显示独特。
测试策略直接来自注入。规则引擎测的是:给定模拟上下文和模拟网关,某条指南是否授权某工具。不要在单元测试里打真实模型。真实模型放在契约测试或预发。环境绑定表应出现在部署文档:开发、预发、生产三列,组件实现各是什么。缺这张表,DI 只存在于口头。
环依赖是结构味道。出现 A 要 B、B 要 A,通常是职责没切干净,例如网关又去解析指南。切开后再注册。延迟加载能掩盖启动失败,也会把错误推迟到第一通用户电话。能在启动时校验的,不要懒到运行时。原文写注册阶段拓扑排序报错,就是这个纪律。
自适应绑定、强化学习调依赖,当作研究向。生产里先做手工绑定和明确的环境差异。高负载换缓存策略可以用配置开关,不必上学习器。智能体已经够难观测,再给容器一层自学,事故会说不清是指南问题还是绑定问题。克制是架构美德,这里再强调一次。
绑定表(示例列) 组件 | 开发 | 预发 | 生产 网关 | 模拟 | 受限真接口 | 真接口+限速 审计 | 内存 | 文件 | 分布式 模型 | 便宜小模型 | 同生产模型 | 生产模型 上下文 | 作用域 | 作用域 | 作用域+持久化
故意把上下文管理器改成单例,用两个并发会话各说一个城市天气,观察是否串。这是教学演习,预发做,生产禁。演习能让不信 IoC 的人看见生命周期不是学院派。再演习一次:测试环境若仍注入真实网关,沙箱数据被改,说明绑定表没执行。DI 的价值在演习里比在图里清楚。规范写了不算,演习过了才算。把演习列入预发清单,比再写一篇容器原理有用。
围绕「生命周期演习是否做过」,把四条路径再过一遍。表里每格都是可执行判断,不是形容词。读完请把你的项目钉进一格,不要钉在两格之间假装都占了。
| 检查项 | 纯 prompt | 通用 Agent | 规则引擎 | Parlant |
|---|---|---|---|---|
| 决策权放哪 | 到处创建客户端 | 模块级全局客户端 | 静态工厂 | 类型声明注入 |
| 改口径谁动手 | 测试打真实模型 | 测试也走规划循环 | 测试要起中间件 | 单测注入模拟网关 |
| 行动如何被拦 | 环依赖拖到运行时 | 错误堆栈难读 | 配置复杂 | 注册期查环 |
| 出事如何复盘 | 会话状态全局一份 | 记忆对象串用 | 会话在服务器会话里 | 上下文必须作用域 |
| 口语进得来吗 | 绑定靠口头 | 环境差异靠if | 配置文件切换 | 三列绑定表 |
| 上线第一周验什么 | 启动能跑就行 | 懒加载掩盖失败 | 启动较重 | 启动校验依赖图 |
串话演习能说服不信 IoC 的人。看见两个城市天气对调,才懂单例不是省事而是事故。演习列入预发,比再讲容器原理有效。
自适应绑定与强化学习调依赖留在研究向。生产先把层级用对。智能体已够难观测,容器再自学,锅会分不清。
在「依赖注入生命周期」上,纯 prompt 把判断写进一段话,改的人必须会改提示,复盘只能翻聊天,口语进得来但口径会漂。通用 Agent 把判断交给循环,灵活的代价是越权与路径不可复现。规则引擎把判断写进分支,确定的代价是口语进不来、改口径要排期。Parlant 把判断写成指南与契约:业务改口径,未授权则无行动,复盘指轨迹。把这四句贴到工位上,比再记一组术语有用。
针对依赖注入生命周期,本周只做一件可验收的事:找出一条真实对话或工单,标注它今天落在哪一列;若要迁到第四列,缺的是指南、工具还是关系边。缺指南就写草稿,缺工具就列契约,缺关系就补消歧或依赖。不要同时开十条战线。最常见的伪装是文件名叫指南、真源仍是提示词,或者架构图上有网关、运行时模型仍直接调函数。用「改文本能否改行为」和「低权限点名是否被拒」两张试纸识破。识破了再谈优化与案例。优化在伪装上加速,只会让错误承诺更多;案例在伪装上复制,只会把新闻变成事故。
依赖注入生命周期的纪律是先钉列,再谈快。钉列需要抽检,抽检需要轨迹,轨迹需要审计真的在记抑制原因,而不只记最终回复。若没有抑制原因,排错会以为没写规则,其实是优先级压了。看得见「为什么没走另一条路」,才叫对照,才叫可控。把这句话写进值班手册,依赖注入生命周期才从概念变成岗位。对照驱动不是文风,是岗位制:模型是引擎和笔杆子,方向盘在指南与工具契约上。谁把方向盘又塞回提示词,谁就在依赖注入生命周期上退回第一列。
下一节把「能换的零件」里最危险的一类单独对照:工具。谁有权调用,比怎么注入更致命。