基于 `@mastra/claude` 包的 `ClaudeSDKAgent` 集成指南:在 Mastra 中使用 Claude Agent SDK
2026/9/12 15:02:32 网站建设 项目流程

基于@mastra/claude包的ClaudeSDKAgent集成指南:在 Mastra 中使用 Claude Agent SDK

【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastra

导读

agent-sdks/claude是 Mastra 仓库中负责连接 Claude Agent SDK 的官方适配包,其核心导出ClaudeSDKAgent是一个包装了 Claude Agent SDK 的 Mastra Agent。它让你在 Mastra 项目中直接注册一个由 Claude Code 运行时驱动的代理,同时保留 Claude SDK 自己的 agent 循环、工具、权限配置,并通过 Mastra 兼容的generate()/stream()接口对外暴露,最终把使用量(usage)、成本(cost)和工具活动(tool activity)接入 Mastra 的可观测体系。读完本文,你将掌握@mastra/claude的安装、ClaudeSDKAgent的完整配置项(sdkOptions)、工具挂载(MCP servers)、会话恢复(resumeGenerate/resumeStream)、结构化输出以及构建测试命令,并能从源码级理解它的底层实现。

包定位:ClaudeSDKAgent是什么

仓库内的 agent-sdks/claude/AGENTS.md 明确了本包的三个关键事实:

  1. 包的本质:ClaudeSDKAgent是围绕 Claude Agent SDK 的 Mastra Agent 包装器(wrapper);
  2. 构建方式:在仓库根目录执行pnpm --filter ./agent-sdks/claude build:lib即可构建该包;
  3. 测试方式:在仓库根目录执行pnpm --filter ./agent-sdks/claude test即可运行其 Vitest 测试。

在 Mastra 的整体架构里,这类包被归入 "SDK agents" 模式。官方文档 docs/src/content/en/docs/connections/sdk-agents.mdx 对此的定位是:当某个厂商 SDK 已经拥有自己的 agent 循环、工具、权限或本地运行时,而你希望把这个 SDK 驱动的代理注册进 Mastra 项目、需要 Mastra 兼容的generate()/stream()输出、并让 SDK 运行产生的使用量/成本/工具活动出现在 Mastra 可观测性中时,就使用 SDK agent。@mastra/claude@mastra/cursor@mastra/openai同属这一家族,本文聚焦 Claude 一侧。

从源码看,agent-sdks/claude/src/index.ts 中的ClaudeSDKAgent继承自@mastra/core/agentAgent基类,其内部通过createNoopModel注册了一个 provider 为@anthropic-ai/claude-agent-sdk、modelId 为sdkOptions.model ?? 'claude-agent-sdk'的占位模型——真正的推理与 agent 循环完全交给 Claude Agent SDK 的query()完成,Mastra 侧只负责接口兼容与数据透传。

安装与环境配置

安装两个包

@mastra/claude与 Claude Agent SDK 之间是 peer 依赖关系。查看 agent-sdks/claude/package.json 可以确认:

  • peerDependencies@anthropic-ai/claude-agent-sdk: ^0.3.145@mastra/core: >=1.34.0-0 <2.0.0-0
  • 运行环境要求:Node.js>=22.13.0

因此安装时需要同时安装二者:

npm install @mastra/claude npm install @anthropic-ai/claude-agent-sdk

设置凭据

创建 Agent 之前需要设置 Claude SDK 的 API Key 环境变量:

export ANTHROPIC_API_KEY="..."

创建 Claude SDK Agent

最小示例

以下代码来自 agent-sdks/claude/README.md,它演示了如何创建一个ClaudeSDKAgent并注册到 Mastra 实例:

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 }, });

配置项详解

从源码的类型定义(agent-sdks/claude/src/index.ts)可以看出ClaudeAgentOptions只有四个字段:

字段必填说明
id注册进 Mastra 时使用的 agent id
name显示名,缺省时回退为id
description描述信息,Mastra 在列出或选择 agent 时展示
sdkOptions透传给 Claude Agent SDKquery()的选项(即ClaudeQueryOptions

idnamedescription在构造函数中被原样传入Agent基类,而instructions被置为空字符串、model使用占位模型——这是因为 Claude SDK 自己管理模型与指令,Mastra 不需要也无法接管。测试 agent-sdks/claude/src/index.test.ts 中也验证了isAgentCompatible(agent) === true,即该包装器完全符合 Mastra 的 Agent/SubAgent 契约。

sdkOptions是整个配置的核心,它是 Claude Agent SDK 的query()options。测试用例中覆盖了以下常用键,均会原样透传给 SDK:

const agent = new ClaudeSDKAgent({ id: 'claude-agent', description: 'Claude', sdkOptions: { cwd: '/tmp/project', // 工作目录 model: 'claude-sonnet-4-6', // 模型 ID maxTurns: 1, // 最大轮次 permissionMode: 'acceptEdits', // 权限模式 tools: ['Read', 'Bash'], // 启用工具列表 allowedTools: ['Read'], // 允许工具白名单 disallowedTools: ['Bash'], // 禁用工具黑名单 mcpServers: { // MCP 服务器 weather: { type: 'sdk', name: 'weather' }, }, env: { CLAUDE_AGENT_SDK_CLIENT_APP: 'mastra-test', // SDK 环境变量 }, pathToClaudeCodeExecutable: '/usr/local/bin/claude', }, });

为 Agent 添加 Claude SDK 工具

与 Mastra 原生工具不同,Claude Agent SDK 的工具通过其 MCP 服务器机制提供。官方文档 sdk-agents.mdx 给出的做法是:用createSdkMcpServer创建服务器,再通过sdkOptions.mcpServers传入:

import { createSdkMcpServer } from '@anthropic-ai/claude-agent-sdk' import { ClaudeSDKAgent } from '@mastra/claude' import { getTemperature } from '../tools/get-temperature' const weatherServer = createSdkMcpServer({ name: 'weather', version: '1.0.0', tools: [getTemperature], }) export const claudeSDKAgent = new ClaudeSDKAgent({ id: 'claude-sdk-agent', name: 'Claude SDK Agent', description: 'Use Claude Agent SDK through Mastra.', sdkOptions: { model: 'claude-sonnet-4-6', cwd: process.cwd(), mcpServers: { weather: weatherServer, }, allowedTools: ['mcp__weather__get_temperature'], }, })

注意allowedTools中使用的命名规则是 Claude Agent SDK 的 MCP 工具命名格式:mcp__<server name>__<tool name>。这一点在源码中有对应证据——agent-sdks/claude/src/utils.ts 的parseMcpToolName用正则/^mcp__([^_].*?)__(.+)$/解析该命名,把mcp__weather__get_temperature拆分为 serverNameweather与 toolNameget_temperature,用于可观测性中生成 MCP 工具调用 span。

注册并调用 SDK Agent

与其他 Agent 一样,将ClaudeSDKAgent实例注册进 Mastra 即可:

// src/mastra/index.ts import { Mastra } from '@mastra/core' import { claudeSDKAgent } from './agents/claude-sdk-agent' export const mastra = new Mastra({ agents: { claudeSDKAgent, }, })

注册后通过mastra.getAgentById()获取并调用:

const agent = mastra.getAgentById('claude-sdk-agent') const stream = await agent.stream('Inspect this project and describe the test setup.') for await (const chunk of stream.textStream) { process.stdout.write(chunk) }

底层运行原理:generate 与 stream

generate:把消息转为提示词并透传 query

ClaudeSDKAgent.generate()的实现链路(agent-sdks/claude/src/index.ts)大致如下:

  1. 通过promptToText(messages)把 Mastra 消息列表归一化为纯文本 prompt;
  2. 创建 telemetry 上下文(agent span + model span);
  3. 调用runClaudeGenerate,内部消费runClaude()返回的AsyncIterable<SDKMessage>
  4. 在迭代中:用createClaudeUsageCollector()汇总 usage,监听result消息——若subtype !== 'success'则抛出错误(错误信息为message.errors的拼接),否则提取result文本与structured_output
  5. 最终包装为 Mastra 的FullOutput,携带providerMetadata(含totalCostUsdmodelcwdpermissionModemaxTurnsallowedToolsdisallowedToolsusage)与costContext

runClaude()(index.ts)的关键行为是合并两层 sdkOptions:先展开构造时的options.sdkOptions,再覆盖运行时的runOptions.sdkOptions{ ...options.sdkOptions, ...runOptions?.sdkOptions }),从而支持按次调用覆盖配置。同时它还处理了两件重要的事:

  • 结构化输出:若调用方传了structuredOutput,会把标准 schema 转换为 JSON Schema,并设置queryOptions.outputFormat = { type: 'json_schema', schema },走 Claude SDK 原生的 schema 约束输出;
  • 中止信号:把调用方的abortSignal映射为AbortController传给 SDK 的query()

stream:转换为 Mastra 分块流

ClaudeSDKAgent.stream()(index.ts)返回一个MastraModelOutput,底层是ReadableStream<ChunkType>runClaudeAsMastraStream(index.ts)的转换规则是:

  • 先入队startstep-startresponse-metadatatext-start起始块;
  • 遍历 Claude SDK 消息,从stream_event中的content_block_delta/text_delta提取增量文本,逐个入队text-delta块;
  • 收到result消息后入队text-endstep-finishfinish结束块;
  • 异常时入队error块并关闭流。

测试 index.test.ts 验证了完整的分块序列为:start → step-start → response-metadata → text-start → text-delta × N → text-end → step-finish → finish,且stream.text能正确聚合增量文本。同时stream.usage会把 SDK 的 token 用量换算为 Mastra 的LanguageModelUsage(如测试中inputTokens: 15outputTokens: 4totalTokens: 19——其中输入 15 = 无缓存 10 + 缓存读取 2 + 缓存写入 3)。

usage 汇总逻辑

createClaudeUsageCollector(index.ts)同时监听assistant消息(按消息 id 记录 usage)和result消息(记录total_cost_usdmodelUsage)。totals()优先采用result消息的用量,缺失字段再回退到各 assistant 消息用量的累加;observability.test.ts 中专门有一个测试用例验证:当 result 消息只有成本字段时,token 用量会从 assistant 消息中保留下来。

会话恢复:resumeGenerate 与 resumeStream

Claude SDK Agent 通过 Mastra 已有的resumeGenerate()/resumeStream()实现厂商原生会话恢复。其resumeData支持两种互斥形态(类型定义见 index.ts):

// 形态一:恢复指定 session const result = await claudeSDKAgent.resumeGenerate({ message: 'Continue the previous task.', sessionId: 'claude-session-id', // 要恢复的 Claude session id forkSession: true, // 可选:fork 到新 session resumeSessionAt: 'assistant-message-id', // 可选:恢复到指定 assistant 消息处 }) // 形态二:继续当前工作目录下的最新 session const stream = await claudeSDKAgent.resumeStream({ message: 'Continue the previous task.', continue: true, })

底层映射逻辑在createClaudeResumeRunOptions(index.ts)中:sessionId形态会设置 SDK 选项resume(并可选forkSessionresumeSessionAt),continue: true形态则设置 SDK 选项continue。校验函数validateClaudeResumeData会拒绝非法组合,例如同时传sessionIdcontinue会抛出 "either sessionId or continue: true, not both" 的错误,sessionId非字符串、continuetrue同样会被拒绝(对应测试见 index.test.ts)。

结构化输出

从 CHANGELOG.md 的 0.2.0 版本记录可以看到,Claude 与 OpenAI SDK agent 都通过各自厂商的原生结构化输出 API 支持了 Mastra 的structuredOutput。用法如下:

const result = await claudeAgent.generate<{ answer: string }>('Return a JSON answer', { structuredOutput: { schema: z.object({ answer: z.string() }), }, }) console.log(result.object) // { answer: '...' }

其工作链路为(源码证据见 index.ts 与 utils.ts):

  1. getStructuredOutputSchema把标准 schema 转换为 JSON Schema,并设置outputFormat: { type: 'json_schema', schema }——让 Claude SDK 原生产出符合 schema 的 JSON;
  2. 运行结束后优先读取 result 消息的structured_output字段(getClaudeStructuredOutput),否则回退到纯文本;
  3. getStructuredOutputFromValue对该值做标准 schema 校验,校验失败时按errorStrategy处理:fallback返回fallbackValuewarn仅记日志并返回undefined,默认(throw)则抛出带 issue 明细的错误;
  4. 校验通过的值暴露在result.object上。

测试 index.test.ts 验证了:传入{ answer: 'yes' }的结构化输出后,result.object等于该对象,且传给 SDK 的 options 中确实包含outputFormat: { type: 'json_schema', schema: ... }

可观测性:span、成本与工具调用

SDK Agent 会为每次generate()/stream()创建 Mastra 的 agent span 与 model span。createSDKAgentTelemetry(agent-sdks/claude/src/utils.ts)负责这一整套埋点:

  • Agent span:类型AGENT_RUN,名称为`agent run: '${agentId}'`,属性包含 prompt、instructions、maxSteps;
  • Model span:类型MODEL_GENERATION,名称为`llm: '${modelId}'`,结束时记录文本、usage、finishReason、responseId、responseModel、costContext;
  • 工具 span:遍历 SDK 消息中的tool_use/tool_result内容块,生成TOOL_CALLMCP_TOOL_CALLspan。MCP 工具名会被解析出 serverName,例如 observability.test.ts 中断言mcp__weather__get_temperature生成名为"mcp_tool: 'mcp__weather__get_temperature' on 'weather'"、带mcpServer: 'weather'属性的 span。

成本方面,Claude SDK 会在 result 消息里给出 SDK 估算成本total_cost_usdgetClaudeCostContext(index.ts)将其映射为 Mastra 的CostContext:provider 为anthropicestimatedCost取该值,costUnitUSD,并在costMetadata中标注来源sdk_estimate、SDK 成本字段total_cost_usd、统计范围query_total以及模型粒度明细modelUsage。可观测性测试验证了 model span 结束时携带了包含estimatedCost: 0.0123的 costContext。

另外要注意:ClaudeSDKAgent.supportsMemory()固定返回false(见 index.ts),即此类 SDK 代理不支持 Mastra 的内存管理能力,会话状态完全由 Claude SDK 侧维护。

包边界与设计约束

agent-sdks/claude/AGENTS.md 的最后一行是一条重要的工程约定:除非某个辅助函数被明确证明适合作为稳定的核心 API,否则厂商特有的 SDK-agent 辅助函数应保持在本包私有。这一设计约束在源码中有直观体现——agent-sdks/claude/src/utils.ts 中诸如parseMcpToolNametoV3UsageenqueueStartChunks等函数并未从包入口重新导出,避免把 Claude SDK 的命名与结构泄漏给 Mastra 核心层,也为其他厂商包(cursor、openai)各自维护同类辅助逻辑留出了边界。

构建与测试

在仓库根目录按 AGENTS.md 给出的命令即可完成该包的构建与测试:

# 构建 lib(底层为 tsdown,配置见 agent-sdks/claude/tsdown.config.ts) pnpm --filter ./agent-sdks/claude build:lib # 运行测试(Vitest,配置见 agent-sdks/claude/vitest.config.ts) pnpm --filter ./agent-sdks/claude test

测试入口为 agent-sdks/claude/src/index.test.ts 与 agent-sdks/claude/src/observability.test.ts,前者覆盖基础契约、generate/stream 行为、结构化输出、会话恢复与 resumeData 校验,后者验证 span 记录、成本元数据与 MCP 工具调用埋点。它们通过 mock@anthropic-ai/claude-agent-sdkquery()来模拟 SDK 消息流,是理解本包行为的可靠参考。

相关资源

  • 本包说明:agent-sdks/claude/README.md
  • 核心实现:agent-sdks/claude/src/index.ts
  • 辅助工具函数:agent-sdks/claude/src/utils.ts
  • 功能测试:agent-sdks/claude/src/index.test.ts 与 agent-sdks/claude/src/observability.test.ts
  • 版本记录:agent-sdks/claude/CHANGELOG.md
  • 官方集成文档:docs/src/content/en/docs/connections/sdk-agents.mdx(其中包含 Cursor、OpenAI SDK agent 的对照用法)

【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastra

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询