选择扩展点与修改边界
先判断你要改变的是 Agent 能做的动作、当前模型输入、调用过程,还是运行控制。选择最接近目的的接口,可以让改动保持在一个领域内。
应用扩展还是框架改动
| 需求 | 首选入口 | 通常是否需要修改 Iris 源码 |
|---|---|---|
| 增加项目查询或外部业务操作 | Python 工具或 MCP | 否 |
| 给每步提供编辑器当前状态 | ContextSource | 否 |
| 在工具前后做固定处理 | Hook 或工具 Middleware | 否 |
| 记录已提交事件 | RunEventObserver | 否 |
| 使用另一种模型实现 | CompletionProvider,按需实现 StreamingProvider | 否 |
| 替换 lifecycle 持久化后端 | LifecycleStore | 通常可在宿主实现,但须完整满足当前契约 |
| 改变模型步骤或恢复语义 | runtime + harness + lifecycle 的实际 owner | 是 |
| 添加新的标准消息类型 | message + provider + 持久化/相关使用路径 | 是 |
操作例子见工具、动态 context、扩展。这里说明修改框架时还要考虑哪些边界。
新配置从一个解析入口进入
外部 YAML 在配置模型解析为 typed 对象。新增字段应声明类型、默认值和必要的组合约束,再由装配层把它交给拥有该行为的组件。不要在 runtime、工具和宿主各自读取同名环境变量。
已完成校验的数据进入内部运行后,下游直接消费 typed 对象。持久数据读回时重新解析;状态转换只验证本次改变涉及的条件。这样能明确问题究竟发生在输入、状态转换还是恢复边界。
扩展工具要保留哪些契约
先决定工具描述、参数 schema、结果和它需要的执行上下文。模型看到的工具定义属于 ToolSpec,执行策略仍在工具系统。工具结果可以携带文字或图片,不能把所有 content 当作字符串。
若增加公共内置工具,还要同步 YAML 注册名、模型调用名、对应测试和工具参考。同一个名称不一定贯穿所有层,例如声明式 file.read 对应模型调用 read_file。
改变普通工具执行时,保留权限、调用 claim、middleware、artifact 与提交之间的正确顺序;不要通过重跑一个结果未知的副作用来“补齐成功输出”。详细正常流程见工具设计。
修改持久状态时保持一个权威来源
如果需求改变一个 Run 的状态,先在 lifecycle 定义所需数据与操作,再由 store 实现其一致性。Runner 负责在正确时机调用这些操作,runtime 用 commit port 交付事实。
内存与 SQLite 后端需要满足相同的新契约,调用方和测试替身也一起迁移。不默认增加旧签名探测、异常后旧调用重试或数据迁移分支。
这不意味着可以删掉修订号、activation fence 或恢复检查。它们保护真实状态转换与执行所有权,和对同一 typed 字段反复校验不是一回事。
模型和媒体改动需贯穿真实路径
新增内容类型时,至少检查输入、历史、工具结果、provider 请求投影、存储读回,以及压缩后的回读。能显示文件链接只说明宿主能展示文件,不能证明模型收到了内容。
流式改动还要区分部分结果和完整完成:增量显示不能提前触发工具执行或提交成功模型步骤。对应结构见模型参考与流式设计。
收尾应与改动一致
扩展后运行相关测试,补足必要示例,更新受影响的使用页、精确参考和设计解释。无需为了新增一个工具改写全站,也不应仅更新源码而让公开参数表继续描述旧契约。具体检查入口见测试指南。
