本文档用于定义 SparkCore 当前阶段 single-agent runtime 的标准输入输出 contract。
本文档不重复 runtime 的整体职责边界,而重点回答:
- runtime 的标准输入对象是什么
- runtime 的标准输出对象是什么
- role、memory、session 如何被 runtime 消费
- output 为什么必须先收口,才能继续做接入层与产品层
状态:当前有效 对应阶段:Phase 1 相关文档:
docs/architecture/single_agent_runtime_design_v1.0.mddocs/architecture/runtime_input_contract_v1.0.mddocs/architecture/runtime_event_catalog_v1.0.mddocs/architecture/role_layer_design_v1.0.mddocs/architecture/memory_layer_design_v1.0.mddocs/architecture/session_layer_design_v1.0.mddocs/engineering/phase1_adjustment_execution_plan_v1.0.md
runtime contract 是 SparkCore 当前阶段 single-agent runtime 对外暴露的统一输入输出协议,用于确保接入层、产品层和底座层都围绕同一套运行时对象协作。
当前阶段 runtime contract 目标是:
- 固定 runtime 的统一入口
- 固定 runtime 的统一输出包
- 明确 role / memory / session 的消费方式
- 为 IM adapter 与产品层提供统一调用面
当前阶段 runtime contract 不负责:
- 多 Agent 编排协议
- 产品 UI contract
- 具体 IM 平台 SDK 事件格式
- 复杂任务编排协议
当前建议统一为:
RuntimeTurnInput
其最小结构应遵循 actor / message / context 三块分层:
type RuntimeTurnInput = {
actor: {
user_id: string
agent_id: string
thread_id: string
workspace_id?: string | null
}
message: {
content: string
message_type: "text"
source: "web" | "im" | "scheduler" | "internal"
timestamp?: string
message_id?: string | null
metadata?: Record<string, unknown>
}
context?: {
source_platform?: string | null
binding_id?: string | null
trigger_kind?: string | null
}
}最小必需字段:
actor.user_idactor.agent_idactor.thread_idmessage.contentmessage.message_typemessage.source
说明:
RuntimeTurnInput只表达原始外部输入- 不建议把
RoleProfile / SessionContext / MemoryRecallResult直接塞进原始输入对象 - 这些对象应在 runtime 入口或邻近装配层被加载
runtime 在处理一轮时,至少要消费:
RoleProfile / role_core_packetSessionContextRuntimeMemoryContext
这三者不是 runtime input 原始字段本身,但属于 runtime 必须加载与组织的标准依赖对象。
当前更稳的分层是:
- 外部入口传入:
RuntimeTurnInput - runtime 内部装配得到:
PreparedRuntimeTurn
当前建议统一为 RuntimeOutput。
最小字段:
assistant_messagememory_write_requestsfollow_up_requestsruntime_eventsdebug_metadata?
当前建议最小字段:
rolecontentlanguagemessage_typemetadata?
它回答的是:
这一轮最终应该返回给用户的内容是什么
当前实现补充:
assistant_message.metadata已开始进入统一 builder 收口:apps/web/lib/chat/assistant-message-metadata.ts
runtime.ts当前已不再直接内联拼接整块 assistant metadata,而是开始通过统一 builder 生成- 当前 metadata shape 已开始出现最小分组,例如:
model_profilelanguageanswer_strategysessionmemory
- 但当前仍刻意保留一批关键平铺字段,用于兼容:
- smoke tests
- quality eval
- session continuity 邻近读取面
- 当前最靠近 runtime 的读取面也已开始按兼容方式消费 grouped shape,例如:
session-context.ts已开始优先读metadata.language.detectedsmoke.ts的 continuity helper 已开始优先读metadata.language.detectedchat-thread-view.tsx的 runtime summary 已开始优先读model_profile与memory
- smoke 生成的 assistant metadata 当前也已开始补出兼容式 grouped shape,例如:
model_profilelanguagesessionmemory
- 当前 assistant metadata 这条线也已出现更明确的共用层:
- 统一 builder
- 统一 grouped/fallback read helper
- Web / IM 两侧的 runtime preview metadata 当前也已开始共用:
- builder
- updater
- runtime user message metadata 当前也已进一步收口到真实 persistence 入口,而不再额外依赖单独小 builder 壳
- follow-up claim 当前也已进一步收口为 repository 直接 claim,而不再额外依赖单独 claim wrapper
- 因此当前 assistant metadata 的状态应理解为:
- 已开始统一收口
- 已开始形成 grouped shape
- 读写两侧都已开始进入 grouped shape
- preview metadata 也已开始进入统一 helper
- 但仍处在兼容式过渡阶段
当前建议为数组。
每项应符合 MemoryWriteRequest contract。
它回答的是:
这一轮结束后,哪些长期记忆候选需要写入或更新
当前实现补充:
- runtime 顶层暂不新增
relationship_write_requests relationship memory先收口为memory_write_requests内的显式 subtype- 当前 request 至少分为:
kind = "generic_memory"kind = "relationship_memory"
这样可以先把 relationship 的旁路写入收回统一 pipeline,而不扩张新的顶层协议面。
当前建议为数组。
最小字段可包括:
kindtrigger_atreasonpayload
它回答的是:
这一轮是否需要后续提醒、延迟跟进或 scheduler 回流
当前实现补充:
- runtime 当前已能产出最小
gentle_check_inrequest - 当前先通过 executor stub 消费并返回显式
FollowUpExecutionResult - 当前结果状态至少包括:
acceptedskippedunsupportedinvalid
- 当前阶段不涉及真实持久化或真实调度
当前建议为数组。
用于承载运行过程中的标准事件,例如:
memory_recalledmemory_write_plannedanswer_strategy_selectedfollow_up_planned
当前实现补充:
runtime_events已开始承接最小thread_state_writeback_completed事件- 当前最小 event catalog 也已开始明确收口为:
memory_recalledmemory_write_plannedfollow_up_plannedanswer_strategy_selectedassistant_reply_completedthread_state_writeback_completed
RuntimeEvent现在也已开始从裸payload收成更明确的 typed union- 当前 event payload 命名也已开始做第一轮规范化,例如:
memory_recalled.countanswer_strategy_selected.strategyanswer_strategy_selected.reason_codeassistant_reply_completed.recalled_count
- IM adapter / harness 这一侧也已开始对齐这层 typed runtime event 约束
- 当前边界判断也已开始明确:
runtime_events负责“本轮发生了什么标准过程”debug_metadata负责“这轮为什么这样、有哪些最小调试摘要”
它主要服务:
- debug
- observability
- 后续 eval
当前可选。
用于承载:
- recall summary
- role packet summary
- answer strategy label
- continuity signal
- provider/model details
当前实现补充:
debug_metadata已开始承接最小thread_state_writeback摘要answer_strategy*现在也已开始进入最小分组收口:debug_metadata.answer_strategy.selecteddebug_metadata.answer_strategy.reason_code
memory*现在也已开始进入最小分组收口:debug_metadata.memory.recalled_countdebug_metadata.memory.write_request_count
follow_up*现在也已开始进入最小分组收口:debug_metadata.follow_up.request_count
session / continuity现在也已开始进入最小分组收口:debug_metadata.session.continuation_reason_codedebug_metadata.session.recent_turn_countdebug_metadata.session.context_pressure
- 当前更适合继续承接:
- 局部原因
- 计数摘要
- 当前还不值得升级成标准 event 的调试信息
它不应成为业务主逻辑依赖,但应作为当前阶段的重要调试位。
如果 runtime 只返回 reply_text,后续:
- IM adapter 会自己发明 follow-up 结构
- 产品层会自己发明 memory write 结构
- runtime 会再次被污染
因此当前必须先收口 RuntimeOutput。
- 是否发给 IM,由接入层负责
- 是否展示给用户,由产品层负责
- runtime 只负责标准产物
这样才能:
- 便于调试
- 便于重放
- 便于后续接入层复用
- 接收
RuntimeTurnInput - 加载
RoleProfile - 加载
SessionContext - 加载
RuntimeMemoryContext - 组装推理上下文
- 进入统一运行入口
- 生成
assistant_message - 产出
memory_write_requests - 产出
follow_up_requests - 返回
RuntimeOutput
当前阶段补充:
- 外层可选调用
executeFollowUpRequests(...)消费这些 request - 记录
FollowUpExecutionResult作为 debug / observability 元数据
当前 runtime 相关逻辑主要集中在:
apps/web/lib/chat/runtime.ts
当前 input 相关设计已在独立文档中收口:
docs/architecture/runtime_input_contract_v1.0.md
当前已有:
- role packet 组装倾向
- answer strategy 逻辑
- memory recall 消费
- reply 生成
RuntimeOutput已以代码形式初步落地assistant_message已有统一最小字段memory_write_requests已有最小 planner outputfollow_up_requests已有最小 planner outputruntime_events已有标准事件类型雏形
当前代码中的主要落点已包括:
apps/web/lib/chat/runtime-contract.tsapps/web/lib/chat/runtime.tsapps/web/lib/chat/memory-recall.tsapps/web/lib/chat/memory-write.ts
当前已落实的最小输出事实:
generateAgentReply(...)已返回统一RuntimeTurnResultassistant_message当前至少包含role / content / language / message_type / metadatamemory_write_requests当前已能产出profile / preference的建议写入请求follow_up_requests当前已能产出最小gentle_check_in请求actions.ts已开始消费统一输出对象,而不是只依赖隐式副作用
当前仍缺:
RuntimeInput的独立 contract 文档化RuntimeInput到调用方入口的完全统一memory_write_requests与真实执行器之间的进一步解耦与标准化follow_up_requests与 scheduler / adapter 的真实接线runtime_events事件字典与 payload schema 的进一步固定
RuntimeInput最小字段已固定RuntimeOutput最小字段已固定assistant_message / memory_write_requests / follow_up_requests / runtime_events / debug_metadata的角色已明确- runtime 与 role / memory / session 的输入边界已明确
- 接入层与产品层都可以围绕这一 contract 设计,而不再自行发明结构
当前代码进度补充判断:
RuntimeOutput已不是纯文档概念,而是已有第一版可执行实现- 当前仍属于“最小 contract 已落地,细部 schema 继续收口”的阶段
当前阶段最需要先做稳的 runtime contract,不是“模型怎么调得更聪明”,而是:
让所有下游都围绕同一套输入输出对象协作。
只有先把 contract 收口,接入层、产品层与底座层才不会继续互相污染。