
人工智能AI AgentAgent 框架DeepSeek【免费下载链接】deepseek-harnessDeepSeek Harness: Everything is a Plugin.项目地址https://gitcode.com/gh_mirrors/de/deepseek-harness点击查看免费下载本文系统阐述 DeepSeek HarnessREADME.md微内核插件体系中的事件域语义Event-domain Semantics设计session/*作为可持久、可重放的“事实日志”agent/*作为携带实时Agent句柄的“实时通道”以及二者之间唯一的分界规则——一切可持久可重放的事实必须落在会话日志上任何实时拦截或瞬态信号只能走 Cordis 事件。阅读本文后你将掌握三个事件域各自承载的事件类别、turn/step 边界镜像事件被移除的来龙去脉以及插件作者应当如何正确选择订阅通道session/event还是agent/*。本文内容以 .agents/notes/implemented/architecture/2026-06-30-event-domain-semantics.md 为核心骨架结合仓库内事件类型定义、会话追加实现、agent 循环派发源码与相关 Agent Notes 展开。背景为什么需要把事件域钉死DeepSeek Harness 的产品原则是 “everything is a plugin”一切皆插件hooks、/goal、动态工作流、compaction、沙箱、权限、UI、持久化、MCP、skills 都必须能以插件方式编写而无需修改核心见 微内核事件分类学 Agent Note。这一原则的落地方式是纯粹的 Cordis 事件分类学agent 循环的扩展点全部由带明确派发模式waterfall / serial / parallel / emit的强类型事件构成。随着事件分类学不断增长三个事件域之间的界线开始模糊session/*承载持久化、事件溯源event-sourced的日志由SessionEventMap定义agent/*承载实时运行时信号把Agent句柄交给插件tools/*承载工具注册表与执行流水线。由此产生两个必须澄清的问题其一同一事实有两个真相源。若干 turn/step 边界同时以两种形态存在既是持久化的SessionEventturn/start、turn/end、step/start、step/end又被镜像发射为agent/*事件agent/turn-start、agent/turn-end、agent/step-start、agent/step-end。消费方面对同一事实的两个来源每次生命周期改动都必须同时更新两处。其二Hooks 子系统需要一个统一、有文档可查的订阅面。插件作者以及构建在其上的 Claude Code / Codex hook 桥必须在不阅读 agent 循环源码的前提下知道某个事件该监听 session 事件还是 agent 事件以及为什么。这套词汇是拦截决策、持久化的hook/*日志以及 Claude Code / Codex 桥的共同基石。本文讨论的决策与实现均已落地Status: implemented。核心决策三个域、一个职责、一条分界规则三个事件域各司其职session/*— 可持久、可重放的事实日志。它是SessionEventMap的拥有者每一条目只允许 JSON 数据不允许任何实时对象。每追加一条记录对应一次session/event发射外加session/flush并行持久化检查点。它同时也是实时转录流live transcript feed任何想要渲染或响应“发生了什么”的消费者都在这里订阅因此实时渲染与重放投影共用同一条路径。agent/*— 实时运行时表面。总是携带实时Agent对象。拦截瀑布agent/pre-step、agent/request、agent/request-error负责转换、拒绝或恢复被 await 的agent/turn-stopping观察停止边界瞬态发射报告生命周期、状态、inbox 插入/认领/丢弃以及错误。turn 与 step 边界不在这里——它们是持久化的 session 事件从session/event读出token 流assistant/chunk与轮中转向user/message同样如此。tools/*— 工具注册表与执行流水线。唯一分界规则一个可持久、可重放的事实就是SessionEvent一个实时拦截或瞬态/实时对象信号就是agent/toolsCordis 事件。turn 或 step 边界是持久化事实因此它活在会话日志中从session/event订阅流中读取——绝不被镜像为agent/*发射。把这条规则套用到“边界孪生事件”上结论很直接四个边界镜像agent/turn-start、agent/turn-end、agent/step-start、agent/step-end全部移除。没有任何生产消费者需要边界上的实时AgentACP 桥用确切的session/eventturn/start/turn/end事件对来关联其进行中的 prompt其他转录消费者同样从持久化流中推导边界。完整的移除决策由 移除边界镜像事件 Agent Note 拥有。移除发射同时也简化了循环的closeStep/closeTurn——各只需一次追加不再有配对发射。源码实证会话日志与实时通道的边界在代码中如何体现SessionEventMap事实日志的完整词汇表事件域语义的落点在packages/core/session/src/types.ts的SessionEventMap类型定义。它是session/*域的契约核心每个键都配有一段文档注释说明其持久化语义例如事件类型数据载荷语义要点turn/start{ turn: number }在循环认领排队输入或运行 pre-step 之前打开 turnturn拒绝、空输入、取消或失败可能在无 step 的情况下关闭它turn/end{ turn: number; reason: TurnEndReason }以结束原因关闭 turn没有进入 step 的 turn 不产生step/start/step/end循环在 turn 边界不 await flushdsh-session-checkpoint-policy负责每次请求的持久化检查点step/start{ turn: number; step: number }打开 turnturn的 stepstep——一次模型调用及其请求的工具执行step/end{ turn: number; step: number }关闭对应 stepuser/messageUserMessage模型可见表面上的 user 角色消息source区分直接人类提示、合成agent.inject()上下文文件变更通知、子目录 AGENTS.md、skill 内容、cron 通知等与目标延续轮assistant/chunk{ turn, step, chunk: StreamChunk }原始流分块token 级重放保真度assistant/message{ turn, step, message, usage?, interrupted? }单 step 组装完成的助手消息usage跟随模型输出一起落账取消的流以interrupted: true结束其已交付前缀tool/call{ turn, step, callId, name, arguments }模型请求一次工具调用arguments为模型产出的原始 JSON 字符串不解析callId与tool/result配对tool/result{ turn, step, message, error?, meta? }完成调用的模型可见结果meta对核心不透明但必须可 JSON 序列化见下request/header{ header, reason, startsSeries? }下一次请求的完整头部仅日志用途最新快照重建请求头request/contextRequestContext路由元数据仅在路由或容量变化时记录session/end-seedRecordstring, never构造函数 seedresume/fork/replay结束的标记空载荷该接口把“每一条目都是 JSON-only”写进了类型层SessionEventType keyof SessionEventMapSurfaceEventType则进一步限定只有user/message、assistant/message、tool/result可以携带SurfaceOp和sourceEventSeqs出现在有序表面上。Session.appendJSON-only 强制与边界后观察者隔离“事实日志只收 JSON”不是口头约定而是Session.append的运行时强制。在 packages/core/session/src/index.ts 中追加流程依次对data做snapshotJsonValue(data)快照若返回undefined则直接抛出session event ... carries non-JSON-serializable data——实时对象在这里就被拒之门外通过assertSupportedRequestHeader校验 request header构造deepFreeze的不可变事件含type、seq、time、data由surfaceManager.validateNext做表面校验this.log.push(event)入日志随后才通过collectSessionCallbacksinvokeContainedSessionObservers触发session/event观察者。注意顺序先入日志、后触发观察者。这就是文档所说 “Session.append拥有提交后post-commit观察者隔离” 的实现基础——抛异常的边界观察者无法改变 turn 结果也不会饿死后续消费者而接受性/内部校验失败会在边界进入日志之前逃逸。状态entry.appending同时防止追加在另一个追加发布期间重入。循环侧边界只追加不镜像在 agent 循环实现 packages/core/agent-loop/src/agent.ts 中可以看到边界事件与实时事件的分工turn()在认领首个 step 之前先this.session.append(turn/start, { turn })turn() 打开边界捕获失败并throwError只有append(turn/start)返回后循环才把phase.turn turn置位、标记 step 打开stepOpen true。内部派发校验先于日志推送执行可能在不打开 step 的情况下拒绝因此stepOpen标记精确代表“已提交、尚欠一个step/end”的边界。preStep()走this.dispatch.waterfall(agent/pre-step, { messages: claimed, ...position, signal }, ...)preStep 拦截瀑布——这里就是“实时拦截走 agent 事件”的代码位置waterfall 语义允许插件next()转换、短路或拒绝decision.kind reject时 turn 以blocked结束。请求侧同理agent/request请求瀑布在无 provider/model 时兜底抛错agent/request-error处理请求失败停止边界则由this.dispatch.serial(agent/turn-stopping, { turn, signal })以串行listener 顺序 await方式观察。一个直观的对照边界turn/start的代码是“追加进日志”而拦截agent/pre-step的代码是“派发 waterfall”——两者各自只出现在属于自己的那条通道上没有配对发射。这正是移除边界镜像后循环变简单的直接证据。移除边界镜像事件的完整时间线围绕session/event单一真相源仓库里有一串彼此咬合的决策记录构成一个完整的演进链2026-06-11— 微内核事件分类学 确立了 Cordis 事件分类学与四种派发模式并声明“持久化 session 事件拥有 turn 与 step 边界”。2026-06-20— 停止把持久化边界镜像为 agent 事件 移除全部四个边界镜像。该决策把dsh-ui-stdio重新定位为“可丢弃的测试 REPL”——它从session/event渲染边界只在需要Agent句柄做[main turn N]标题时保留agent/created/agent/disposed的实时目标对象。它同时明确了范围之外保留的事件agent/steering、agent/stream-chunk、agent/created/disposed/status/error/queued。特别注意agent/queued——它是 inbox 确认在任何持久化事件存在之前就会发射被取消的排队工作可能永远不进日志因此刻意只实时。2026-06-30— 本文主文档 事件域语义 把上述实践提炼为三条域职责 一条分界规则成为后续所有移除的语义依据。2026-07-02— 停止把 token 流镜像为 agent 事件 移除agent/stream-chunk。代码证据很直白——原实现在 packages/core/agent-loop/src/agent.ts 中两行相邻const chunkEvent session.append(assistant/chunk, { turn, step, chunk }) chunkSeqs.push(chunkEvent.seq) ctx.emit(agent/stream-chunk, agent, turn, step, chunk) // ← the mirror唯一的真实消费者dsh-ui-stdio连Agent句柄都用不上签名是(_agent, _turn, _step, chunk)高保真重放、部分失败流与快照重放全部依赖持久化的assistant/chunk于是镜像被删除session/event成为唯一的实时转录流。2026-07-04— 移除agent/steering镜像发射 移除最后一个瞬态镜像。原实现里drainSteering先追加持久化的steering/message { turn, content, source }紧接着发射携带完全相同事实的agent/steering且零生产监听者唯一订阅方是断言source的循环回归测试——而同一事实在持久化事件里已经记录。转向携带真实生产流量hook 桥的 turn 延续决策通过inbox.steer()注入落为持久化steering/message所有消费方本来就观察持久化事件。删除后转向的入队时通知仍有agent/queued带steering标志排空时通知则由session/event上的steering/message承担。至此“每个可持久事实有且只有一个通道”的收敛完成。从源码结构看agent/*上剩下的都是确实没有持久化孪生的实时控制信号生命周期、状态、错误、inbox 确认、拦截瀑布、停止观察点而转录数据边界、token 流、转向、工具活动全部收敛到session/event一条流上。持久化的hook/*日志分界规则的直接受益者事件域语义文档指出这套词汇是“持久化hook/*日志”的基石。hooks 子系统在 packages/hooks/hook-protocol/src/events.ts 中实践了同一条规则session.append(hook/invoked, { ... })追加一个命名 handler 与 hook 点的hook/invoked事件到 session文档明确“不在 turn 之外追加hook/*”session.append(hook/result, { ... })追加与hook/invoked配对的持久化结果记录决策与墙钟耗时durationMs。对应的不变量在 packages/hooks/hook-protocol/src/invariant.ts 中钉死hook/invoked的 point 与 handlerId 非空、dialect 已知hook/result必须能找到配对的hook/invokeddurationMs必须是非负有限数。这正是“可持久事实走 session 日志”在 hooks 场景的具体应用——hook 的调用与结果不是瞬态通知而是必须能回放审计的记录所以它们进session而不是作为瞬态 Cordis 事件发射。插件作者订阅指南该听哪个通道综合文档与源码给出一个可直接照抄的决策流程这个信号是可持久、可重放的事实吗比如一次 turn/step 边界、一条 user/assistant 消息、一次工具调用或结果、一次 token 流、一次转向 → 订阅session/event。边界从turn/start/turn/end/step/start/step/end读取token 流从assistant/chunk读取轮中转向从user/message或转向控制记录读取。需要实时Agent句柄时用agent/created/agent/disposed保留目标对象并通过共享 id如ctx.agents解析而不是在边界事件里拿。这是一个实时拦截点吗需要在模型调用前转换/拒绝/恢复请求 → 订阅 waterfall 事件agent/pre-stepstep 准备可返回enter/reject决策、agent/request、agent/request-error、tools/pre-execute/tools/execute/tools/post-execute、llm/stream、system-prompt/assemble。这是一个需要按顺序 await 的检查点吗→ 订阅 serial 事件例如agent/turn-stopping停止边界观察。这是需要每个监听者独立机会的持久化检查点吗→ 监听session/flushparallel 扇出。这是一个不需要回放的瞬态通知吗生命周期、状态、错误、inbox 插入/认领/丢弃 → 订阅对应的 emit 事件如agent/created、agent/disposed、agent/status、agent/error、agent/queued。agent/queued尤其特殊它在任何持久化事件之前发射被取消的排队工作可能永远不进日志因此只实时。容易踩坑的三条不要在agent/*上找边界。agent/turn-start等四个镜像已经不存在再依赖它们只会读到空。不要重复记账。同一事实边界、chunk、转向从session/event读一次即可session/event是实时渲染与重放投影共享的单一转录流。payload 必须 JSON-only。给session.append传实时对象会在 Session.append 的snapshotJsonValue校验处被拒绝——这是硬错误不是警告。结语事件域语义是 DeepSeek Harness 微内核插件体系的一条总纲式约束session/*是唯一的事实日志与实时转录流agent/*是唯一的实时拦截与瞬态信号通道tools/*负责工具注册与执行。两者之间没有灰色地带——分界规则可持久可重放 → session实时拦截/瞬态 → agent/tools就是判定标准。理解这条规则是正确编写 Hooks 插件、ACP 桥、Claude Code / Codex 桥以及任何需要观察 agent 循环行为的插件的第一步仓库内的事件类型定义SessionEventMap、追加实现Session.append与循环派发agent.ts提供了可逐行核对的实现证据。进一步阅读事件域语义 Agent Note本文主文档微内核事件分类学 Agent Note停止把持久化边界镜像为 agent 事件移除agent/steering镜像发射hook 协议事件实现赞分享人工智能AI AgentAgent 框架DeepSeek【免费下载链接】deepseek-harnessDeepSeek Harness: Everything is a Plugin.项目地址https://gitcode.com/gh_mirrors/de/deepseek-harness点击查看免费下载相关推荐DeepSeek Harness 事件边界收敛移除 agent/* 边界镜像事件让 session/event 成为唯一事实流DeepSeek Harness 事件边界收敛移除 agent/ 边界镜像事件让 session/event 成为唯一事实流 本文基于仓库内 Agent N人工智能AI AgentAgent 框架DeepSeekDeepSeek Harness 事件精简实践移除 agent/stream-chunk 镜像事件让 session/event 成为唯一 Token 流事实源DeepSeek Harness 事件精简实践移除 agent/stream chunk 镜像事件让 session/event 成为唯一 Token 流事人工智能AI AgentAgent 框架DeepSeekDeepSeek Harness 事件架构演进Agent 作用域事件统一为单 payload 对象的设计实践DeepSeek Harness 事件架构演进Agent 作用域事件统一为单 payload 对象的设计实践 导读 本篇技术文章基于 DeepSeek Har人工智能AI AgentAgent 框架DeepSeek创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考