CopilotKit Runtime 中 AgentRunner 怎么选:InMemory、Sqlite 与 Intelligence

发布时间:2026/9/11 17:53:08

CopilotKit Runtime 中 AgentRunner 怎么选:InMemory、Sqlite 与 Intelligence CopilotKit Runtime 中 AgentRunner 怎么选InMemory、Sqlite 与 Intelligence【免费下载链接】CopilotKitThe Frontend Stack for Agents Generative UI. React, Angular, Mobile, Slack, and more. Makers of the AG-UI Protocol项目地址: https://gitcode.com/GitHub_Trending/co/CopilotKit搭建 CopilotKit Runtime 时每个 runtime 都把 agent 执行和会话持久化委托给一个AgentRunner。runner 负责把POST /agent/:id/run变成一条 AG-UI 事件流记住 thread 以便POST /agent/:id/connect重新挂接并在需要时停止运行。选择或子类化runner 决定了对话状态存放在哪里进程内存、本地 SQLite 文件还是 CopilotKit Intelligence 平台。这篇文章给出三者的适用条件、配置写法和验证方式覆盖从本地开发到单实例上线再到多实例扩展的选型路径。AgentRunner 是什么、由谁承担AgentRunner是一个抽象类有四个方法与 runtime 的 HTTP 路由一一对应详见 AgentRunner and persistenceimport type { Observable } from rxjs; import type { BaseEvent } from ag-ui/client; abstract class AgentRunner { // 启动一次 run返回 AG-UI 事件流 abstract run(request: AgentRunnerRunRequest): ObservableBaseEvent; // 重新挂接到已有 thread 的流reconnect / 刷新页面 abstract connect(request: AgentRunnerConnectRequest): ObservableBaseEvent; // 该 thread 当前是否有活跃的 run abstract isRunning(request: AgentRunnerIsRunningRequest): Promiseboolean; // 停止该 thread 上正在进行的 run abstract stop(request: AgentRunnerStopRequest): Promiseboolean | undefined; }run接收threadId、克隆后的agent、AG-UIRunAgentInput以及persistedInputMessagesconnect接收threadId外加可选的 headers 和joinCode。thread 背后的存储由 runner 自己持有。不传runner时runtime 默认使用InMemoryAgentRunner。runner在CopilotRuntime上只配置一次对它的每个 agent 生效同一个 runner 处理所有已注册 agent 的run、connect和stop。按部署形态选 runner文档给出的内置 runner 及用途如下Runner导入来源适用场景InMemoryAgentRunnercopilotkit/runtime/v2v2 默认 runner。thread 保存在进程内存中用于本地开发、单实例部署或作为扩展基类SqliteAgentRunnercopilotkit/sqlite-runner第一方文件级持久化 runner。thread 运行记录写入 SQLite 文件单实例重启后历史仍在。需要better-sqlite3peer 依赖和一个真实非:memory:的dbPathIntelligenceAgentRunnercopilotkit/runtime/v2为 CopilotKit Intelligence 提供持久化 thread、跨实例持久化和 threads/history 功能。在 Intelligence runtime 上自动使用TelemetryAgentRunnercopilotkit/runtime旧版包装行为。根 runtime 在开启遥测时会在 runner 外组合遥测层copilotkit/runtime/v2不这样做据此可以按三条主路径决策本地开发或单实例、不要求重启后保留历史保持默认的InMemoryAgentRunner。单实例生产部署要求重启后历史仍在换成第一方SqliteAgentRunner。多实例水平扩展使用 CopilotKit Intelligence 的IntelligenceAgentRunner或者自己提供一个基于共享数据存储的 runner文档建议的子类化路径见后文。InMemoryAgentRunner的历史在重启时丢失、进程运行期间有界见下文边界配置且不在多实例间共享。这三点就是它不能作为多实例方案的依据。配置 InMemoryAgentRunner 并给内存历史上界最小配置以 Next.js App Router 为例import { CopilotRuntime, BuiltInAgent, InMemoryAgentRunner } from copilotkit/runtime/v2; const runtime new CopilotRuntime({ agents: { default: new BuiltInAgent({ model: openai/gpt-4o-mini }) }, // 显式声明省略时也是这个默认值 runner: new InMemoryAgentRunner(), });InMemoryAgentRunner把每个 thread 的运行历史放在一个进程级全局 store 中。该 store默认就有上界长生命周期服务会驱逐旧历史而不是把 Node.js 堆撑爆。当默认值不匹配你的负载时通过构造函数传入限制import { CopilotRuntime, BuiltInAgent, InMemoryAgentRunner } from copilotkit/runtime/v2; const runtime new CopilotRuntime({ agents: { default: new BuiltInAgent({ model: openai/gpt-4o-mini }) }, runner: new InMemoryAgentRunner({ maxThreads: 200, maxRunsPerThread: 50, maxBytes: 128 * 1024 ** 2, // 128 MiB }), });选项默认值约束对象maxThreads1000保留的不同 thread 数量。超限时整个丢弃最近最少使用的 threadmaxRunsPerThread100每个 thread 保留的 run 数按最旧优先驱逐。设为Infinity或0会关闭该上限——这是唯一的按线程边界maxBytes只驱逐其他 thread单个热 thread 会无限增长文档建议改为一个较大的有限值maxBytes536870912512 MiB所有 thread 保留历史的近似总大小是主要防线两个计数是次要的保险上限哪个边界先触发哪个生效。两条规则保证驱逐安全有活跃或仍在收尾的 run 的 thread 永远不会被驱逐即使这意味着暂时超限。maxBytes是跨 thread 的上限它驱逐其他最近最少使用的 thread从不裁剪刚结束 run 的 thread。单个热 thread 只受maxRunsPerThread约束不受maxBytes约束。驱逐有两种形式移除的内容和影响范围不同整 thread 驱逐整体丢弃最近最少使用的 thread——所有 run、事件和该 thread 的消息快照。maxThreads和maxBytes都会触发它。被驱逐的 thread 不再出现在GET /threads中后续connect()也没有任何内容可回放。run 上限裁剪maxRunsPerThread只丢弃单个超上限 thread 的最旧 runthread 本身保留。该 thread 仍出现在GET /threads中、保留原始创建时间最新消息快照和最新 run 都在——只有被裁剪 run 的事件消失了后续connect()回放剩余部分。任一形式触发时都会打一条单行警告然后保持安静。该警告每个 store 只锁存一次不是每次驱逐一次所以频繁的驱逐不会刷爆日志锁存只在 store 被清空clearThreads()/POST /threads/clear后复位之后最多再触发一次警告。把它当作正在发生驱逐的信号而不是逐条丢弃的审计记录。驱逐还会削弱该 thread 上的消息去重。run()通过扫描仍持有的 run 来剥离输入中已见过的消息一旦 thread 超过maxRunsPerThread且最旧 run 被丢弃只存在于被驱逐 run 中的消息就不再被识别为已见过后续connect()或run()可能再次呈现它客户端可能短暂显示一条已见过的历史消息。这是显示层面的现象不是数据损坏。如果某个 thread 绝不允许旧消息重新出现应迁移到持久化 runner或把maxRunsPerThread调大为有限值——不要设为Infinity或0那会移除唯一的按线程边界让单个长生命周期 thread 增长到堆耗尽。一个必须注意的坑这些限制是进程全局的。所有InMemoryAgentRunner共享同一个进程内存 store限制也一样——最后一个传入限制的 runner 生效于所有内存 thread会静默覆盖之前 runner 设置的边界。文档明确提示不要指望日志来发现这个问题覆盖警告只在传入限制的 runner 之后又出现另一个传入不同限制的runner 时才触发一个用默认值、第二个传自定义限制的常见场景属于首次显式覆盖不产生日志。一个进程里只配置一套一致的限制。设置上界防止的是崩溃不等于持久化。如果不能接受历史丢失就切换到下面的持久化后端。配置 SqliteAgentRunner 让历史在重启后保留SqliteAgentRunner来自copilotkit/sqlite-runner把 thread 运行记录持久化到 SQLite 文件单实例重启后历史仍在。使用前提有两个安装better-sqlite3peer 依赖包声明的版本约束是^12.2.0并提供一个真实的、非:memory:的dbPathimport { CopilotRuntime, BuiltInAgent } from copilotkit/runtime/v2; import { SqliteAgentRunner } from copilotkit/sqlite-runner; const runtime new CopilotRuntime({ agents: { default: new BuiltInAgent({ model: openai/gpt-4o-mini }) }, runner: new SqliteAgentRunner({ dbPath: ./data/threads.db }), });dbPath: ./data/threads.db是文档给出的示例路径指向一个可写目录下的真实文件。copilotkit/sqlite-runner要求 Node18。接入 CopilotKit Intelligence需要跨水平扩展实例共享历史时文档给的路径是 Intelligence 的IntelligenceAgentRunner在 Intelligence runtime 上自动使用或者自建共享数据存储 runner。接入托管平台的接线步骤见 Connect your runtime to Intelligence准备项目 API key。用 CLInpx copilotkit login npx copilotkit project selectproject select会把项目级 key 写入.env的CPK_INTELLIGENCE_API_KEY。该 key 是服务端机密不要加NEXT_PUBLIC_或VITE_前缀。构造CopilotKitIntelligence客户端并作为intelligence传给 runtime。runtime 从你传入的客户端读取 key不是从环境读import { CopilotRuntime, CopilotKitIntelligence, createCopilotRuntimeHandler, } from copilotkit/runtime/v2; const intelligence new CopilotKitIntelligence({ // apiUrl 和 wsUrl 默认指向托管平台不要设置 apiKey: process.env.CPK_INTELLIGENCE_API_KEY!, }); const runtime new CopilotRuntime({ agents, intelligence, // Threads 按用户隔离否则所有访客共享同一份历史 identifyUser: (request) ({ id: request.headers.get(x-user-id) ?? anonymous, name: request.headers.get(x-user-name) ?? Anonymous, }), }); export const { GET, POST } createCopilotRuntimeHandler({ runtime });apiKey是唯一必填字段key 本身限定项目范围不需要另传组织或 project id。agents是你的 agent 注册对象需自行替换为实际应用中的注册内容。如果是自托管部署apiUrl和wsUrl必须一起覆盖或都不覆盖——API 面和实时面部署在不同主机上websocket URL 无法从 API URL 推导只设一个会让另一面仍指向托管主机。传裸 websocket 基址即可客户端自己追加/runner和/client并给每个 REST 调用加/api前缀传apiUrl: .../api会产生/api/api/threads这样的双前缀。验证 runner 是否按预期工作文档给出的检查方式按 runner 分别对应InMemory / Sqlite用GET /threads查看当前保留的 thread。被整 thread 驱逐的 thread 会从这里消失被maxRunsPerThread裁剪的 thread 仍在列表中且保留原始创建时间。刷新或断线后用POST /agent/:id/connect重新挂接能回放的内容就是 runner 实际保留的历史——这正是验证持久化与否最直接的行为差异重启后 InMemory 为空Sqlite 仍能回放。Intelligence编译通过和聊天能回复都证明不了 Intelligence 在工作——runtime 在 SSE 模式下不读 key 也能做到这些。文档要求的验证方式是从产品侧确认打开云托管 dashboard在应用里发一条消息应该出现一个 thread没有出现就说明 runtime 根本没有连到平台实际仍跑在 SSE 模式。对应的排查表现象原因聊天正常dashboard 里没有 threadintelligence没有传给CopilotRuntimeruntime 处于 SSE 模式首个请求出现不透明的鉴权错误CPK_INTELLIGENCE_API_KEY为空或属于别的项目socket 停在connecting随后报 did not settle in time只覆盖了wsUrl或把它指向了 API 主机请求日志里出现/api/api/...apiUrl带了/api后缀并发 run 与自定义 runner 的边界当你的 UX 允许用户快速发送追问、或卡住的 run 需要被顶替时可以对并发的run()选择 supersede 语义默认行为是对同一 thread 的并发run()抛Thread already runningimport { InMemoryAgentRunner } from copilotkit/runtime/v2; const runner new InMemoryAgentRunner({ onConcurrentRun: supersede });取值行为throw默认同一 thread 上的并发run()抛出Thread already runningsupersede进行中的 run 被中止走stop()同一条路径新 run 开始被顶替 run 的部分输出被丢弃不写入历史与内存限制不同onConcurrentRun是按 runner的只作用于你传入它的那个 runner。需要共享数据存储或外部记忆层时最常见的定制方式是子类化InMemoryAgentRunner只覆盖需要的方法、其余调用superimport { InMemoryAgentRunner } from copilotkit/runtime/v2; export class MyRunner extends InMemoryAgentRunner { override run(request: ParametersInMemoryAgentRunner[run][0]) { // 在此持久化 request.threadId / input然后委托 return super.run(request); } override connect(request: ParametersInMemoryAgentRunner[connect][0]) { // 重新挂接前先从自己的存储恢复 thread return super.connect(request); } }这里有一个文档明确要求的边界情况如果connect()可能被调用在 runner 从未见过的 thread 上例如首次页面加载时的新 thread id必须显式处理否则POST /agent/:id/connect会在用户发消息之前返回 404 或报错。完整的生产级示例可参考仓库中的 AWS AgentCore 集成AWS AgentCore 文档 指向的/deploy/agentcore页面。限制小结InMemoryAgentRunner的历史重启即失、进程内不跨实例共享上界配置防止内存耗尽但不提供持久化。内存限制是进程全局的多个传限 runner 时最后一个生效且该场景通常无日志。SqliteAgentRunner解决单实例重启问题依赖better-sqlite3和真实dbPath跨实例仍需 Intelligence 或自建共享存储 runner。TelemetryAgentRunner属于copilotkit/runtime根入口的旧版组合行为copilotkit/runtime/v2不做这件事——新项目按 v2 方式配置 runner 和遥测。下一步若需了解每个 runner 方法对应的路由细节见 Runtime HTTP endpoints运行时整体配置见 Copilot Runtime。【免费下载链接】CopilotKitThe Frontend Stack for Agents Generative UI. React, Angular, Mobile, Slack, and more. Makers of the AG-UI Protocol项目地址: https://gitcode.com/GitHub_Trending/co/CopilotKit创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/9/11 18:58:20

同城O2O源码:部署包、库账号和导出脚本怎么验收

同城O2O源码私有化最容易停在口头:「代码都给你了」。真正可运维,要看三层清单能不能在客户环境逐项打勾——部署包能启能回滚、库账号在客户侧、导出脚本能空跑出字段。本文按架构说明给出分层验收清单与最小脚本示意,避免「交了目录却开不了…

2026/9/11 18:58:20

SAP Industry AI :从通用 AI 走向 Autonomous Enterprise 最关键的一步

过去两年,很多企业做生成式 AI 项目时都经历过一种很相似的落差。 在演示环境里,把一份采购合同、设备维修手册或者销售报表交给一个能力很强的大模型,模型往往可以完成摘要、问答、分类甚至推理。可一旦真正进入 SAP S/4HANA、SAP SuccessFactors、SAP Ariba、SAP Integra…

2026/9/11 18:58:20

C# Windows服务实现医保数据可靠传输

简介:本资源是一套基于C#开发的医保接口自动传输Windows服务程序,面向医疗信息化开发者、HIS系统集成工程师及.NET中级以上技术实践者,解决医疗机构与医保平台间患者信息、诊疗费用等关键数据的后台定时、稳定、无人值守式传输问题。压缩包共…

2026/9/11 18:58:20

从设备异常到自主执行,深度解读 SAP Industry AI 在油气能源资产管理中的 Agentic AI 架构

油气平台上的压缩机、泵、涡轮机、换热器或者海上生产设施,一旦出现异常,企业真正头疼的往往不是能不能发现一个异常点,而是发现之后,后面的业务流程能不能迅速跟上。 传感器可能已经发现振动值偏离正常区间,可靠性工程师也许能够判断设备状态正在恶化,可如果异常信息还…

2026/9/11 18:58:20

数据治理实战|基于ZCBUS解决运营商多源数据口径混乱、业务孤岛问题

运营商普遍存在业务系统繁多、数据分散、口径不统一、跨域数据无法联动等治理难题,传统ETL仅能完成数据同步,无法解决数据冗余、版本混乱、业务割裂问题。本文从数据治理、口径标准化、业务协同全新角度,分享ZCBUS在省级运营商的落地实践。通…

2026/9/11 18:53:20

智慧校园管理系统个性化定制:从用户配置表到动态路由的落地实践

简介:这套基于SpringBoot与Vue的个性化定制智慧校园管理系统项目包,面向需要完成毕业设计、课程实训或快速上手前后端分离开发的学习者。系统覆盖学生、教师、管理员三类角色,包含用户管理、课程与选课、考试管理、资源共享、个性化定制及后台…

2026/9/10 16:39:38

超人会飞不算本事:系统稳定依赖清晰规则与边界设计

开头先不绕弯子。“#斯坦李吐槽dc 所以超人是无缘无故会飞的嘛哈哈哈哈哈哈哈锤哥真是技术人才啊!#雷神 #复联”这类调侃式短标题,第一波冲击力在于它把两个宇宙的角色塞进同一个吐槽箱里,但细想一下就能发现,它真正碰到的根本不是…

2026/9/10 11:16:38

超人VS蜘蛛侠:拆解超级IP的影响力与传播方法论

把“蜘蛛侠 vs 超人”放在 CSDN 上聊,可能很多人第一反应是走错片场了。但如果把这两个角色看成“两个持续运营了 80 多年的文化产品”,你会发现,这场比较本质上是两个不同 IP 策略的长期结果对比:超人赢在定义了整个超级英雄题材…

2026/9/9 16:31:09

基于CNN的调制信号识别:MATLAB实现时频图分类实战

简介:本资源是一套面向通信工程与信号处理方向学习者、研究者的深度学习实践方案,聚焦调制信号自动检测与识别这一典型无线通信任务,解决传统方法依赖人工特征、低信噪比下性能下降等痛点。压缩包共12个文件(10.73MB)&…

2026/9/10 12:32:02

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/10 15:19:50

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/10 15:49:53

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码