Laravel AI SDK 智能代理实战

摘要

智能代理(Agent)是 Laravel AI SDK 的核心功能之一,允许构建能够使用工具、访问外部数据并执行复杂任务的 AI 系统。本文将深入讲解如何使用 Laravel AI SDK 构建智能代理,包括:

  • 智能代理的核心概念与架构
  • 创建自定义代理类
  • 工具定义与注册
  • 工具调用流程与结果处理
  • RAG(检索增强生成)实现
  • 实战案例:销售教练代理

本文适合希望构建复杂 AI 应用的开发者,需要具备 Laravel AI SDK 基础知识。

1. 智能代理概述

1.1 什么是智能代理

智能代理是一种能够自主决策、使用工具并与外部系统交互的 AI 系统。与简单的问答不同,代理可以:

  • 理解用户意图
  • 选择合适的工具
  • 执行多步骤任务
  • 整合多个数据源
  • 提供结构化输出

1.2 代理架构

1
2
3
用户请求 -> 代理 -> 工具选择 -> 工具执行 -> 结果整合 -> 响应
↑ |
└──────────── 迭代循环 ←───────────────┘

1.3 Laravel AI SDK 代理特性

特性描述
工具调用自动选择并执行工具
多轮对话保持上下文记忆
结构化输出返回特定格式的数据
向量搜索RAG 能力支持
流式响应实时输出结果

2. 创建代理类

2.1 基本代理结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?php

namespace App\Ai\Agents;

use Laravel\Ai\Agent;
use Laravel\Ai\Contracts\AgentContract;

class SalesCoach extends Agent implements AgentContract
{
protected string $name = 'Sales Coach';

protected string $description = 'A helpful assistant for sales team training';

protected string $instructions = <<<INSTRUCTIONS
You are an expert sales coach. Your role is to:
- Analyze sales transcripts
- Provide feedback on sales techniques
- Suggest improvements
- Answer questions about sales best practices

Always be constructive and specific in your feedback.
INSTRUCTIONS;

public function tools(): array
{
return [
// 工具列表
];
}
}

2.2 代理配置

1
2
3
4
5
6
7
8
9
10
11
12
class SalesCoach extends Agent
{
protected string $model = 'gpt-4';

protected int $maxTokens = 2000;

protected float $temperature = 0.7;

protected int $maxSteps = 10;

protected bool $stream = true;
}

2.3 使用代理

1
2
3
4
5
use App\Ai\Agents\SalesCoach;

$response = SalesCoach::make()->prompt('Analyze this sales transcript...');

echo (string) $response;

3. 工具定义

3.1 创建工具类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<?php

namespace App\Ai\Tools;

use Laravel\Ai\Tool;
use App\Services\CRMService;

class GetCustomerInfo extends Tool
{
public function __construct(
protected CRMService $crm
) {}

public function name(): string
{
return 'get_customer_info';
}

public function description(): string
{
return 'Get customer information from CRM by email';
}

public function parameters(): array
{
return [
'email' => [
'type' => 'string',
'description' => 'Customer email address',
'required' => true,
],
];
}

public function execute(array $arguments): mixed
{
return $this->crm->findByEmail($arguments['email']);
}
}

3.2 注册工具

1
2
3
4
5
6
7
8
9
10
11
class SalesCoach extends Agent
{
public function tools(): array
{
return [
new GetCustomerInfo(app(CRMService::class)),
new SearchKnowledgeBase(),
new LogInteraction(),
];
}
}

3.3 闭包工具

1
2
3
4
5
6
7
8
9
10
11
12
13
14
use Laravel\Ai\Facades\Tool;

class SalesCoach extends Agent
{
public function tools(): array
{
return [
Tool::make('get_weather')
->description('Get current weather for a location')
->parameter('location', 'string', 'City name', true)
->execute(fn($args) => $this->getWeather($args['location'])),
];
}
}

4. 工具调用流程

4.1 自动工具选择

1
2
3
4
5
6
7
8
9
$response = SalesCoach::make()->prompt(
'What products has customer john@example.com purchased?'
);

// 代理自动:
// 1. 识别需要使用 get_customer_info 工具
// 2. 提取参数 email = 'john@example.com'
// 3. 执行工具获取客户信息
// 4. 整合结果生成响应

4.2 多工具调用

1
2
3
4
5
6
7
8
$response = SalesCoach::make()->prompt(
'Compare the purchase history of john@example.com and jane@example.com'
);

// 代理会依次调用:
// 1. get_customer_info(email: 'john@example.com')
// 2. get_customer_info(email: 'jane@example.com')
// 3. 整合两个结果进行比较

4.3 工具调用日志

1
2
3
4
5
6
7
$response = SalesCoach::make()->prompt('...');

foreach ($response->toolCalls() as $call) {
echo "Tool: {$call->name}\n";
echo "Arguments: " . json_encode($call->arguments) . "\n";
echo "Result: " . json_encode($call->result) . "\n";
}

5. 内置工具

5.1 相似性搜索工具

1
2
3
4
5
6
7
8
9
10
11
12
13
14
use Laravel\Ai\Tools\SimilaritySearch;

class SalesCoach extends Agent
{
public function tools(): array
{
return [
SimilaritySearch::make()
->table('knowledge_base')
->embeddingColumn('embedding')
->contentColumn('content'),
];
}
}

5.2 Web 搜索工具

1
2
3
4
5
6
7
8
9
10
11
12
13
use Laravel\Ai\Tools\WebSearch;

class ResearchAgent extends Agent
{
public function tools(): array
{
return [
WebSearch::make()
->provider('google')
->maxResults(5),
];
}
}

5.3 数据库查询工具

1
2
3
4
5
6
7
8
9
10
11
12
13
14
use Laravel\Ai\Tools\DatabaseQuery;

class AnalyticsAgent extends Agent
{
public function tools(): array
{
return [
DatabaseQuery::make()
->connection('analytics')
->allowedTables(['users', 'orders', 'products'])
->readOnly(true),
];
}
}

6. RAG 实现

6.1 文档嵌入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
use Illuminate\Support\Str;
use App\Models\Document;

class DocumentProcessor
{
public function process(string $content): Document
{
$chunks = Str::of($content)
->splitIntoChunks(1000)
->toArray();

$documents = [];

foreach ($chunks as $chunk) {
$embedding = Str::of($chunk)->toEmbeddings();

$documents[] = Document::create([
'content' => $chunk,
'embedding' => $embedding,
]);
}

return $documents;
}
}

6.2 向量搜索

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
use Laravel\Ai\Tools\SimilaritySearch;

class KnowledgeAgent extends Agent
{
public function tools(): array
{
return [
SimilaritySearch::make()
->table('documents')
->embeddingColumn('embedding')
->contentColumn('content')
->threshold(0.8)
->limit(5),
];
}
}

6.3 使用 RAG 代理

1
2
3
4
5
6
7
8
$response = KnowledgeAgent::make()->prompt(
'What are our refund policies for digital products?'
);

// 代理会:
// 1. 将问题转换为向量
// 2. 在文档库中搜索相似内容
// 3. 使用检索到的内容生成回答

7. 实战案例:销售教练代理

7.1 完整代理实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
<?php

namespace App\Ai\Agents;

use Laravel\Ai\Agent;
use Laravel\Ai\Tools\SimilaritySearch;
use App\Ai\Tools\GetCustomerInfo;
use App\Ai\Tools\GetProductInfo;
use App\Ai\Tools\LogInteraction;

class SalesCoach extends Agent
{
protected string $name = 'Sales Coach';

protected string $description = 'Expert sales training assistant';

protected string $instructions = <<<INSTRUCTIONS
You are an expert sales coach with years of experience in B2B sales.

Your responsibilities:
- Analyze sales call transcripts and provide constructive feedback
- Suggest improvements for sales techniques
- Help with objection handling
- Provide product information when needed
- Track customer interactions

Guidelines:
- Always be specific and actionable in feedback
- Reference relevant sales methodologies
- Consider the customer's perspective
- Suggest concrete next steps
INSTRUCTIONS;

protected string $model = 'gpt-4';

protected int $maxTokens = 2000;

protected float $temperature = 0.7;

public function tools(): array
{
return [
SimilaritySearch::make()
->table('sales_knowledge')
->embeddingColumn('embedding')
->contentColumn('content')
->description('Search sales knowledge base for best practices'),

new GetCustomerInfo(),
new GetProductInfo(),
new LogInteraction(),
];
}
}

7.2 控制器使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?php

namespace App\Http\Controllers;

use App\Ai\Agents\SalesCoach;
use Illuminate\Http\Request;

class SalesCoachController extends Controller
{
public function analyze(Request $request)
{
$validated = $request->validate([
'transcript' => 'required|string',
'customer_email' => 'nullable|email',
]);

$prompt = $validated['customer_email']
? "Analyze this sales call with customer {$validated['customer_email']}:\n\n{$validated['transcript']}"
: "Analyze this sales call:\n\n{$validated['transcript']}";

$response = SalesCoach::make()->prompt($prompt);

return response()->json([
'analysis' => (string) $response,
'tool_calls' => $response->toolCalls(),
'usage' => $response->usage(),
]);
}
}

7.3 Livewire 组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?php

namespace App\Http\Livewire;

use Livewire\Component;
use App\Ai\Agents\SalesCoach;

class SalesCoachAssistant extends Component
{
public string $transcript = '';
public string $analysis = '';
public bool $analyzing = false;

public function analyze()
{
$this->validate([
'transcript' => 'required|min:100',
]);

$this->analyzing = true;
$this->analysis = '';

foreach (SalesCoach::make()->stream($this->transcript) as $chunk) {
$this->analysis .= $chunk;
$this->stream('analysis', $this->analysis);
}

$this->analyzing = false;
}

public function render()
{
return view('livewire.sales-coach-assistant');
}
}

8. 高级特性

8.1 多代理协作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class SalesTeamOrchestrator
{
public function handle(Request $request)
{
$transcript = $request->input('transcript');

$analysis = SalesCoach::make()
->prompt("Analyze: {$transcript}");

$feedback = FeedbackSpecialist::make()
->withContext(['analysis' => $analysis])
->prompt("Provide detailed feedback");

$actionItems = ActionPlanner::make()
->withContext(['analysis' => $analysis, 'feedback' => $feedback])
->prompt("Create action items");

return [
'analysis' => $analysis,
'feedback' => $feedback,
'action_items' => $actionItems,
];
}
}

8.2 代理记忆

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class SalesCoach extends Agent
{
protected bool $withMemory = true;

protected int $memoryLimit = 10;

public function prompt(string $message, array $options = [])
{
$conversationId = $options['conversation_id'] ?? null;

if ($conversationId) {
$this->loadMemory($conversationId);
}

$response = parent::prompt($message, $options);

if ($conversationId) {
$this->saveMemory($conversationId);
}

return $response;
}
}

8.3 代理中间件

1
2
3
4
5
6
7
8
class SalesCoach extends Agent
{
protected array $middleware = [
RateLimitMiddleware::class,
LoggingMiddleware::class,
ContentFilterMiddleware::class,
];
}

9. 测试代理

9.1 单元测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?php

namespace Tests\Unit\Agents;

use Tests\TestCase;
use App\Ai\Agents\SalesCoach;
use Laravel\Ai\Facades\Ai;

class SalesCoachTest extends TestCase
{
public function test_analyzes_sales_transcript()
{
Ai::fake([
'response' => 'Great use of open-ended questions...',
]);

$response = SalesCoach::make()->prompt('Test transcript');

$this->assertStringContainsString('open-ended', $response);
}

public function test_uses_customer_info_tool()
{
Ai::fake();

SalesCoach::make()->prompt('What did john@example.com buy?');

Ai::assertToolCalled('get_customer_info', ['email' => 'john@example.com']);
}
}

9.2 集成测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php

namespace Tests\Feature;

use Tests\TestCase;
use App\Ai\Agents\SalesCoach;

class SalesCoachIntegrationTest extends TestCase
{
public function test_full_analysis_workflow()
{
$response = $this->postJson('/api/sales-coach/analyze', [
'transcript' => file_get_contents(__DIR__ . '/fixtures/transcript.txt'),
'customer_email' => 'test@example.com',
]);

$response->assertStatus(200)
->assertJsonStructure([
'analysis',
'tool_calls',
'usage',
]);
}
}

10. 最佳实践

10.1 工具设计原则

  1. 单一职责:每个工具只做一件事
  2. 清晰描述:让代理理解何时使用
  3. 参数验证:确保输入有效
  4. 错误处理:返回有意义的错误信息
  5. 幂等性:相同输入产生相同结果

10.2 提示词优化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
protected string $instructions = <<<INSTRUCTIONS
You are an expert sales coach.

## Primary Goals
- Improve sales team performance
- Provide actionable feedback
- Support customer success

## Available Tools
- get_customer_info: Use when customer details are needed
- search_knowledge: Use for sales best practices
- log_interaction: Use to record customer touchpoints

## Response Format
1. Summary of key observations
2. Specific recommendations
3. Suggested next steps
INSTRUCTIONS;

10.3 性能优化

1
2
3
4
5
6
7
8
class SalesCoach extends Agent
{
protected bool $cacheTools = true;

protected int $cacheTtl = 3600;

protected bool $parallelToolCalls = true;
}

11. 总结

Laravel AI SDK 的智能代理功能为构建复杂 AI 应用提供了强大支持:

  1. 声明式工具定义:简单直观的工具创建
  2. 自动工具选择:代理智能选择合适的工具
  3. RAG 支持:开箱即用的检索增强生成
  4. 多代理协作:构建复杂工作流
  5. 测试友好:完善的测试支持

通过本指南,您已经掌握了构建智能代理的核心技能,可以开始构建自己的 AI 驱动应用了。

参考资料