跳转到主要内容

首次创建支持 Copilot 的 Laravel 应用

在本指南中,你将使用 Laravel Copilot SDK 创建一个命令行助手。 从发送一个 prompt 开始,逐步进入会话、事件和工具。

前置条件

在开始之前,请确认以下几点。
  • 已经安装并认证 GitHub Copilot CLI
  • PHP 8.4+
  • Laravel 13.x
确认 CLI 是否可用。
copilot --version

安装 SDK

使用 Composer 安装包。
composer require revolution/laravel-copilot-sdk
根据需要发布配置。
php artisan vendor:publish --tag=copilot-config
必要时在 .env 中设置 CLI 的路径。
COPILOT_CLI_PATH=copilot

发送第一条消息

创建命令并调用 Copilot::run()
<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Revolution\Copilot\Facades\Copilot;

class CopilotDemo extends Command
{
    protected $signature = 'copilot:demo';
    protected $description = 'Demo Copilot SDK';

    public function handle()
    {
        $response = Copilot::run(prompt: 'What is 2 + 2?');

        $this->info($response->content());
    }
}
运行该命令。
php artisan copilot:demo

在会话中维持上下文

如果要在一次对话中使用多个 prompt,使用 Copilot::start()
use Revolution\Copilot\Contracts\CopilotSession;
use Revolution\Copilot\Facades\Copilot;

Copilot::start(function (CopilotSession $session) {
    $response = $session->sendAndWait(prompt: 'What is 2 + 2?');
    $this->info('Answer: '.$response->content());

    $response = $session->sendAndWait(prompt: 'Now multiply that by 3');
    $this->info('Answer: '.$response->content());
});

处理会话事件

使用 on() 注册事件处理器,用于检查助手消息和失败情况。
use Revolution\Copilot\Contracts\CopilotSession;
use Revolution\Copilot\Facades\Copilot;
use Revolution\Copilot\Types\SessionEvent;

Copilot::start(function (CopilotSession $session) {
    $session->on(function (SessionEvent $event): void {
        if ($event->isAssistantMessage()) {
            $this->info($event->content());
        } elseif ($event->failed()) {
            $this->error($event->errorMessage() ?? 'Unknown error');
        }
    });

    $session->sendAndWait(prompt: 'Tell me a short Laravel joke');
});

添加自定义工具

使用 JSON schema 和处理器定义工具。
use Illuminate\JsonSchema\JsonSchema;
use Revolution\Copilot\Contracts\CopilotSession;
use Revolution\Copilot\Facades\Copilot;
use Revolution\Copilot\Types\SessionConfig;
use Revolution\Copilot\Types\Tool;

$parameters = JsonSchema::object([
    'topic' => JsonSchema::string()
        ->description('Topic to look up')
        ->required(),
])->toArray();

$config = new SessionConfig(
    tools: [
        Tool::define(
            name: 'lookup_fact',
            description: 'Returns a fact for a topic.',
            parameters: $parameters,
            handler: function (array $params): array {
                $topic = $params['topic'] ?? '';

                return [
                    'textResultForLlm' => "Fact for {$topic}",
                    'resultType' => 'success',
                    'sessionLog' => "lookup_fact: {$topic}",
                    'toolTelemetry' => [],
                ];
            },
        ),
    ],
);

Copilot::start(function (CopilotSession $session) {
    $response = $session->sendAndWait(
        prompt: 'Use lookup_fact to tell me something about Laravel.'
    );

    $this->info($response->content());
}, config: $config);

创建交互式助手

把会话、事件和工具整合起来,你就可以创建一个交互式的 Artisan 命令。
<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\JsonSchema\JsonSchema;
use Revolution\Copilot\Contracts\CopilotSession;
use Revolution\Copilot\Facades\Copilot;
use Revolution\Copilot\Types\SessionConfig;
use Revolution\Copilot\Types\SessionEvent;
use Revolution\Copilot\Types\Tool;
use Revolution\Copilot\Types\ToolResultObject;

use function Laravel\Prompts\error;
use function Laravel\Prompts\info;
use function Laravel\Prompts\note;
use function Laravel\Prompts\spin;
use function Laravel\Prompts\text;

class CopilotAssistant extends Command
{
    protected $signature = 'copilot:assistant';
    protected $description = 'Interactive Copilot assistant';

    public function handle()
    {
        $facts = [
            'PHP' => 'A popular general-purpose scripting language for web development.',
            'Laravel' => 'A web application framework with expressive, elegant syntax.',
            'Composer' => 'Dependency manager for PHP.',
        ];

        $parameters = JsonSchema::object([
            'topic' => JsonSchema::string()
                ->description('Topic to look up')
                ->required(),
        ])->toArray();

        $config = new SessionConfig(
            tools: [
                Tool::define(
                    name: 'lookup_fact',
                    description: 'Returns a fun fact about a given topic.',
                    parameters: $parameters,
                    handler: function (array $params) use ($facts) {
                        $topic = $params['topic'] ?? '';
                        $fact = $facts[$topic] ?? "No fact available for {$topic}.";

                        return new ToolResultObject(
                            textResultForLlm: $fact,
                            resultType: 'success',
                            sessionLog: "lookup_fact: {$topic}",
                            toolTelemetry: [],
                        );
                    },
                ),
            ],
        );

        Copilot::start(function (CopilotSession $session) {
            info('Copilot assistant');
            info("Session: {$session->id()}");
            info("Try: Use lookup_fact to tell me about Laravel");

            $session->on(function (SessionEvent $event): void {
                if ($event->isAssistantMessage()) {
                    note($event->content());
                } elseif ($event->failed()) {
                    error($event->errorMessage() ?? 'Unknown error');
                }
            });

            while (true) {
                $prompt = text(
                    label: 'You',
                    placeholder: 'Ask me anything...',
                    required: true,
                    hint: 'Ctrl+C to exit',
                );

                spin(
                    callback: fn () => $session->sendAndWait($prompt),
                    message: 'Thinking...',
                );

                echo "\n";
            }
        }, config: $config);
    }
}
运行该命令。
php artisan copilot:assistant

工具的工作原理

定义工具时需要指定以下 3 点。
  1. 工具做什么。
  2. 接收哪些参数。
  3. 执行哪段处理器代码。
Copilot 会根据用户输入判断工具调用,SDK 会执行处理器并返回结果。

接下来可以尝试的功能

连接 MCP 服务器

use Revolution\Copilot\Types\SessionConfig;

$config = new SessionConfig(
    mcpServers: [
        'github' => [
            'type' => 'http',
            'url' => 'https://api.githubcopilot.com/mcp/',
        ],
    ],
);

创建自定义代理

use Revolution\Copilot\Types\SessionConfig;

$config = new SessionConfig(
    customAgents: [
        [
            'name' => 'pr-reviewer',
            'displayName' => 'PR Reviewer',
            'description' => 'Reviews pull requests for best practices',
            'prompt' => 'You are an expert code reviewer. Focus on security, performance, and maintainability.',
        ],
    ],
);

自定义 system 消息

use Revolution\Copilot\Types\SessionConfig;
use Revolution\Copilot\Types\SystemMessageConfig;

$config = new SessionConfig(
    systemMessage: new SystemMessageConfig(
        content: 'You are a helpful assistant for our engineering team. Always be concise.',
    ),
);

连接外部 CLI 服务器

以服务器模式启动 Copilot CLI。
copilot --headless --port 4321
然后在 .env 中设置连接目标 URL。
COPILOT_URL=tcp://127.0.0.1:4321
设置 COPILOT_URL 后,SDK 不会启动新的 CLI 进程,而是连接到现有服务器。

遥测与可观测性

config/copilot.php 中配置遥测。
'telemetry' => [
    'otlpEndpoint' => 'http://localhost:4318',
],
或直接配置。
use Revolution\Copilot\Facades\Copilot;
use Revolution\Copilot\Types\TelemetryConfig;

Copilot::useStdio([
    'telemetry' => new TelemetryConfig(
        otlpEndpoint: 'http://localhost:4318',
    ),
]);

进一步学习

下一步

认证

选择适合本地环境和 CI 的认证方式。

SessionConfig

配置模型、钩子、MCP 服务器与运行时行为。

SessionEvent

了解 Laravel 特有的事件辅助工具与生命周期处理。

权限请求

查看通过显式批准来执行工具的权限流程。

工具

从 Copilot 调用应用程序代码。

MCP

连接 MCP 服务器的现成工具。
至此,你已经浏览了从一次性 prompt 到工具协作会话的 Laravel Copilot SDK 核心流程。
最后修改于 2026年7月13日