PHP code example of kode / ai-agent
1. Go to this page and download the library: Download kode/ai-agent library . Choose the download type require .
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
kode / ai-agent example snippets
use Kode\AiAgent\Infrastructure\Adapter\AdapterFactory;
// 快速创建 OpenAI 适配器
$adapter = AdapterFactory::openai('sk-xxx', [
'model' => 'gpt-4o',
'timeout' => 30,
]);
// 快速创建 Anthropic 适配器
$adapter = AdapterFactory::anthropic('sk-ant-xxx');
// 快速创建 Gemini 适配器
$adapter = AdapterFactory::gemini('AIza-xxx');
// 通用创建方式
$adapter = AdapterFactory::create('deepseek', [
'api_key' => 'sk-xxx',
'model' => 'deepseek-chat',
]);
use Kode\AiAgent\Support\Builder\AgentBuilder;
// 构建适配器
$adapter = AgentBuilder::create()
->withPlatform('openai')
->withApiKey('sk-xxx')
->withModel('gpt-4o')
->withTemperature(0.7)
->withTimeout(60)
->withRetry(3, 1000)
->build();
// 构建 Agent(包含工具)
$agent = AgentBuilder::create()
->withPlatform('openai')
->withApiKey('sk-xxx')
->withSystemPrompt('你是一个有用的助手')
->withTool('calculator', '计算器', fn($a, $b) => $a + $b)
->withMaxToolCalls(5)
->buildAgent();
use Kode\AiAgent\Support\Facade\Ai;
use Kode\AiAgent\Infrastructure\Adapter\AdapterFactory;
// 设置默认适配器
$adapter = AdapterFactory::openai('sk-xxx');
Ai::setDefaultAdapter($adapter);
// 发送消息
$response = Ai::chat('你好,世界!');
echo $response->content();
// 流式响应
foreach (Ai::stream('讲一个故事') as $chunk) {
echo $chunk;
}
use Kode\AiAgent\Agent\Agent;
use Kode\AiAgent\Agent\RoleAgentTeam;
use Kode\AiAgent\Infrastructure\Adapter\AdapterFactory;
$chief = new Agent(AdapterFactory::openai('sk-chief-xxx', ['model' => 'gpt-4o']));
$analyst = new Agent(AdapterFactory::deepseek('sk-analyst-xxx', ['model' => 'deepseek-chat']));
$executor = new Agent(AdapterFactory::anthropic('sk-exec-xxx', ['model' => 'claude-3-5-sonnet']));
$team = (new RoleAgentTeam())
->assign('总工', $chief)
->assign('分析员', $analyst)
->assign('执行员', $executor);
$result = $team->run('建设 MCP 工具链路', [
['role' => '总工', 'task' => '根据目标制定技术路线:{{goal}}'],
['role' => '分析员', 'task' => '拆解任务并识别风险'],
['role' => '执行员', 'task' => '按拆解结果输出实现步骤'],
]);
foreach ($result['outputs'] as $output) {
echo "[{$output['role']}] {$output['content']}\n";
}
// 自动路由:根据任务内容命中角色
$team->routes([
'架构|方案|设计' => '总工',
'分析|风险|拆解' => '分析员',
'开发|实现|修复' => '执行员',
]);
$auto = $team->auto('请先分析需求并识别风险');
echo $auto->content();
use Kode\AiAgent\Support\Facade\Ai;
use Kode\AiAgent\Infrastructure\Adapter\AdapterFactory;
Ai::register('chief', AdapterFactory::openai('sk-chief-xxx'));
Ai::register('analyst', AdapterFactory::deepseek('sk-analyst-xxx'));
Ai::register('executor', AdapterFactory::anthropic('sk-exec-xxx'));
$team = Ai::team([
'总工' => 'chief',
'分析员' => 'analyst',
'执行员' => 'executor',
]);
use Kode\AiAgent\MCP\MCPClient;
use Kode\AiAgent\MCP\MCPServer;
$server = new MCPServer(['name' => 'demo-mcp', 'version' => '1.0.0']);
$server->registerTool('sum', '求和', fn(array $args) => ($args['a'] ?? 0) + ($args['b'] ?? 0), [
'a' => 'number',
'b' => 'number',
]);
$client = new MCPClient(transport: fn(array $request) => $server->handle($request));
$client->connect('mcp://local');
$tools = $client->listTools();
$value = $client->callTool('sum', ['a' => 1, 'b' => 2]);
// 检查平台支持
AdapterFactory::supports('openai'); // true
AdapterFactory::supports('claude'); // true (别名)
AdapterFactory::supports('unknown'); // false
// 获取所有支持的平台
$platforms = AdapterFactory::supported();
// ['openai', 'anthropic', 'claude', 'deepseek', 'aliyun', 'qwen', 'tongyi',
// 'gemini', 'google', 'baidu', 'wenxin', 'ernie', 'tencent', 'hunyuan',
// 'xunfei', 'spark', 'xinghuo']
use Kode\AiAgent\Infrastructure\Adapter\AdapterFactory;
// 百度文心一言(需要 API Key + Secret Key 获取 Access Token)
$adapter = AdapterFactory::baidu('your-api-key', 'your-secret-key', [
'model' => 'completions_pro',
]);
// 或直接使用 Access Token
$adapter = AdapterFactory::create('baidu', [
'access_token' => 'your-access-token',
'model' => 'completions_pro',
]);
// 腾讯混元(使用 TC3-HMAC-SHA256 签名)
$adapter = AdapterFactory::tencent('your-secret-id', 'your-secret-key', [
'model' => 'hunyuan-lite',
'region' => 'ap-guangzhou',
]);
// 讯飞星火(三元组认证:AppId + API Key + API Secret)
$adapter = AdapterFactory::xunfei('your-app-id', 'your-api-key', 'your-api-secret', [
'model' => 'generalv3.5',
]);
// 阿里云通义千问(支持两种认证方式)
// 方式1: API Key
$adapter = AdapterFactory::aliyun('your-api-key');
// 方式2: AppKey + AppSecret(签名认证)
$adapter = AdapterFactory::create('aliyun', [
'app_key' => 'your-app-key',
'app_secret' => 'your-app-secret',
'model' => 'qwen-turbo',
]);
use Kode\AiAgent\Domain\ValueObject\ApiKey;
$key = ApiKey::fromEnv('OPENAI_API_KEY');
// 或
$key = ApiKey::fromString('sk-1234567890abcdefghijklmnop');
echo $key->value(); // sk-1234567890abcdefghijklmnop
echo $key->masked(); // sk-1...mnop
echo $key->isValid(); // true
$key = ApiKey::dual('sk-primary-xxx', 'sk-secondary-xxx');
echo $key->current(); // sk-primary-xxx (主 Key)
echo $key->strategy(); // failover
// 主 Key 失败时切换
$failed = $key->failover();
echo $failed->current(); // sk-secondary-xxx
$key = ApiKey::rotating([
'sk-key-one-xxx',
'sk-key-two-xxx',
'sk-key-three-xxx',
], 'round_robin');
echo $key->current(); // sk-key-one-xxx
echo $key->next(); // sk-key-two-xxx
echo $key->count(); // 3
// 轮换到下一个
$rotated = $key->rotate();
echo $rotated->current(); // sk-key-two-xxx
// 创建 AppKey + AppSecret 凭证
$key = ApiKey::appSecret('app-key-xxx', 'app-secret-xxx', [
'region' => 'cn-hangzhou',
'account_id' => '123456',
]);
echo $key->appKey(); // app-key-xxx
echo $key->secret(); // app-secret-xxx
echo $key->extra('region'); // cn-hangzhou
// 检查模式
$key->isAppSecretMode(); // true
// 生成签名
$signature = $key->sign('POST', '/v1/chat', ['query' => 'hello']);
// 生成带签名的请求头
$headers = $key->signedHeaders('POST', '/v1/chat', ['query' => 'hello']);
// [
// 'X-App-Key' => 'app-key-xxx',
// 'X-Timestamp' => '1709512800',
// 'X-Nonce' => 'abc123...',
// 'X-Signature' => 'hmac-sha256...',
// ]
// 获取脱敏凭证信息
$masked = $key->maskedCredentials();
// ['app_key' => 'app-...-xxx', 'app_secret' => 'app-...-xxx']
// 单 Key
$key = ApiKey::fromArray([
'api_key' => 'sk-xxx',
]);
// 多 Key 轮换
$key = ApiKey::fromArray([
'keys' => ['sk-1', 'sk-2', 'sk-3'],
'strategy' => 'round_robin', // 或 'random', 'failover'
]);
// AppKey + AppSecret(阿里云、百度等)
$key = ApiKey::fromArray([
'app_key' => 'your-app-key',
'app_secret' => 'your-app-secret',
'extra' => [
'region' => 'cn-hangzhou',
'account_id' => '123456',
],
]);
use Kode\AiAgent\Store\MemoryVectorStore;
// 创建内存向量存储
$store = new MemoryVectorStore(dimension: 1536);
// 插入向量
$store->upsert('doc-1', [0.1, 0.2, 0.3], ['title' => '文档1']);
$store->upsert('doc-2', [0.4, 0.5, 0.6], ['title' => '文档2']);
// 批量插入
$store->upsertBatch([
['id' => 'doc-3', 'vector' => [0.7, 0.8, 0.9], 'metadata' => ['title' => '文档3']],
['id' => 'doc-4', 'vector' => [1.0, 1.1, 1.2], 'metadata' => ['title' => '文档4']],
]);
// 相似度搜索(余弦相似度)
$results = $store->search([0.1, 0.2, 0.3], limit: 5, filters: []);
// [
// ['id' => 'doc-1', 'score' => 1.0, 'metadata' => ['title' => '文档1'],
// ['id' => 'doc-2', 'score' => 0.95, 'metadata' => ['title' => '文档2'],
// ]
// 获取向量
$doc = $store->get('doc-1');
// 删除向量
$store->delete('doc-1');
// 获取向量数量
$count = $store->count();
// 清空所有向量
$store->clear();
use Kode\AiAgent\MCP\MCPServer;
// 创建 MCP 服务器
$server = new MCPServer([
'name' => 'my-mcp-server',
'version' => '1.0.0',
]);
// 注册工具
$server->registerTool(
name: 'calculator',
description: '执行数学计算',
handler: function (array $args) {
$a = $args['a'] ?? 0;
$b = $args['b'] ?? 0;
return $a + $b;
},
parameters: ['a' => 'number', 'b' => 'number']
);
// 注册资源
$server->registerResource(
uri: 'file:///data/config.json',
provider: fn() => file_get_contents('config.json'),
mimeType: 'application/json'
);
// 处理 JSON-RPC 请求
$response = $server->handle([
'jsonrpc' => '2.0',
'method' => 'tools/call',
'params' => ['name' => 'calculator', 'arguments' => ['a' => 1, 'b' => 2],
'id' => 1,
]);
use Kode\AiAgent\Agent\Agent;
$agent = new Agent($adapter, [
'system_prompt' => '你是一个有用的助手',
'max_tool_calls' => 5,
]);
// 注册工具
$agent->registerTool('calculator', '执行数学计算', function (int $a, int $b, string $op = 'add'): int|float {
return match($op) {
'add' => $a + $b,
'sub' => $a - $b,
'mul' => $a * $b,
'div' => $a / $b,
};
});
// 发送消息(自动处理工具调用)
$response = $agent->chat('计算 10 + 5');
echo $response->content();
use Kode\AiAgent\Attribute\Tool;
use Kode\AiAgent\Agent\Agent;
class MyTools
{
#[Tool(name: 'weather', description: '获取天气信息')]
public function getWeather(string $city): string
{
return "{$city}今天晴,温度 25°C";
}
#[Tool(name: 'search', description: '搜索网络')]
public function search(string $query): array
{
return ['results' => ["关于 {$query} 的结果..."];
}
}
// 从类自动注册
$agent = Agent::fromClass(new MyTools(), $adapter);
use Kode\AiAgent\Chat\ChatSession;
use Kode\AiAgent\Infrastructure\Adapter\AdapterFactory;
$adapter = AdapterFactory::openai('sk-xxx');
$chat = new ChatSession($adapter, '你是一个有用的助手');
// 发送消息
$response = $chat->send('你好!');
echo $response->content();
// 继续对话(自动维护上下文)
$response = $chat->send('请继续');
echo $response->content();
// 流式对话
foreach ($chat->stream('讲个故事') as $chunk) {
echo $chunk;
flush();
}
// 查看对话历史
$messages = $chat->messages();
$count = $chat->count();
// 导出对话
$history = $chat->export();
// 清空历史
$chat->clear();
declare(strict_types=1);
namespace App\Adapter;
use Kode\AiAgent\Domain\Model\{AvatarResponse, ImageResponse, VideoResponse};
use Kode\AiAgent\Domain\ValueObject\{MediaFile, MultimodalCapability};
use Kode\AiAgent\Infrastructure\Adapter\AbstractMultimodalAdapter;
use Kode\HttpClient\HttpClient;
final class MyMultimodalAdapter extends AbstractMultimodalAdapter
{
public function __construct(
private readonly HttpClient $httpClient,
private readonly array $config = [],
) {
parent::__construct();
}
protected function initializeCapabilities(): void
{
$this->addCapabilities([
MultimodalCapability::TEXT_TO_IMAGE,
MultimodalCapability::IMAGE_EDIT,
MultimodalCapability::TEXT_TO_VIDEO,
MultimodalCapability::AVATAR_GENERATION,
MultimodalCapability::AVATAR_LIST,
MultimodalCapability::VOICE_LIST,
MultimodalCapability::ASYNC_GENERATION,
MultimodalCapability::PROGRESS_TRACKING,
]);
}
public function name(): string
{
return 'my-multimodal-platform';
}
public function generateImage(string $prompt, array $options = []): ImageResponse
{
$startTime = microtime(true);
$this->ensureCapability(MultimodalCapability::TEXT_TO_IMAGE);
$response = $this->httpClient->post('https://api.example.com/v1/images/generations', [
'json' => [
'prompt' => $prompt,
'model' => $options['model'] ?? 'image-model-v1',
'size' => $options['size'] ?? '1024x1024',
],
]);
$duration = microtime(true) - $startTime;
return new ImageResponse(
image: $response['data'][0]['url'] ?? '',
duration: $duration,
model: $options['model'] ?? 'image-model-v1',
);
}
public function generateVideo(string $prompt, array $options = []): VideoResponse
{
$startTime = microtime(true);
$this->ensureCapability(MultimodalCapability::TEXT_TO_VIDEO);
$response = $this->httpClient->post('https://api.example.com/v1/videos/generations', [
'json' => [
'prompt' => $prompt,
'model' => $options['model'] ?? 'video-model-v1',
'duration' => $options['duration'] ?? 5,
],
]);
$duration = microtime(true) - $startTime;
return new VideoResponse(
video: $response['data'][0]['url'] ?? '',
videoDuration: $options['duration'] ?? 5,
duration: $duration,
model: $options['model'] ?? 'video-model-v1',
);
}
public function generateAvatarVideo(string $text, array $options = []): AvatarResponse
{
$startTime = microtime(true);
$this->ensureCapability(MultimodalCapability::AVATAR_GENERATION);
$response = $this->httpClient->post('https://api.example.com/v1/avatars/generate', [
'json' => [
'text' => $text,
'avatar_id' => $options['avatar_id'] ?? 'default-female',
'voice_id' => $options['voice_id'] ?? 'voice-female-zh',
],
]);
$duration = microtime(true) - $startTime;
return $this->createAvatarResponse(
videoUrl: $response['data']['video_url'] ?? '',
avatarId: $options['avatar_id'] ?? 'default-female',
voiceId: $options['voice_id'] ?? 'voice-female-zh',
text: $text,
videoDuration: $response['data']['duration'] ?? 30.0,
duration: $duration,
model: 'avatar-model-v1'
);
}
}
use Kode\AiAgent\Support\Facade\Multimodal;
use Kode\AiAgent\Infrastructure\Persistence\LocalFileUploader;
use App\Adapter\MyMultimodalAdapter;
use Kode\HttpClient\HttpClient;
// 1. 创建文件上传器
$uploader = new LocalFileUploader(
uploadDir: __DIR__ . '/uploads',
baseUrl: 'https://example.com/uploads'
);
// 2. 设置文件上传器
Multimodal::setFileUploader($uploader);
// 3. 创建多模态适配器
$httpClient = new HttpClient();
$adapter = new MyMultimodalAdapter($httpClient, [
'api_key' => 'your-api-key',
]);
// 4. 创建并设置多模态服务
$service = Multimodal::createService($adapter);
Multimodal::setDefaultService($service);
use Kode\AiAgent\Support\Facade\Multimodal;
// 检查平台是否支持图像生成
if (Multimodal::supports(\Kode\AiAgent\Domain\ValueObject\MultimodalCapability::TEXT_TO_IMAGE)) {
// 生成图像
$response = Multimodal::generateImage('一只可爱的猫咪在花园里玩耍', [
'style' => 'photorealistic',
'size' => '1024x1024',
'quality' => 'high',
]);
// 获取图像 URL
echo $response->image();
// 转换为数组
print_r($response->toArray());
}
// 编辑现有图像
$response = Multimodal::editImage(
imagePath: '/path/to/original.jpg',
prompt: '把背景改成海滩',
options: [
'mask' => '/path/to/mask.png',
]
);
echo $response->image();
// 生成图像变体
$response = Multimodal::generateImageVariation(
imagePath: '/path/to/original.jpg',
options: [
'variations' => 3,
'strength' => 0.7,
]
);
echo $response->image();
// 检查平台是否支持视频生成
if (Multimodal::supports(\Kode\AiAgent\Domain\ValueObject\MultimodalCapability::TEXT_TO_VIDEO)) {
// 生成视频
$response = Multimodal::generateVideo('一只可爱的猫咪在花园里追逐蝴蝶', [
'duration' => 5,
'resolution' => '1080p',
'fps' => 30,
]);
// 获取视频 URL
echo $response->video();
// 获取视频时长
echo $response->videoDuration();
}
// 从图像生成视频
$response = Multimodal::imageToVideo(
imagePath: '/path/to/image.jpg',
prompt: '让这个场景动起来',
options: [
'duration' => 3,
'motion' => 'medium',
]
);
echo $response->video();
use Kode\AiAgent\Video\SeedanceService;
// 创建服务
$service = new SeedanceService('your-api-key', [
'resolution' => '720p', // 默认 720p,可选 1080p
'duration' => 10,
'aspect_ratio' => '16:9',
]);
// 文生视频
$video = $service->textToVideo('一只可爱的猫咪');
// 1080P
$video = $service->textToVideo('一只可爱的猫咪', ['resolution' => '1080p']);
// 图生视频
$video = $service->imageToVideo('/path/to/image.jpg', '让猫咪动起来');
// 多镜头视频
$video = $service->multiShot('日出风景', 3);
// 快捷函数
$video = ai_video('一只猫咪');
$video = ai_video('一只猫咪', ['resolution' => '1080p']);
// 获取平台支持的所有能力
$capabilities = Multimodal::capabilities();
foreach ($capabilities as $capability) {
echo "能力: {$capability->label()}\n";
echo "描述: {$capability->description()}\n";
}
// 检查特定能力
$canGenerateImage = Multimodal::supports(
\Kode\AiAgent\Domain\ValueObject\MultimodalCapability::TEXT_TO_IMAGE
);
// 按类别检查能力
$capability = \Kode\AiAgent\Domain\ValueObject\MultimodalCapability::TEXT_TO_IMAGE;
if ($capability->isImage()) {
echo "这是图像相关能力\n";
}
if ($capability->isVideo()) {
echo "这是视频相关能力\n";
}
if ($capability->isAvatar()) {
echo "这是数字人相关能力\n";
}
// 获取平台名称
echo Multimodal::platformName();
// 智能多模态生成(自动选择能力)
$result = ai_multimodal_generate('一只可爱的猫咪', [
'output_type' => 'image', // 或 'video', 'avatar'
]);
// 文本生成图像
$imageResponse = ai_generate_image('一只可爱的猫咪');
echo $imageResponse->image();
// 文本生成视频
$videoResponse = ai_generate_video('一只可爱的猫咪在玩耍');
echo $videoResponse->video();
// 生成数字人
$avatarResponse = ai_generate_avatar('大家好,欢迎使用!');
echo $avatarResponse->video();
// 获取数字人列表
$avatars = ai_list_avatars();
print_r($avatars);
// 获取声音列表
$voices = ai_list_voices();
print_r($voices);
// 获取任务进度
$progress = ai_get_progress('task-123');
echo $progress->status();
// 格式化文件大小
echo ai_format_file_size(1048576); // "1.00 MB"
// 验证媒体文件
if (ai_validate_media_file('/path/to/video.mp4', 'video', 104857600)) {
echo "文件有效\n";
}
use Kode\AiAgent\Support\Facade\Multimodal;
// 使用预设数字人和声音生成视频
$response = Multimodal::generateAvatar('大家好,欢迎使用数字人功能!', [
'avatar_id' => 'default-female',
'voice_id' => 'voice-female-zh',
'language' => 'zh-CN',
'resolution' => '1080p',
]);
// 获取视频 URL
echo $response->video();
// 获取下载提示
echo Multimodal::getDownloadPrompt($response);
// 上传您自己的视频作为数字人
$response = Multimodal::generateAvatarWithCustomVideo(
text: '这是使用自定义视频的数字人',
videoPath: '/path/to/your/video.mp4',
videoFileName: 'my-video.mp4',
options: [
'voice_id' => 'voice-male-zh',
'language' => 'zh-CN',
]
);
echo $response->video();
// 上传您自己的音频
$response = Multimodal::generateAvatarWithCustomAudio(
audioPath: '/path/to/your/audio.mp3',
audioFileName: 'my-audio.mp3',
options: [
'avatar_id' => 'default-female',
]
);
echo $response->video();
// 处理表单上传的视频
if (isset($_FILES['video'])) {
$response = Multimodal::generateAvatarFromRequestVideo(
text: $_POST['text'] ?? '',
fileData: $_FILES['video'],
options: [
'voice_id' => 'voice-female-zh',
]
);
// 显示结果
echo "视频生成成功!<br>";
echo "<video src='{$response->video()}' controls></video><br>";
echo Multimodal::getDownloadPrompt($response);
}
// 处理表单上传的音频
if (isset($_FILES['audio'])) {
$response = Multimodal::generateAvatarFromRequestAudio(
fileData: $_FILES['audio'],
options: [
'avatar_id' => 'default-female',
]
);
}
// 获取可用数字人列表
$avatars = Multimodal::listAvatars([
'page' => 1,
'page_size' => 20,
'category' => 'business',
'gender' => 'female',
]);
foreach ($avatars as $avatar) {
echo "ID: {$avatar['id']}, 名称: {$avatar['name']}\n";
}
// 获取可用声音列表
$voices = Multimodal::listVoices([
'page' => 1,
'page_size' => 20,
'language' => 'zh-CN',
'gender' => 'female',
]);
foreach ($voices as $voice) {
echo "ID: {$voice['id']}, 名称: {$voice['name']}\n";
}
// 异步生成数字人视频
$taskId = Multimodal::generateAsync('这是一个异步生成的视频', [
'avatar_id' => 'default-female',
'voice_id' => 'voice-female-zh',
'callback_url' => 'https://your-site.com/webhook',
]);
echo "任务已创建,任务ID: {$taskId}\n";
// 查询任务进度
$progress = Multimodal::getProgress($taskId);
echo "状态: {$progress->status}\n";
echo "进度: {$progress->progress}%\n";
echo "消息: {$progress->message}\n";
echo "耗时: " . round($progress->updatedAt - $progress->createdAt, 2) . "秒\n";
// 检查任务状态
if ($progress->isCompleted()) {
echo "任务完成!\n";
$videoUrl = $progress->data['video_url'] ?? '';
echo "视频地址: {$videoUrl}\n";
} elseif ($progress->isFailed()) {
echo "任务失败: {$progress->message}\n";
} elseif ($progress->isGenerating()) {
echo "正在生成中,请稍候...\n";
}
// 轮询直到任务完成
while (!$progress->isTerminal()) {
sleep(2);
$progress = Multimodal::getProgress($taskId);
echo "当前进度: {$progress->progress}%\n";
}
use Kode\AiAgent\Infrastructure\Persistence\LocalFileUploader;
use Kode\AiAgent\Domain\ValueObject\MediaFile;
use Kode\AiAgent\Support\Facade\Multimodal;
// 创建上传器
$uploader = new LocalFileUploader(
uploadDir: __DIR__ . '/uploads',
baseUrl: 'https://example.com/uploads'
);
// 设置到 Multimodal 门面
Multimodal::setFileUploader($uploader);
// 上传文件
$mediaFile = $uploader->upload(
filePath: '/path/to/source/video.mp4',
fileName: 'my-video.mp4',
type: MediaFile::TYPE_VIDEO
);
// 获取文件信息
echo "文件名: {$mediaFile->name}\n";
echo "路径: {$mediaFile->path}\n";
echo "大小: {$mediaFile->size} bytes\n";
echo "MIME类型: {$mediaFile->mimeType}\n";
echo "类型: {$mediaFile->type}\n";
// 检查文件类型
if ($mediaFile->isVideo()) {
echo "这是一个视频文件\n";
}
if ($mediaFile->isAudio()) {
echo "这是一个音频文件\n";
}
// 获取文件访问 URL
$url = Multimodal::getFileUrl($mediaFile);
echo "访问地址: {$url}\n";
// 检查文件是否存在
if ($uploader->exists($mediaFile)) {
echo "文件存在\n";
}
// 删除文件
$uploader->delete($mediaFile);
// 从 $_FILES 上传
if (isset($_FILES['file'])) {
$mediaFile = $uploader->uploadFromRequest(
fileData: $_FILES['file'],
type: MediaFile::TYPE_VIDEO
);
}
use Kode\AiAgent\Exception\FileUploadException;
use Kode\AiAgent\Exception\InvalidInputException;
use Kode\AiAgent\Exception\PlatformException;
try {
$response = $avatarService->generateFromText('你好', []);
} catch (InvalidInputException $e) {
echo "输入错误: " . $e->getMessage();
} catch (FileUploadException $e) {
echo "上传错误: " . $e->getMessage();
echo "错误码: " . $e->errorCode();
echo "上下文: " . json_encode($e->context());
// 处理特定错误
if ($e->errorCode() === FileUploadException::CODE_FILE_TOO_LARGE) {
echo "文件太大了,请上传较小的文件";
} elseif ($e->errorCode() === FileUploadException::CODE_INVALID_TYPE) {
echo "不支持的文件格式";
}
} catch (PlatformException $e) {
echo "平台错误: " . $e->getMessage();
}
$prompt = $avatarService->getDownloadPrompt($response);
echo $prompt;
// AvatarResponse 对象
$response = $avatarService->generateFromText('你好', []);
// 访问响应属性
echo $response->video(); // 视频 URL
echo $response->avatarId(); // 数字人 ID
echo $response->voiceId(); // 声音 ID
echo $response->text(); // 输入文本
echo $response->videoDuration(); // 视频时长(秒)
echo $response->duration(); // 生成耗时(秒)
echo $response->code(); // 状态码
echo $response->msg(); // 消息
echo $response->requestId(); // 请求 ID
echo $response->model(); // 模型名称
// 检查是否成功
if ($response->isSuccess()) {
echo "生成成功!";
}
// 转换为数组
$array = $response->toArray();
// 转换为 JSON
$json = $response->toJson();
// 直接输出视频 URL
echo $response;
use Kode\AiAgent\Domain\Model\Prompt;
foreach ($adapter->stream(new Prompt('讲一个故事')) as $chunk) {
echo $chunk;
flush();
}
use Kode\AiAgent\SSE\SSEEmitter;
$sse = new SSEEmitter();
foreach ($adapter->stream(new Prompt('讲一个故事')) as $chunk) {
$sse->message($chunk);
}
$sse->close();
use Kode\AiAgent\Application\Service\AgentService;
$service = new AgentService($adapter);
// 日志中间件
$service->pipe(function ($prompt, $next) {
$start = microtime(true);
echo "[LOG] 开始处理\n";
$response = $next($prompt);
$duration = microtime(true) - $start;
echo "[LOG] 完成,耗时: {$duration}s\n";
return $response;
});
// 缓存中间件
$service->pipe(function ($prompt, $next) use ($cache) {
$key = md5($prompt->text());
if ($cached = $cache->get($key)) {
return $cached;
}
$response = $next($prompt);
$cache->set($key, $response, 3600);
return $response;
});
$response = $service->chat('你好');
use Kode\AiAgent\Pipeline\AnnotationProcessor;
use Kode\AiAgent\Attribute\{Cache, RateLimit, Retry};
class MyService
{
#[Cache(ttl: 3600, key: 'chat_{hash}')]
#[RateLimit(requests: 60, per: 'minute')]
#[Retry(maxAttempts: 3, delay: 1000)]
public function chat(string $message): ResponseInterface
{
// 自动缓存、限流、重试
}
}
$processor = new AnnotationProcessor($cache);
$response = $processor->process($prompt, $adapter, fn($p) => $adapter->send($p));
use Kode\AiAgent\Support\Validator\InputValidator;
$validator = new InputValidator();
// 验证提示词
$prompt = $validator->validatePrompt($userInput, [
'max_length' => 100000,
'min_length' => 1,
]);
// 验证消息历史
$messages = $validator->validateMessages($messages);
// 验证工具参数
$args = $validator->validateToolCall('calculator', ['a' => 1, 'b' => 2]);
// 验证配置选项
$options = $validator->validateOptions([
'temperature' => 0.7,
'max_tokens' => 1000,
]);
// 验证 API Key 格式
$isValid = $validator->isValidApiKey('sk-xxx');
// Token 估算
$tokens = ai_token_count('你好,世界'); // 约 3 tokens
// 日志脱敏
$safe = ai_sanitize_log([
'api_key' => 'sk-xxx',
'message' => 'hello',
]);
// ['api_key' => '***REDACTED***', 'message' => 'hello']
// API Key 脱敏显示
echo ai_mask_key('sk-1234567890abcdef'); // sk-1...cdef
// 智能消息裁剪
$messages = ai_truncate_messages($messages, 4000);
// 格式化持续时间
echo ai_format_duration(0.001234); // 1.23 ms
// 格式化 Token 数量
echo ai_format_tokens(1500); // 1.5K
// 智能多模态生成(自动选择能力)
$result = ai_multimodal_generate('一只可爱的猫咪', [
'output_type' => 'image', // 或 'video', 'avatar'
]);
// 文本生成图像
$imageResponse = ai_generate_image('一只可爱的猫咪');
echo $imageResponse->image();
// 文本生成视频
$videoResponse = ai_generate_video('一只可爱的猫咪在玩耍');
echo $videoResponse->video();
// 生成数字人
$avatarResponse = ai_generate_avatar('大家好,欢迎使用!');
echo $avatarResponse->video();
// 获取数字人列表
$avatars = ai_list_avatars();
print_r($avatars);
// 获取声音列表
$voices = ai_list_voices();
print_r($voices);
// 获取任务进度
$progress = ai_get_progress('task-123');
echo $progress->status();
// 格式化文件大小
echo ai_format_file_size(1048576); // "1.00 MB"
// 验证媒体文件
if (ai_validate_media_file('/path/to/video.mp4', 'video', 104857600)) {
echo "文件有效\n";
}
use Kode\AiAgent\Exception\{
AuthenticationException,
ConfigurationException,
PlatformException,
RateLimitException,
TimeoutException,
ToolExecutionException,
ConnectionException,
InvalidResponseException
};
try {
$response = $agent->chat('你好');
} catch (AuthenticationException $e) {
echo "认证失败: " . $e->getMessage();
} catch (ConnectionException $e) {
echo "连接失败: " . $e->getMessage();
} catch (InvalidResponseException $e) {
echo "响应解析失败: " . $e->getMessage();
} catch (RateLimitException $e) {
$retryAfter = $e->context()['retry_after'] ?? 60;
echo "频率限制,{$retryAfter}秒后重试";
} catch (TimeoutException $e) {
echo "请求超时";
} catch (ToolExecutionException $e) {
echo "工具执行失败: " . $e->getMessage();
// 错误码: 4001=不存在, 4002=执行失败, 4003=参数无效, 4004=超时
} catch (PlatformException $e) {
echo "平台错误: " . $e->getMessage();
}
use Kode\AiAgent\Domain\Contract\{AdapterInterface, PromptInterface, ResponseInterface};
use Kode\AiAgent\Infrastructure\Adapter\StreamHelper;
final readonly class MyAdapter implements AdapterInterface
{
use StreamHelper;
public function __construct(
private \Kode\HttpClient\HttpClient $client,
private array $config,
) {}
#[\NoDiscard]
public function send(PromptInterface $prompt, array $options = []): ResponseInterface
{
// 实现同步请求
}
#[\NoDiscard]
public function stream(PromptInterface $prompt, array $options = []): \Generator
{
// 实现流式响应
// 可使用 $this->readLine(), $this->parseSseLine() 等方法
}
public function name(): string
{
return 'my-platform';
}
}
// 注册自定义适配器
AdapterFactory::register('my-platform', MyAdapter::class);
$config = [
'api_key' => 'sk-xxx', // API Key
'model' => 'gpt-4o', // 模型名称
'base_url' => 'https://...', // 自定义端点
'timeout' => 30, // 请求超时(秒)
'retries' => 3, // 重试次数
];
use Kode\AiAgent\Drama\DramAgentV2;
use Kode\AiAgent\Infrastructure\Adapter\AdapterFactory;
use Kode\AiAgent\Log\LogManager;
// 初始化日志
LogManager::init(['env' => 'dev']);
// 创建 DramAgentV2
$agent = new DramAgentV2(
adapter: AdapterFactory::openai('sk-xxx'),
config: [
'scenes' => 5,
'duration_per_scene' => 10,
'style' => 'cinematic',
'enable_parallel' => true,
'concurrency' => 4,
],
);
// 一键生成短剧
$result = $agent->generate('在一个阳光明媚的早晨,小明和小红相遇了...');
echo "视频地址: {$result->video}\n";
echo "总时长: {$result->duration}秒\n";
echo "场景数量: " . count($result->scenes) . "\n";
// 1. 解析剧本
$storyBoard = $agent->parseScript('剧本内容...', [
'scenes' => 8,
'style' => 'cinematic',
]);
// 2. 生成场景图像(支持并行)
$scenes = $agent->generateSceneImages($storyBoard, [
'image_size' => '1920x1080',
]);
// 3. 生成场景视频
$videos = $agent->generateSceneVideos($scenes, [
'video_resolution' => '1080p',
]);
// 4. 合成最终视频
$finalVideo = $agent->composeFinalVideo($videos, [
'transition' => 'fade',
'background_music' => '/path/to/music.mp3',
]);
// 生成包含数字人讲解的短剧
$result = $agent->generateWithAvatar(
script: '今天给大家介绍一款新产品...',
avatarOptions: [
'avatar_id' => 'default-female',
'voice_id' => 'voice-female-zh',
'language' => 'zh-CN',
],
dramaOptions: [
'scenes' => 5,
'style' => 'modern',
]
);
use Kode\AiAgent\Video\VideoComposerV3;
use Kode\AiAgent\Video\VideoClipper;
// 创建视频合成器
$composer = new VideoComposerV3(
logger: null,
concurrency: 4,
config: ['output_dir' => 'var/drama/output']
);
// 合成视频
$output = $composer->compose($sceneVideos, [
'transition' => 'fade',
'background_music' => '/path/to/music.mp3',
'music_volume' => 0.3,
]);
// 使用剪辑器
$clipper = new VideoClipper();
$clipper->split('/path/to/video.mp4', 60);
$clipper->cut('/path/to/video.mp4', 10, 30);
use Kode\AiAgent\Drama\{DramAgentV2, EnhancedScene, SceneType, TransitionType, FrameVideo};
use Kode\AiAgent\Infrastructure\Adapter\AdapterFactory;
use Kode\AiAgent\Log\LogManager;
LogManager::init(['env' => 'dev']);
$agent = new DramAgentV2(
adapter: AdapterFactory::openai('sk-xxx'),
config: [
'scenes' => 5,
'duration_per_scene' => 10,
'style' => 'cinematic',
'transition_type' => 'fade',
'transition_duration' => 1,
'background_music' => '/path/to/bgm.mp3',
'music_volume' => 0.3,
],
);
// 一键生成完整短剧(带开场、结尾、转场)
$result = $agent->generate('在一个阳光明媚的早晨...', [
'scenes' => 5,
'reference_image' => 'https://example.com/style-ref.jpg',
'opening' => [
'title' => '精彩故事即将开始',
'duration' => 5,
],
'closing' => [
'text' => '感谢观看',
'duration' => 10,
],
'background_music' => '/path/to/music.mp3',
]);
echo "输出视频: {$result->video}\n";
echo "场景数量: {$result->scenesCount()}\n";
echo "转场数量: {$result->transitionsCount()}\n";
// 设置参考图(风格引导)
$result = $agent->generate($script, [
'reference_image' => 'https://example.com/style.jpg',
'scenes' => 5,
]);
// 单个场景也可以指定参考图
$scene = new EnhancedScene(
id: 'scene-1',
order: 1,
description: '古风建筑,桃花树下',
type: SceneType::MAIN,
referenceImage: 'https://example.com/ancient-style.jpg',
referenceVideo: 'https://example.com/motion-ref.mp4',
);
use Kode\AiAgent\Drama\TransitionManager;
use Kode\AiAgent\Video\VideoComposerV3;
$composer = new VideoComposerV3();
// 添加多种转场
$composer->addTransition('scene-1', 'scene-2', TransitionType::FADE, 1);
$composer->addTransition('scene-2', 'scene-3', TransitionType::SLIDE_LEFT, 1);
$composer->addTransition('scene-3', 'scene-4', TransitionType::ZOOM_IN, 2);
// 设置开场/结尾
$composer->setOpening(FrameVideo::opening('https://cdn.example.com/intro.mp4', [
'title' => '精彩故事即将开始',
'duration' => 5,
]));
$composer->setClosing(FrameVideo::closing('https://cdn.example.com/outro.mp4', [
'ending_text' => '感谢观看',
'duration' => 10,
]));
// 合成
$result = $composer->compose();
echo $result['output'];
use Kode\AiAgent\Subtitle\{SubtitleGenerator, SubtitleFormat, SubtitleCue};
$generator = new SubtitleGenerator($adapter);
// 从视频生成字幕
$subtitles = $generator->generateFromVideo('/path/to/video.mp4', [
'language' => 'zh-CN',
'format' => SubtitleFormat::SRT,
]);
// 保存字幕
$generator->save($subtitles, '/path/to/subtitles.srt', SubtitleFormat::SRT);
// 加载字幕
$subtitles = $generator->load('/path/to/subtitles.srt');
// 格式化输出
$content = $generator->formatSubtitles($subtitles, SubtitleFormat::VTT);
use Kode\AiAgent\Voice\{VoiceoverGenerator, VoiceRole, VoiceStyle, VoiceSegment};
$generator = new VoiceoverGenerator($adapter);
// 单段配音
$audioPath = $generator->generate('欢迎观看今天的节目', [
'role' => VoiceRole::NARRATOR,
'style' => VoiceStyle::FRIENDLY,
]);
// 多段配音
$audioPaths = $generator->generateBatch([
new VoiceSegment('第一段内容', VoiceRole::MALE),
new VoiceSegment('第二段内容', VoiceRole::FEMALE),
]);
// 合并音频
$mergedAudio = $generator->mergeAudio($audioPaths);
// 为视频添加配音
$outputVideo = $generator->addToVideo('/path/to/video.mp4', $mergedAudio);
use Kode\AiAgent\Video\VideoClipper;
$clipper = new VideoClipper();
// 剪裁视频
$clipper->cut('/path/to/video.mp4', 10, 30);
// 变速播放 (2倍速)
$clipper->setSpeed('/path/to/video.mp4', 2.0);
// 旋转视频
$clipper->rotate('/path/to/video.mp4', 90);
// 分割视频
$chunks = $clipper->split('/path/to/video.mp4', 60);
// 批量操作
$clipper->execute('/path/to/video.mp4', [
new ClipOperationConfig(ClipOperation::CROP, ['width' => 1920, 'height' => 1080]),
new ClipOperationConfig(ClipOperation::SPEED, ['speed' => 1.5]),
]);
// 获取视频信息
$info = $clipper->getInfo('/path/to/video.mp4');
echo $info['duration'];
echo $info['video']['width'];
use Kode\AiAgent\Workflow\{WorkflowPresetManager, PresetType};
$manager = new WorkflowPresetManager();
// 获取预设模板
$preset = $manager->get(PresetType::SHORT_DRAMA);
// 应用模板生成短剧
$result = $agent->generate($script, $preset->config);
// 自定义模板
$custom = $manager->createCustom('my_template', [
'scenes' => 10,
'transition_type' => 'fade',
'opening' => ['title' => '我的短剧'],
]);
// 合并配置
$merged = $preset->merge(['scenes' => 8]);
use Kode\AiAgent\Log\LoggerFactory;
// 创建文件日志
$logger = LoggerFactory::create([
'channel' => 'ai-agent',
'level' => 'debug',
'path' => 'var/log/ai-agent.log',
'env' => 'dev',
]);
// 创建控制台日志
$console = LoggerFactory::console([
'level' => 'debug',
'output' => 'php://stdout',
]);
use Kode\AiAgent\Log\LogManager;
// 初始化
LogManager::init(['env' => 'dev']);
// 获取日志器
$logger = LogManager::get();
// 使用日志
LogManager::info('消息发送成功', ['message_id' => 'xxx']);
LogManager::error('请求失败', ['error' => 'timeout']);
// 获取指定频道
$videoLogger = LogManager::channel('video');
$videoLogger->info('视频处理完成');
LogManager::info('API请求', [
'api_key' => 'sk-xxx', // 自动变为 ***REDACTED***
'token' => 'Bearer xxx', // 自动变为 ***REDACTED***
'message' => 'hello', // 保持原样
]);
use Kode\AiAgent\Async\AsyncTask;
// 创建异步任务
$task = new AsyncTask(function() {
// 执行耗操作
return $result;
});
$task->start();
$result = $task->getResult();
use Kode\AiAgent\Async\FiberPool;
// 创建并发池
$pool = new FiberPool(concurrency: 10);
// 提交任务
$pool->submit(fn() => processImage($image));
// 批量执行
$pool->runAndWait();
use Kode\AiAgent\Async\ParallelExecutor;
// 创建执行器
$executor = new ParallelExecutor(
concurrency: 4,
enableParallel: true
);
// 并行执行
$results = $executor->executeBatch([
fn() => generateImage('场景1'),
fn() => generateImage('场景2'),
fn() => generateImage('场景3'),
fn() => generateImage('场景4'),
]);
// Map 操作
$images = $executor->map($prompts, fn($p) => generateImage($p));
use Kode\AiAgent\Process\ProcessPoolManager;
// 创建进程池
$pool = new ProcessPoolManager(maxProcesses: 4);
// 提交进程任务
$pool->submit('ffmpeg -i input.mp4 output.mp4');
// 等待完成
$pool->runAndWait();
use Kode\AiAgent\Process\SystemProcess;
// 创建进程
$process = new SystemProcess('ffmpeg -i input.mp4 output.mp4', [
'timeout' => 300,
]);
// 启动
$process->start();
// 等待完成
$process->wait();
// 获取输出
echo $process->getOutput();