Electric Agents AgentConfig 全解析用 ctx.useAgent() 配置 LLM Agent 循环【免费下载链接】electricThe agent platform built on sync.项目地址: https://gitcode.com/GitHub_Trending/el/electricAgentConfig 是 Electric Agents 运行时中配置 LLM Agent 循环的核心接口通过ctx.useAgent(config)传入 Handler 上下文用于指定系统提示词、模型、工具、流式回调与测试响应。读完本文你将掌握 AgentConfig 全部字段的语义与默认值、ctx.agent.run()的执行契约、testResponses无 LLM 测试方案以及这些配置在electric-ax/agents-runtime源码中的真实落地路径从而在自己的实体 Handler 中正确编排持久化的多步 Agent 循环。AgentConfig 是什么Electric Agents 是构建在 Electric Streams 之上的持久化 Agent 运行时每个 Agent 是一个可寻址的实体entity当消息到达、子实体完成、状态变化或定时器触发时实体被唤醒wake并执行 Handler。在 Handler 内部ctx.useAgent()用于为本次唤醒配置 LLM Agent 循环——从模型调用、文本增量输出到工具调用、错误每一个步骤都会被路由到实体的事件流上形成持久化记录。AgentConfig 即这份配置的结构化载体其类型定义位于 packages/agents-runtime/src/types.ts对外发布在electric-ax/agents-runtime包中。官方完整类型定义如下interface AgentConfig { systemPrompt: string model: string | Modelany provider?: Provider tools: AgentTool[] streamFn?: StreamFn getApiKey?: ( provider: string ) Promisestring | undefined | string | undefined onPayload?: SimpleStreamOptions[onPayload] onStepEnd?: (stats: { input: number uncachedInput: number output: number }) void modelTimeoutMs?: number modelMaxRetries?: number testResponses?: string[] | TestResponseFn }从实现上看createHandlerContext 内部以模块级变量持有这份配置useAgent(cfg)只是把cfg存入agentConfig并返回同一个AgentHandle实例见 context-factory.ts。这意味着在一次 Handler 调用中多次调用useAgent()会覆盖之前的配置而返回的句柄是同一个对象。真正的配置生效发生在ctx.agent.run()被调用时——如果尚未调用useAgent()就执行run()运行时会在 context-factory.ts 抛出明确错误[agent-runtime] agent.run() called without useAgent().字段总览字段类型必填说明systemPromptstring是每一步发送给 LLM 的系统提示词modelstring \| Modelany是模型标识如claude-sonnet-4-6或已解析的模型对象providerProvider否当model为字符串时使用的 pi-ai provider默认anthropictoolsAgentTool[]是提供给 LLM 的工具数组若运行时宿主提供了运行时级工具应展开ctx.electricToolsstreamFnStreamFn否透传给底层 Agent 的可选流式回调getApiKey(provider) string \| Promisestring \| undefined否可选的 API Key 解析函数透传到模型层onPayloadSimpleStreamOptions[onPayload]否模型层原始流式 payload 的可选回调onStepEnd(stats) void否每个模型步骤结束后回调携带 provider 上报的 token 计数modelTimeoutMsnumber否单次模型调用超时单位毫秒modelMaxRetriesnumber否模型调用最大重试次数testResponsesstring[] \| TestResponseFn否用于测试的模拟 LLM 响应一旦设置将不会发起真实 LLM 调用补充在 types.ts 的源码定义中还存在三个参考文档未列出的可选字段reasoning、thinkingBudgets均来自SimpleStreamOptions用于控制模型推理与思考预算会在 pi-adapter.ts 中被合并进底层streamFn调用以及summarizeComplete上下文压缩摘要的模型调用接缝默认使用 pi-ai 的completeSimple注释说明它可由测试注入也可用于将来把摘要路由到不同模型。使用这些字段前请确认当前运行时版本已支持。必填字段systemPrompt、model 与 toolssystemPrompt每次步骤都生效的系统提示词systemPrompt是发给 LLM 的系统提示词在 Agent 循环的每一步都会被传入。它是引导 Agent 行为与个性的主要手段。在 pi-adapter.ts 中createPiAgentAdapter接收的systemPrompt会被直接交给底层 pi-agent 适配器贯穿整个多步循环。model字符串标识或模型对象model接受两种形式model: claude-sonnet-4-6 // 字符串标识配合 provider 解析 model: someResolvedModelObject // 已解析的 Model 对象直接使用当传入字符串时运行时通过resolvePiModel见 pi-adapter.ts解析模型provider缺省为anthropic调用 pi-ai 的getModel(provider, model)得到真实模型对象若解析失败则抛出Unknown model ... for provider ...错误。值得注意的是解析逻辑对MOONSHOT_PROVIDERmoonshot 厂商做了特判走getMoonshotModel分支。provider 的取值逻辑在 context-factory.ts 的agentModelProvider中体现得更加清晰function agentModelProvider(config: AgentConfig): string { return typeof config.model string ? (config.provider ?? anthropic) : config.model.provider }即字符串模型取provider字段默认anthropic模型对象则直接用其自带的provider属性。同理agentModelIdcontext-factory.ts对字符串模型原样返回、对对象模型取model.id用于日志与运行记录。toolsAgentTool 数组与 ctx.electricToolstools是 Agent 循环中可供 LLM 调用的工具集合。工具接口AgentTool由electric-ax/agents-runtime从 pi-agent-core 重新导出完整定义见 AgentTool 参考interface AgentToolTParameters extends TSchema TSchema, TDetails any { name: string label: string description: string parameters: TParameters // TypeBox JSON Schema用于函数调用与参数校验 execute: (toolCallId, params, signal?, onUpdate?) PromiseAgentToolResult }每个工具必须提供nameLLM 函数调用中的唯一名称、label展示用、description告知 LLM 何时及如何使用、TypeBox 参数 schema 以及execute实现工具执行结果AgentToolResult包含返回给 LLM 的content文本或图片内容块和必须提供的details元数据。当运行时宿主提供了运行时级工具如调度管理工具时官方推荐用展开语法并入tools: [...ctx.electricTools, myCustomTool, anotherTool]ctx.electricTools可能为空数组也可能包含宿主提供的工具即便不展开它ctx.spawn、ctx.observe、ctx.send等 Handler 级协调 API 也始终可用见 配置指南。在 context-factory.ts 中配置的工具还会经过composeToolsWithProviders组装后再传给适配器工具调用产生的每一步事件都会被写入实体流。可选字段详解provider、streamFn 与 getApiKeyprovider仅当model为字符串时生效指定 pi-ai 的 LLM 供应商默认anthropic。streamFn可选的流式回调透传给底层 Agent。在 pi-adapter.ts 中若未提供则默认使用 pi-ai 的streamSimple且传入的streamFn会被包装统一注入reasoning、thinkingBudgets、timeoutMs与maxRetries选项。getApiKeyAPI Key 解析函数接收 provider 名称、返回字符串或 Promise。它会被透传到模型层也会在上下文压缩摘要mid-turn compaction的summarizeAgentMessages调用中被使用context-factory.ts用于为摘要模型调用补充密钥。onPayload 与 onStepEnd流式与 token 统计onPayload模型层原始流式 payload 回调可用于观察底层传输的原始数据块。onStepEnd每个模型步骤结束后回调携带 provider 上报的三个 token 计数。源码注释types.ts给出了精确的语义input完整提示词体量含 prompt 缓存的读/写即界面 meta 行展示的值uncachedInput仅本次步骤的新输入新 token 缓存写入排除缓存读取output本次输出 token。预算核算应使用uncachedInput output这样热缓存回合不会在每一步重复计入整段对话。modelTimeoutMs 与 modelMaxRetries调用超时与重试这两个字段控制单次模型调用的超时与重试。源码中定义了默认值pi-adapter.tsconst DEFAULT_MODEL_TIMEOUT_MS 30_000 // 默认 30 秒 const DEFAULT_MODEL_MAX_RETRIES 2 // 默认最多重试 2 次未显式配置时采用上述默认显式传入的值会覆盖默认并经由包装后的streamFn以timeoutMs/maxRetries形式传入底层流式调用pi-adapter.ts。testResponses不调用 LLM 的测试方案testResponses是 AgentConfig 中最具实战价值的测试字段一旦设置运行时完全跳过真实 LLM 调用。它有两种形式类型定义见 types.tstype TestResponses Arraystring | TestResponseFn type TestResponseFn ( message: string, bridge: OutboundBridgeHandle ) Promisestring | undefined数组形式按历史轮次确定性选择传入字符串数组时运行时按实体已有的 run 次数取模选择响应使多次唤醒的测试结果完全确定ctx.useAgent({ systemPrompt: ..., model: claude-sonnet-4-6, tools: [...ctx.electricTools], testResponses: [Hello! How can I help?, Sure, I can do that.], }) await ctx.agent.run()实现上context-factory.ts 会先统计runs集合的既有记录数priorRunCount再以responses[priorRunCount % responses.length]选取响应并将其作为该轮 Agent 的文本输出。函数形式基于消息动态响应传入函数时它接收当前触发消息和一个出站桥bridge返回模拟响应字符串返回undefined则不自动产生文本响应ctx.useAgent({ // ... testResponses: async (message, bridge) { if (message.includes(calculate)) { return The answer is 42. } return undefined // 不产生自动文本响应 }, })在 context-factory.ts 的测试分支中运行时会在调用你的函数前后自动包裹bridge.onRunStart()/bridge.onRunEnd()以及步骤级 start/end 调用onStepStart、onStepEnd并模拟finishReason: stop或错误时的error。因此函数内部只需使用文本级与工具级方法切勿自行调用 run/step 生命周期方法测试指南 中有明确提示。OutboundBridgeHandle模拟工具调用与多轮交互OutboundBridgeHandle提供了完整的事件模拟接口定义见 types.ts实现位于 outbound-bridge.ts 的createOutboundBridge方法说明onRunStart()/onRunEnd(opts?)标记一次运行的开始/结束onStepStart({ modelProvider, modelId })/onStepEnd({ finishReason, durationMs })标记一个模型步骤的开始/结束onTextStart()/onTextDelta(delta)/onTextEnd()模拟文本增量输出onToolCallStart(id\|name, name\|args, args?)/onToolCallEnd(..., isError)模拟工具调用开始/结束含结果与错误标记借助这些方法可以在测试中模拟工具调用、推理步骤与多轮交互。仓库测试 runtime-dsl.test.ts 中createFakeToolAssistant的做法极具参考价值——它在TestResponseFn内部通过bridge.onToolCallStart(sync_echo, { text })与bridge.onToolCallEnd(sync_echo, result, false)完整模拟一个同步工具调用的生命周期还支持带异步延迟的async_lookup工具模拟以及通过bridge.onTextDelta分批输出文本testResponses: async (message, bridge) { if (message.trim().startsWith(sync_echo )) { const text message.trim().slice(sync_echo .length) bridge.onToolCallStart(sync_echo, { text }) const result { echoed: text } bridge.onToolCallEnd(sync_echo, result, false) return sync_echo: ${text} } // ... }AgentHandleuseAgent 的返回值ctx.useAgent()返回AgentHandle同时它也被挂载为ctx.agent两个引用等价配置指南interface AgentHandle { run(input?: string): PromiseAgentRunResult }方法返回类型说明run(input?)PromiseAgentRunResult执行 Agent 循环直到 LLM 停止或所有工具调用完成参数input为可选字符串会在 Agent 循环开始前追加到对话中。从源码看AgentHandle.run的实际签名还支持第二个可选参数abortSignal见 types.ts用于与 Handler 的取消信号合并combineAbortSignalscontext-factory.ts实现 SIGINT 或终端关闭时的提前中止。run()的执行流程context-factory.ts大致如下校验已调用useAgent()否则抛错提取触发消息文本getTriggerMessageText以input ?? messageText作为本轮输入组装工具composeToolsWithProviders(activeAgentConfig.tools)并可能追加上下文自动工具createContextTools处理上下文预算从steps集合读取最近的 token 用量注入预算提示截断超大工具结果truncateOversizedToolResults并在每个模型步骤前执行中轮压缩mid-turn compaction通过createMidTurnCompactor其摘要模型调用会复用getApiKey与summarizeComplete通过createPiAgentAdapter创建底层适配器并handle.run(runInput, combinedSignal)全程写入日志与事件若设置了testResponses则直接走模拟分支不触达任何真实模型。AgentRunResultrun() 的返回值interface AgentRunResult { result?: unknown writes: ChangeEvent[] toolCalls: Array{ name: string; args: unknown; result: unknown } usage: { tokens: number; duration: number } }字段类型说明resultunknown底层 Agent 适配器返回的可选最终结果writesChangeEvent[]目前返回空数组占位toolCallsArray{ name, args, result }目前返回空数组占位usage{ tokens: number; duration: number }目前返回{ tokens: 0, duration: 0 }等待 usage 聚合接入从 context-factory.ts 与测试分支context-factory.ts可以确认当前版本中writes、toolCalls与usage均为占位实现真实聚合尚未接线。这意味着现阶段不应依赖AgentRunResult的这三个字段做业务判断更可靠的做法是通过onStepEnd回调自行统计 token或直接从实体的runs、steps等内置集合读取运行记录。完整实战示例定义一个 Assistant 实体将以上知识整合为一个可直接运行的实体定义。该示例取自 Quickstart 的核心形态同时结合 Horton 内置 Agent 的扩展模式import { createEntityRegistry } from electric-ax/agents-runtime const registry createEntityRegistry() registry.define(assistant, { description: A general-purpose AI assistant, async handler(ctx) { ctx.useAgent({ systemPrompt: You are a helpful assistant., model: claude-sonnet-4-6, // provider 缺省为 anthropic tools: [...ctx.electricTools], // 展开运行时级工具 modelTimeoutMs: 60_000, // 单次模型调用 60 秒超时 modelMaxRetries: 3, // 最多重试 3 次 onStepEnd({ input, uncachedInput, output }) { console.log(step tokens:, { input, uncachedInput, output }) }, }) await ctx.agent.run() // 阻塞直到 LLM 停止或工具调用完成 }, })测试时只需把testResponses加入配置即可完全绕过 LLMctx.useAgent({ systemPrompt: You are a helpful assistant., model: claude-sonnet-4-6, tools: [...ctx.electricTools], testResponses: async (message, bridge) { if (message.includes(calculate)) return The answer is 42. return undefined }, }) await ctx.agent.run()如果想控制填充到 Agent 上下文窗口的内容token 预算、缓存层级、外部来源可以同时使用ctx.useContext()与useAgent详见 上下文组合。相关参考Configuring the agent 使用指南 ——useAgent、模型、工具与流式的完整实践AgentTool 参考 —— 工具接口与AgentToolResult约束HandlerContext 参考 ——useAgent、ctx.agent与其余上下文 APITesting 指南 —— 用testResponses做 LLM 模拟测试Quickstart —— 从零搭建一个包含 Assistant 实体的 Agent 应用AgentConfig 类型定义 —— 含reasoning、thinkingBudgets、summarizeComplete等扩展字段createHandlerContext 实现 ——useAgent与agent.run的完整执行链路pi-adapter 实现 —— 模型解析、默认超时/重试与流式包装runtime-dsl 测试 ——testResponses与 bridge 模拟工具调用的真实用例【免费下载链接】electricThe agent platform built on sync.项目地址: https://gitcode.com/GitHub_Trending/el/electric创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
