Mastra @mastra/claude:将 Claude Agent SDK 的 Agent 循环接入 Mastra 的 generate/stream 体系

发布时间:2026/9/14 3:40:30
Mastra @mastra/claude:将 Claude Agent SDK 的 Agent 循环接入 Mastra 的 generate/stream 体系 Mastra mastra/claude将 Claude Agent SDK 的 Agent 循环接入 Mastra 的 generate/stream 体系【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastramastra/claude是 Mastra 仓库中agent-sdks/claude子包发布的 TypeScript 包它把 Anthropic 官方的 Claude Agent SDKClaude Code 的 agent loop、工具调用、权限与运行时配置封装成一个 Mastra 兼容的Agent让你可以用 Mastra 熟悉的generate()与stream()方法驱动 Claude 的智能体执行。读完本文你将掌握该包的完整安装方式、构造函数与运行时参数、结构化输出与会话恢复resume机制以及源码层面的消息流转换、用量统计、成本上报与可观测性埋点细节。包定位一个围绕 Claude Agent SDK 的 Mastra Agent 包装器从 包说明文档 可以看到mastra/claude的用途非常明确当你希望保留 Claude Code 的 agent loop、工具、权限permissions与运行时配置同时又需要通过 Mastra 兼容的generate()和stream()方法暴露这个 agent 时使用它。从源码结构看ClaudeSDKAgent直接继承自mastra/core/agent的Agent基类见 agent-sdks/claude/src/index.ts注册到Mastra实例后即可被 Agent 兼容性检查、SubAgent 机制等核心能力识别。它有两个值得注意的设计特征模型层是“空实现”构造器传入的是一个createNoopModel()agent-sdks/claude/src/utils.ts其doGenerate/doStream都返回立即关闭的空流。真正的推理完全委托给 Claude Agent SDK 的query()noop 模型只承担modelId与provideranthropic-ai/claude-agent-sdk的标识作用。不支持 Mastra 内置 MemorysupportsMemory()固定返回falseindex.ts#L132-L134会话连续性交由 Claude SDK 自身的 session 机制下文 resume 章节处理而非 Mastra 的 memory 存储。安装与环境要求README 给出的安装命令需要装两个包npm install mastra/claude npm install anthropic-ai/claude-agent-sdk第二个包不是可选项在 package.json 中anthropic-ai/claude-agent-sdkpeer 要求^0.3.145与mastra/corepeer 要求1.34.0-0 2.0.0-0都被声明为peerDependencies因此使用方必须自行安装这两个依赖。其他适用前提Node.js 版本要求22.13.0engines字段包的当前版本为0.3.1许可证 Apache-2.0入口同时提供 ESMdist/index.js与 CJSdist/index.cjs产物创建 agent 前需要先设置ANTHROPIC_API_KEY环境变量README 明确要求仓库文档 docs/src/content/en/docs/connections/sdk-agents.mdx 中也给出了export ANTHROPIC_API_KEY...的示例。快速开始创建并注册 ClaudeSDKAgentREADME 的最小可用示例import { ClaudeSDKAgent } from mastra/claude; import { Mastra } from mastra/core/mastra; export const claudeAgent new ClaudeSDKAgent({ id: claude-sdk-agent, name: Claude SDK Agent, description: Use Claude Agent SDK through Mastra., sdkOptions: { cwd: process.cwd(), }, }); export const mastra new Mastra({ agents: { claudeAgent }, });构造函数选项ClaudeAgentOptions的完整定义见 index.ts#L51-L68选项必填说明id是注册到 Mastra 时使用的 agent idname否展示名缺省时回退为iddescription是Mastra 在列出/选择 agent 时展示的描述sdkOptions否每次运行时透传给 Claude SDKquery()的选项类型即 Claude Agent SDK 的OptionsClaudeSDKOptions ClaudeQueryOptionssdkOptions就是 Claude Agent SDKquery()的原生选项从 单元测试的断言 可以确认以下字段会被原样转发cwdagent 工作目录、model如claude-sonnet-4-6、maxTurns最大轮数、permissionMode如acceptEdits、tools、allowedTools、disallowedTools、mcpServersSDK 内建 MCP server 定义、env、pathToClaudeCodeExecutable自定义 Claude Code 可执行文件路径等。模型 id 的取值逻辑在getModelId()index.ts#L532-L534优先取sdkOptions.model否则回退为字面量claude-agent-sdk。运行时参数与 sdkOptions 的合并规则generate()/stream()接受的运行选项是ClaudeSDKAgentRunOptionsindex.ts#L70-L77它在 Mastra 的AgentExecutionOptionsBase基础上扩展了sdkOptions本次运行专属的 Claude SDK 选项会覆盖合并到构造函数传入的sdkOptions之上见runClaude()中的{ ...options.sdkOptions, ...runOptions?.sdkOptions }index.ts#L419-L445。典型用途是在调用时传入resume/continue等会话续接参数而无需修改构造器配置signal/abortSignal中止信号。源码会把它桥接成一个内部AbortController注入到queryOptions.abortControllerindex.ts#L517-L530已 abort 的信号会立即传递中止原因structuredOutput结构化输出下节详述runId缺省用randomUUID()生成以及 Mastra 通用的instructions、maxSteps、tracingOptions、tracingContext、onFinish、onStepFinish、requestContext等字段SDKAgentRunOptions定义见 utils.ts#L25-L29。一个值得注意的细节Mastra 的MessageListInput会先经过promptToText()utils.ts#L837-L862压平成纯文本字符串再交给query({ prompt })。也就是说Claude SDK 侧接收的是单条文本 prompt多模态/富消息结构不会直接透传到 SDK。generate() 与 stream() 的执行流程两条路径共用同一个执行内核runClaude()它调用 Claude Agent SDK 的query()并得到一个AsyncIterableSDKMessage消息流generate() 路径index.ts#L136-L179遍历 SDK 消息流用usage收集器记录每条消息的 token 用量遇到type result的消息时终结若subtype ! success把message.errors拼成错误抛出否则取message.result作为最终文本通过toFullOutput()构造 MastraFullOutput内部会把结果包装成一条“已完成”的 Mastra 流createCompletedMastraStream因此result.text、result.usage、result.providerMetadata、result.object等字段与stream()的产物保持同构。stream() 路径runClaudeAsMastraStream()index.ts#L336-L417先发start、step-start、response-metadata、text-start四个起始 chunkenqueueStartChunksutils.ts#L616-L667其中step-start携带 prompt 原文response-metadata携带runId、responseId、modelId与providerMetadata增量文本只认stream_event消息中的content_block_delta/text_delta事件getTextDelta()index.ts#L680-L698逐段enqueueTextDelta兜底逻辑如果整个过程中没有出现过任何 delta但result消息带有result文本则把全文作为一个 delta 补发index.ts#L380-L383结尾发送text-end、若有结构化输出的object-result、step-finish、finishchunk出错时发送errorchunk 后关闭流。stream 测试 用 mock 的query精确断言了fullStream的 chunk 序列start → step-start → response-metadata → text-start → text-delta → text-delta → text-end → step-finish → finish并验证了await stream.text能正确聚合增量文本、stream.usage可解析。结构化输出走 Claude 原生的 JSON Schema 通道ClaudeSDKAgent的结构化输出没有采用“提示词拼接 事后解析”的通用套路而是直接使用 Claude Agent SDK 的原生能力当运行选项带structuredOutput.schema时getStructuredOutputSchema()先把 Standard Schema如 Zod转成 JSON Schemautils.ts#L880-L888在runClaude()中写入queryOptions.outputFormat { type: json_schema, schema }index.ts#L430-L436由 SDK 约束模型输出结果优先取result消息上的structured_output字段getClaudeStructuredOutput()index.ts#L447-L453取不到再回退到result文本最终值统一经过getStructuredOutputFromValue()校验utils.ts#L897-L927字符串会先JSON.parse再按 Standard Schema 的~standard.validate校验校验失败按errorStrategy处理——fallback返回fallbackValue、warn走 logger 并返回undefined、默认则抛错。对应测试 断言了result.object直接等于{ answer: yes }且query收到的options.outputFormat正是{ type: json_schema, schema: ... }。该能力在 CHANGELOG 的 0.2.0 版本中首次引入“Added structured output support for Claude and OpenAI SDK agents using their provider-native structured output APIs”。会话恢复resumeGenerate / resumeStream 与 Claude session 的映射0.2.0 版本同时引入了 provider 原生的会话恢复。ClaudeSDKAgentResumeData有两种形态index.ts#L79-L107字段含义message必填恢复时发送的消息MessageListInputsessionId: string恢复指定 Claude 会话forkSession?: boolean将恢复出的会话 fork 成新会话resumeSessionAt?: string只恢复到某条 assistant 消息按消息 UUID为止continue: true继续当前工作目录下最近的 Claude 会话与sessionId互斥调用侧写法来自 CHANGELOG 0.2.0 的官方示例await claudeAgent.resumeGenerate({ message: Continue the task., sessionId: claude-session-id, });映射逻辑在createClaudeResumeRunOptions()index.ts#L266-L288sessionId形态会生成sdkOptions.resume sessionId并按需附加forkSession、resumeSessionAtcontinue形态则置sdkOptions.continue true。resumeGenerate()/resumeStream()本质是校验后调用generate()/stream()的便捷入口index.ts#L220-L234。validateClaudeResumeData()index.ts#L237-L264对参数做了严格校验sessionId与continue同时出现会抛出must include either sessionId or continue: true, not bothcontinue必须严格为true两者都不提供同样报错。测试用例 覆盖了三种场景sessionId forkSession resumeSessionAt的完整映射、continue: true的流式恢复、以及混合形态被拒绝且query从未被调用。用量统计与成本上报Claude SDK 的消息流中token 用量分散在两类消息里assistant消息每条带usage和最终的result消息带usage、total_cost_usd、modelUsage。createClaudeUsageCollector()index.ts#L536-L577的策略是按message.id去重累加所有assistant消息的input_tokens/output_tokens/cache_read_input_tokens/cache_creation_input_tokens若result消息自带用量则以它为准缺失字段如仅返回成本而无 token 数时从 assistant 累计值补齐——专门的测试 验证了“result 只有成本、token 靠 assistant 消息兜底”时inputTokens仍为 1510 2 缓存读 3 缓存写。汇总后的用量被转换成 Mastra 的 V3 用量结构V3Usageutils.ts#L31-L42inputTokens.total包含 noCache、cacheRead、cacheWrite 三个分量outputTokens.total与text分量一致再经toLanguageModelUsage()映射为LanguageModelUsagecachedInputTokens、cacheCreationInputTokens等字段。成本方面getClaudeCostContext()index.ts#L660-L678只在total_cost_usd是数字时构造CostContextprovider: anthropic、estimatedCost、costUnit: USD并在costMetadata中标注来源为sdk_estimate字段total_cost_usd、范围query_total同时附modelUsage明细。另外getClaudeProviderMetadata()index.ts#L645-L658会把totalCostUsd、model、cwd、permissionMode、maxTurns、allowedTools、disallowedTools、usage打包进providerMetadata.claude下随每个流 chunk 的 metadata 暴露给下游——测试 对这一结构做了逐项断言。可观测性agent span、模型 span 与工具调用追踪SDK agent 的埋点由共享的createSDKAgentTelemetry()完成utils.ts#L245-L520其 span 层级为AGENT_RUN spanagent run: id记录 prompt、instructions、maxSteps 属性与runId、sdkAgent: true、sdkProvider、sdkMethod等元数据MODEL_GENERATION 子 spanllm: modelId作为 agent span 的子 span携带 model、provider、streaming 属性生成结束或流finish/errorchunk时由wrapStreamForAgentSpan()utils.ts#L544-L591统一收尾错误路径会关闭所有未结束的 span 并打 error工具调用 spanobserveClaudeMessages()index.ts#L455-L463在转发每条SDKMessage的同时提取工具事件——assistant消息中的tool_use块触发startToolCalluser消息中的tool_result块触发endToolCallis_error为真时按错误结束 span。特别地形如mcp__server__tool的工具名会被parseMcpToolName()utils.ts#L522-L532识别为 MCP 工具创建MCP_TOOL_CALL类型 span 并记录mcpServer属性observability 测试 用mcp__weather__get_temperature构造了 tool_use/tool_result 消息对来验证这一行为。这意味着即使 agent 的推理发生在 Claude SDK 进程内Mastra 的 tracing 系统以及接在后面的观测后端仍能看到完整的“agent run → llm 生成 → N 个工具调用”的树状链路。在本仓库中构建与验证如果需要在仓库内验证该包仓库为只读环境时建议以查阅为主agent-sdks/claude/AGENTS.md 给出了标准命令# 从仓库根目录构建 pnpm --filter ./agent-sdks/claude build:lib # 从仓库根目录跑测试 pnpm --filter ./agent-sdks/claude test测试全部基于对anthropic-ai/claude-agent-sdk的query函数 mockvi.mock无需真实 API key 即可验证SDK 选项转发、chunk 序列、用量兜底、结构化输出、resume 映射与校验、MCP 工具 span。构建脚本由tsdown驱动tsdown.config.tsprepack时会调用仓库根目录的文档生成脚本 scripts/generate-package-docs.ts。小结mastra/claude的价值在于“接口归一化”把 Claude Agent SDK 的异步消息流assistant 消息、stream_event 增量、result 终结消息翻译成 Mastra 标准的 chunk 协议与FullOutput/MastraModelOutput契约同时保留 SDK 侧的cwd、权限模式、工具白名单、MCP server、会话恢复等原生配置用量、成本与工具调用则通过 providerMetadata、CostContext 和 span 埋点回流到 Mastra 的观测体系。需要注意的边界是该 agent 不支持 Mastra Memory会话连续性依赖 Claude session 机制prompt 会被压平为文本传入且要求 Node.js ≥ 22.13.0 与 peer 声明的两个依赖同时就位。更多官方说明可参考仓库文档 docs/src/content/en/docs/connections/sdk-agents.mdx 与 agent-sdks/claude/README.md。【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastra创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考