本文目录导读:

这是一个关于在PHP项目中实现“模型选择”的常见问题,这里的“模型”通常指机器学习模型(如预测、分类)或AI大模型(如OpenAI、Claude等),为了实现模型选择,你需要考虑调用方式、切换逻辑以及性能与成本平衡。
下面为你提供几种主流实现方案,涵盖从简单到复杂的场景:
基于配置文件的硬编码切换(最简单,适合小型项目)
通过修改配置文件,在代码中判断当前使用的模型。
定义配置(config/model.php)
<?php
return [
'default' => env('MODEL_PROVIDER', 'openai'), // 或 'gemini', 'local'
'providers' => [
'openai' => [
'model' => 'gpt-4o',
'api_key' => env('OPENAI_API_KEY'),
'temperature' => 0.7,
],
'gemini' => [
'model' => 'gemini-1.5-flash',
'api_key' => env('GEMINI_API_KEY'),
],
'local_llm' => [
'model' => 'llama3',
'endpoint' => 'http://localhost:11434/api/generate', // Ollama
],
],
];
创建模型分发器类
<?php
namespace App\Services;
class ModelRouter
{
protected $config;
public function __construct(array $config)
{
$this->config = $config;
}
public function chat(string $prompt): string
{
$provider = $this->config['default'];
$providerConfig = $this->config['providers'][$provider];
return match ($provider) {
'openai' => $this->callOpenAI($prompt, $providerConfig),
'gemini' => $this->callGemini($prompt, $providerConfig),
'local_llm' => $this->callLocalLlama($prompt, $providerConfig),
default => throw new \InvalidArgumentException("未知模型提供商"),
};
}
protected function callOpenAI(string $prompt, array $config): string
{
// 使用 GuzzleHttp 或 cURL 调用 OpenAI API
$response = \Http::withToken($config['api_key'])
->post('https://api.openai.com/v1/chat/completions', [
'model' => $config['model'],
'messages' => [['role' => 'user', 'content' => $prompt]],
]);
return $response->json()['choices'][0]['message']['content'];
}
// ... 其他模型调用方法
}
优点:实现简单,直接生效。
缺点:切换模型依赖修改配置文件,不适合生产动态切换。
基于策略模式 + 工厂模式(推荐,中大型项目)
这是最优雅的面向对象解决方案,解耦模型逻辑,易于扩展。
定义模型接口
<?php
namespace App\Contracts;
interface AIModelInterface
{
public function generate(string $prompt, array $params = []): string;
public function supports(array $task): bool; // 可选:判断模型是否符合任务
}
实现具体模型
<?php
namespace App\Models\AI;
class OpenAIModel implements AIModelInterface
{
public function generate(string $prompt, array $params = []): string
{
$model = $params['model'] ?? 'gpt-4o-mini';
// OpenAI API 调用逻辑...
return response();
}
public function supports(array $task): bool
{
return $task['type'] === 'chat' || $task['complexity'] < 7;
}
}
class LocalLlamaModel implements AIModelInterface
{
public function generate(string $prompt, array $params = []): string
{
// 调用本地 Ollama 服务...
return response();
}
public function supports(array $task): bool
{
return $task['type'] === 'code' || $task['complexity'] <= 3;
}
}
创建工厂类(模型选择器)
<?php
namespace App\Services;
use App\Contracts\AIModelInterface;
class ModelFactory
{
protected array $models = [];
// 注册模型(通过服务容器绑定,或手动注册)
public function register(string $name, AIModelInterface $model): void
{
$this->models[$name] = $model;
}
// 根据任务选择模型
public function selectForTask(array $task): AIModelInterface
{
// 1. 精确匹配:task 里指定了模型名
if (isset($task['model']) && isset($this->models[$task['model']])) {
return $this->models[$task['model']];
}
// 2. 智能选择:基于能力、成本、性能评分
$bestModel = null;
$bestScore = -1;
foreach ($this->models as $name => $model) {
if ($model->supports($task)) {
$score = $this->calculateScore($name, $task); // 根据规则算分(成本、速度等)
if ($score > $bestScore) {
$bestScore = $score;
$bestModel = $model;
}
}
}
if ($bestModel === null) {
throw new \RuntimeException("没有合适的模型处理此任务");
}
return $bestModel;
}
protected function calculateScore(string $name, array $task): int
{
// 自定义评分逻辑:简单任务用低成本模型,复杂任务用高智能模型
return match ($name) {
'gpt-4o' => $task['complexity'] > 5 ? 100 : 10,
'llama3' => $task['complexity'] < 4 ? 90 : 30,
default => 50,
};
}
// 获取当前所有模型列表(用于管理后台)
public function getAvailableModels(): array
{
return array_keys($this->models);
}
}
在 Laravel 等服务容器中注册
// AppServiceProvider.php
public function register()
{
$this->app->singleton(ModelFactory::class, function ($app) {
$factory = new ModelFactory();
$factory->register('gpt-4o', new OpenAIModel());
$factory->register('llama3', new LocalLlamaModel());
// 未来添加 Claude、Gemini 只需增加一行
return $factory;
});
}
使用示例:
$factory = app(ModelFactory::class);
$model = $factory->selectForTask(['type' => 'code', 'complexity' => 4]);
$result = $model->generate("写一个PHP排序算法");
数据库驱动的动态选择(适合SaaS后台管理)
将模型配置存储在数据库中,管理员可在后台动态添加、启用/禁用模型。
数据库表设计:
CREATE TABLE ai_models (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL UNIQUE,
provider VARCHAR(50), -- openai, gemini, local
api_key_encrypted TEXT,
model_name VARCHAR(100), -- gpt-4o, gemini-1.5-pro
cost_per_token DECIMAL(10,8),
speed_score INT, -- 1-10
intelligence_score INT, -- 1-10
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP
);
CREATE TABLE task_model_rules (
id INT PRIMARY KEY AUTO_INCREMENT,
task_type VARCHAR(50), -- 'chat', 'code', 'embedding'
complexity_range JSON, -- {"min": 1, "max": 5}
priority INT DEFAULT 0,
model_id INT FOREIGN KEY REFERENCES ai_models(id)
);
选择逻辑:
public function selectModel(string $taskType, int $complexity): string
{
$model = DB::table('ai_models')
->join('task_model_rules', 'ai_models.id', '=', 'task_model_rules.model_id')
->where('ai_models.is_active', true)
->where('task_model_rules.task_type', $taskType)
->whereRaw('JSON_UNQUOTE(JSON_EXTRACT(complexity_range, "$.min")) <= ?', [$complexity])
->whereRaw('JSON_UNQUOTE(JSON_EXTRACT(complexity_range, "$.max")) >= ?', [$complexity])
->orderBy('task_model_rules.priority')
->first();
return $model ? $model->name : 'default_fallback_model';
}
高级优化建议
- 缓存模型选择结果:如果同一用户同一任务反复调用,缓存选择的模型ID,避免重复计算。
- 降级与熔断:如果主模型(如GPT-4)超时或报错,自动切换到备用模型(如GPT-3.5或本地模型)。
try { return $selectedModel->generate($prompt); } catch (TimeoutException $e) { return $this->fallbackModel->generate($prompt); } - 成本追踪:记录每次调用使用了哪个模型、耗费了多少token,方便出账单和优化。
- A/B测试:对不同用户组使用不同模型,观察效果差异。
| 方案 | 适用场景 | 复杂度 | 灵活性 |
|---|---|---|---|
| 配置文件切换 | 个人项目、Demo | 低 | |
| 策略模式+工厂 | 企业级应用、中大型项目 | 高 | |
| 数据库驱动 | SaaS平台、多租户系统 | 非常高 |
推荐你使用方案二(策略模式 + 工厂模式),它兼顾了可维护性、扩展性和清晰的代码结构,如果你需要给用户提供后台管理界面来选择模型,则结合方案三。