在 Laravel AI SDK 中复用 Laravel MCP 工具
围绕"如何把 AI 智能体接入 Laravel 应用"这件事,业界已经探索了一段时间。随着 Laravel MCP 与 Laravel AI SDK 相继出现,这条路径正变得自然而富有潜力。
在实际测试两者的过程中,有一个问题会很快浮现:如何避免在"暴露给外部智能体的工具"和"应用内部直接使用的工具"之间重复实现同一套逻辑?
本文介绍一种基于代理(proxy)的简单做法,用来在 Laravel AI SDK 中复用 Laravel MCP 工具。下面会展示如何连接这两端、如何设计可复用的结构,并通过一个来自内部 Bug 追踪系统的实际案例加以说明。
Laravel MCP,让应用对 AI 智能体可用
Laravel MCP 让一个 Laravel 应用可以成为兼容 Model Context Protocol 的服务器。具体而言,它允许 AI 客户端发现并调用应用内的部分能力:工具(tool)、资源(resource)、提示(prompt)。
一个 MCP 工具可以:
- 在内部系统里查询某个请求;
- 创建一个任务;
- 对客户档案做摘要;
- 读取业务数据;
- 触发应用内的某个动作。
最核心的价值在于:把这些能力开放给外部智能体,例如 Claude Desktop、ChatGPT、GitHub Copilot 或其它兼容环境。这对快速验证想法、打磨提示词、探索不同工作流、以及让开发者以"被辅助"的方式与应用互动,都格外有用。
Laravel AI SDK,把 AI 直接集成进应用
Laravel AI SDK 面向的是互补的需求。它的重点不是把工具暴露给外部客户端,而是把 AI 能力直接嵌入 Laravel 应用本身。
SDK 提供统一 API,用来对接不同 AI 服务商、创建智能体、调用工具、处理结构化输出、生成 embedding、处理文件等。
在 Laravel 应用中,这让以下使用场景成为可能:
- 内嵌在用户界面的助手;
- 用于请求分类的分诊智能体;
- 自动摘要工具;
- 写作辅助;
- 对内部数据的智能分析;
- 带上下文的推荐引擎。
换言之,Laravel MCP 用于把应用暴露给外部智能体,Laravel AI SDK 则适合把对应能力直接融进产品本身。
推荐的集成思路
一种值得推荐的集成思路是:
- 用 Laravel MCP 创建业务工具。
- 把它们暴露给 GitHub Copilot、Claude、ChatGPT 等外部智能体。
- 快速验证不同的提示词与工作流。
- 再把同一批工具,通过 Laravel AI SDK 在应用内部的专用智能体中复用。
这一路径先保留一个高度灵活的探索阶段。开发者可以直接操作 MCP 工具、调整参数、观察响应、打磨提示词。
等到行为稳定到可接受的程度,同一批能力便可作为专用智能体集成进应用本身——从实验环境过渡到产品功能,不需要把业务逻辑再写一遍。
问题,两套接口、同一份逻辑
矛盾在于:目前还不能把本地或远程的 MCP 服务器直接接到 Laravel AI SDK 上,并且 Laravel MCP 工具与 AI SDK 工具实现的接口并不完全一致。
一个 MCP 工具已经具备:
- 名称;
- 描述;
- 输入 schema;
handle方法;- 可复用的业务逻辑。
Laravel AI SDK 工具需要的是非常相似的元素:
- 名称;
- 描述;
- schema;
handle方法。
概念层面两边几乎同形。但若不做适配,就会陷入代码重复——同一个工具要写两份:一份供 MCP 使用,另一份供 AI SDK 使用。
可行的简单做法是:构造一个代理类,把一个 Laravel MCP 工具包装成 Laravel AI SDK 兼容的工具。
解法,在 Laravel MCP 与 AI SDK 之间搭一层代理
下面是该 ProxyMcpTool 类的一个精简版本:
<?php
namespace App\Ai\Tools;
use Illuminate\Contracts\JsonSchema\JsonSchema;
use Illuminate\Support\Facades\App;
use Laravel\Ai\Contracts\Tool;
use Laravel\Ai\Tools\Request as AgentRequest;
use Laravel\Mcp\Request as McpRequest;
use Laravel\Mcp\ResponseFactory;
use Laravel\Mcp\Server\Tool as McpTool;
use Stringable;
class ProxyMcpTool implements Tool
{
protected McpTool $tool;
public function __construct(McpTool|string $tool)
{
$this->tool = $tool instanceof McpTool ? $tool : App::make($tool);
}
/**
* 获取工具名。
*/
public function name(): string
{
return $this->tool->name();
}
/**
* 获取工具用途描述。
*/
public function description(): string
{
return $this->tool->description();
}
/**
* 执行工具。
*/
public function handle(AgentRequest $request): Stringable|string
{
$mcpRequest = new McpRequest($request->all());
/** @var \Laravel\Mcp\Response|\Laravel\Mcp\ResponseFactory $response */
$response = App::call([$this->tool, 'handle'], [
'request' => $mcpRequest,
]);
$data = $response instanceof ResponseFactory
? json_encode($response->getStructuredContent())
: (string)$response->content();
return $data;
}
/**
* 返回工具的 schema 定义。
*/
public function schema(JsonSchema $schema): array
{
return $this->tool->schema($schema);
}
}思路有意写得朴素:代理类实现 Laravel\Ai\Contracts\Tool 契约,把全部工作委派给底层的 MCP 工具。
名称、描述、schema 都从 MCP 工具直接取用。当 Laravel AI SDK 的智能体调用这个工具时,代理把 SDK 请求转换成 MCP 请求,再调用 MCP 工具的 handle。
这样业务逻辑保持唯一事实来源。
一个真实案例,内部 Bug 追踪系统
在实际项目中,这套思路被用来围绕一套内部 Bug 追踪系统构建了多个专用 MCP 工具。
它们可以承担例如:
- 查看某个请求的详情;
- 分析一张工单的上下文;
- 识别缺失信息;
- 给出优先级建议;
- 辅助新请求的分诊。
起初,这些工具被接到了 GitHub Copilot、ChatGPT 与 Claude 上,用来测试不同提示词与工作流。这一阶段帮团队迅速验证了"哪些做得好、哪些需要调整、应该给智能体哪些约束"。
在行为稳定下来之后,同一批工具又被复用进 Bug 追踪系统内部的专用智能体。例如,新请求被创建时一个钩子触发,由分诊智能体对其进行分析、给出分类建议、识别潜在重复项,帮助团队更快介入。
这样的自动化不替代人类判断。它减少摩擦、加速若干重复环节,让团队把精力留给真正需要经验判断的决策。
为什么这样做值得
这种做法带来几点好处:
- 减少代码重复;
- 业务逻辑集中在一处;
- 让"实验阶段"与"生产使用"之间更对齐;
- 让 AI 能力在应用中渐进地落地;
- 让工具在正式纳入产品体验之前,有更方便的验证通道。
它也呼应软件开发里的一条重要理念:从小处起步,快速验证,再把真正能带来价值的部分逐步沉淀下来。
结语
Laravel 的 AI 生态演进很快,这对希望在不偏离既有 Laravel 实践的前提下集成 AI 智能体的团队是好消息。
理想情况下,这种在 Laravel MCP 与 Laravel AI SDK 之间复用工具的能力,未来会成为 Laravel 生态的原生特性。如果 Laravel AI SDK 能直接连接本地或远程 MCP 服务器,并能指定哪些工具被允许使用,力度还会更强。
在此之前,一个如上所示的代理类,已经足以让团队先动起来。它提供的是一套简单、务实、与"好奇心驱动探索、高效协作、交付能简化日常工作的方案"这一工程节奏相契合的路径。