Coolify 中的 Laravel Actions:用 `AsAction` 统一多入口服务逻辑的工程实践
本指南以 Coolify 仓库内置的开发技能文档(.cursor/skills/laravel-actions/SKILL.md)为骨架,结合仓库内 App\Actions 命名空间下的真实实现,系统讲解基于 lorisleiva/laravel-actions 的 Action 化开发:从单一 handle(...) 业务核心出发,按需装配对象、控制器、队列任务、事件监听器、Artisan 命令五种入口,并用 AsFake 进行可预测的测试。阅读后你将掌握 Coolify 团队推荐的 Action 类结构、入口适配模式、任务重试/幂等控制以及完整的两层测试策略。
一、Coolify 为什么采用 Action 模式
Coolify 是一个自托管的 PaaS 平台,一个"用例"经常同时暴露在多个入口:
- HTTP 入口:用户在前端点击"重启数据库",走的是 Livewire/控制器;
- 队列入口:部署、代理重启等重任务需要异步执行并支持重试;
- 事件入口:状态变更(如
ApplicationStatusChanged)需要联动后续动作; - CLI 入口:运维命令与定时调度通过 Artisan 触发。
若为每个入口各自写一个控制器/Job/监听器,业务规则会被复制多份、极易漂移。lorisleiva/laravel-actions 的核心思路是:业务逻辑只写一次在 handle(...) 里,框架相关的传输/适配逻辑放在 asController、asJob、asListener、asCommand 等适配方法中,一个类即可同时作为对象、控制器、队列任务、监听器或命令使用。
Coolify 在 composer.json 中声明依赖 "lorisleiva/laravel-actions": "^2.10.2",并在 app/Actions 下按领域组织了大量 Action 类(Application、Database、Server、Docker、Service 等子目录),是该模式在大型 Laravel 项目中的典型落地。
何时该用 Action,何时该用普通 Service
| 场景 | 建议 |
|---|---|
| 同一用例需要多种入口(HTTP + 队列 + 事件 + CLI) | 用 Action |
需要一等公民级的编排与 fake 能力(dispatch、shouldRun、assertDispatched 等) |
用 Action |
| 逻辑局部、单入口、几乎不会复用 | 保持普通 Service 类 |
判定标准一句话:存在"复用压力"或"多入口压力"时才 Action 化,否则不要为用而用。
二、基础 Action 骨架与项目约定
确认包已安装
composer show lorisleiva/laravel-actions
应输出 ^2.10.2 版本信息(与 composer.json 声明一致)。
最小骨架
<?php
namespace App\Actions;
use Lorisleiva\Actions\Concerns\AsAction;
class PublishArticle
{
use AsAction;
public function handle(int $articleId): bool
{
return true;
}
}
Coolify 项目内的通用约定
- 命名空间:Action 类放在
App\Actions,除非已有领域子命名空间(如App\Actions\Database、App\Actions\Application); - 命名:使用描述性的
动词+名词(VerbNoun),例如RestartDatabase、StopApplication、CleanupPreviewDeployment、GetContainersStatus; - 职责边界:领域/业务逻辑留在
handle(...);框架与传输关注点放在适配方法(asController/asJob/asListener/asCommand); - 类型偏好:所有 Action 方法优先声明显式参数类型与返回类型;
- 文档偏好:复杂数据结构(如数组 shape)用 PHPDoc,而非内联注释。
开发流程(Quick Workflow)
composer show lorisleiva/laravel-actions确认包可用;- 新建/编辑 Action 类,使用
Lorisleiva\Actions\Concerns\AsAction; - 先实现
handle(...)(核心业务逻辑); - 仅在需要对应入口时才补适配方法:
asController(+ 路由/可调用控制器)、asJob(+ dispatch)、asListener(+ 事件监听注册)、asCommand(+ 命令签名/描述); - 为所选入口补充测试;
- 需要隔离编排时使用 Action fake(
MyAction::fake())与断言(MyAction::assertDispatched())。
三、作为普通对象运行(Object Entrypoint)
对象的三种调用方式是所有入口的地基,因为它们最终都汇聚到 handle(...)。
| 方法 | 说明 | 等价写法 |
|---|---|---|
Action::run(...) |
从容器解析并立即执行(推荐,可读性最好) | Action::make()->handle(...) |
Action::make() |
仅从容器解析实例 | app(Action::class) |
app(Action::class)->handle(...) |
手动注入调用 | —— |
Action::runIf($cond, ...) |
条件为真才执行 | if ($cond) Action::run(...) |
Action::runUnless($cond, ...) |
条件为假才执行 | if (! $cond) Action::run(...) |
依赖注入写法适合在 Service 内协作:
final class ArticleService
{
public function __construct(
private PublishArticle $publishArticle
) {}
public function publish(int $articleId): bool
{
return $this->publishArticle->handle($articleId);
}
}
仓库佐证:Action 之间的对象级编排
Coolify 的 RestartDatabase 是教科书式的对象入口编排——它接收数据库模型,先做前置检查,再用 ::run() 依次调用另外两个 Action:
public function handle(StandaloneRedis|StandalonePostgresql|StandaloneMongodb|StandaloneMysql|StandaloneMariadb|StandaloneKeydb|StandaloneDragonfly|StandaloneClickhouse $database)
{
$server = $database->destination->server;
if (! $server->isFunctional()) {
return 'Server is not functional';
}
StopDatabase::run($database, dockerCleanup: false);
return StartDatabase::run($database);
}
从中可读出几条值得借鉴的实践:
- 窄化依赖:
handle参数使用数据库模型的联合类型,而不是宽泛的对象; - 显式前置守卫:服务器不可用(
isFunctional())时直接短路返回,业务分支清晰; - 通过
::run()组合:编排层只声明"先停后启",具体逻辑下沉到StopDatabase/StartDatabase,天然形成可独立测试、可独立复用的 Action 链。
四、作为队列任务运行(Job Entrypoint)
异步执行是 Coolify 最重度的入口之一(部署、清理、代理操作都走队列)。lorisleiva/laravel-actions 通过 AsJob 把 Action 变成标准 Laravel job。
分发辅助方法
| 方法 | 语义 |
|---|---|
Action::dispatch(...) |
异步入队 |
Action::dispatchIf($cond, ...) |
条件满足才异步入队 |
Action::dispatchUnless($cond, ...) |
条件不满足才异步入队 |
Action::dispatchSync(...) |
同步执行(dispatchNow 为其别名) |
Action::dispatchAfterResponse(...) |
HTTP 响应发送后再同步执行 |
包装与链式任务
makeJob(...):创建JobDecorator包装,配合dispatch(...)辅助函数或任务链使用;makeUniqueJob(...):创建UniqueJobDecorator包装(实现ShouldBeUnique时通常自动,但可强制);withChain([...]):在当前任务成功后追加后续任务。
$chain = [
OptimizeTeamReport::makeJob($team),
SendTeamReportEmail::makeJob($team),
];
CreateNewTeamReport::withChain($chain)->dispatch($team);
等价于 Bus::chain([...]),且可用 Bus::assertChained([...]) 断言整条链:
use Illuminate\Support\Facades\Bus;
Bus::fake();
Bus::assertChained([
CreateNewTeamReport::makeJob($team),
OptimizeTeamReport::makeJob($team),
SendTeamReportEmail::makeJob($team),
]);
JobDecorator 提供的任务生命周期钩子(全部与 handle 分离)
asJob 在任务被分发时调用;若未实现则回退到 handle(...)。因此只有在需要队列专属编排时才写:
public function asJob(Team $team): void
{
$this->handle($team, true); // 队列场景强制全量报表
}
configureJob(JobDecorator $job) 可统一配置连接/队列/中间件/延迟:
public function configureJob(JobDecorator $job): void
{
$job->onConnection('my_connection')
->onQueue('my_queue')
->through(['my_middleware'])
->chain(['my_chain'])
->delay(60);
}
任务属性:重试、超时、幂等(属性写法)
| 属性 | 作用 | 示例 |
|---|---|---|
public string $jobConnection |
队列连接 | 'my_connection' |
public string $jobQueue |
队列名 | 'high' |
public int $jobTries |
最大尝试次数 | 10 |
public int $jobMaxExceptions |
失败前最大未捕获异常数 | 3 |
public int $jobBackoff |
重试延迟秒数(标量版) | 60 |
public int $jobTimeout |
超时秒数 | 60 * 30 |
public int $jobRetryUntil |
重试截止时间戳(属性版) | 1610191764 |
public string $jobUniqueId |
静态幂等键 | 'some_static_key' |
public int $jobUniqueFor |
幂等锁时长(秒) | 3600 |
public bool $jobDeleteWhenMissingModels |
模型缺失时是否直接删除任务 | true |
任务方法:重试、幂等、失败处理(方法写法)
方法写法可做动态/按参数决策,优先级高于对应属性。
public function getJobRetryUntil(): DateTime
{
return now()->addMinutes(30); // 绝对重试截止时间
}
public function getJobBackoff(): array
{
return [30, 60, 120]; // 逐次递增的延迟策略
}
其余常用钩子:
getJobDisplayName():自定义队列显示名;getJobTags(Team $team): array:返回队列标签,如['report', 'team:'.$team->id];getJobUniqueId(Team $team): int:基于参数的幂等键(如$team->id);getJobUniqueFor(Team $team): int:幂等锁时长,可按参数分支;getJobUniqueVia():幂等锁使用的缓存驱动,如Cache::driver('redis');getJobDeleteWhenMissingModels(): bool:模型缺失处理;getJobMiddleware(array $parameters): array:为队列任务追加中间件(如[new RateLimited('reports')]);jobFailed(?Throwable $e, ...$parameters): void:失败兜底,用于通知用户、上报错误、执行补偿。
仓库佐证:Coolify 用 $jobQueue 做高优队列
Coolify 的大量 Action 声明了 public string $jobQueue = 'high';,把关键操作送入专用高优队列,例如 CleanupPreviewDeployment、StopApplication、StopDatabaseProxy、GetContainersStatus 以及 app/Actions/Server 下的一批服务器运维 Action。这印证了 SKILL 中"Job Action 常定义额外队列生命周期方法与任务属性,用于重试、幂等与时机控制"的项目约定。
队列断言
use Illuminate\Support\Facades\Queue;
Queue::fake();
SendTeamReportEmail::assertPushed();
SendTeamReportEmail::assertPushed(3);
SendTeamReportEmail::assertPushed($callback); // 回调拿到 Action 实例、参数、JobDecorator、队列名
SendTeamReportEmail::assertNotPushed();
SendTeamReportEmail::assertPushedOn('reports');
SendTeamReportEmail::assertPushedOn('reports', 3, $callback);
五、作为 HTTP 控制器运行(Controller Entrypoint)
Action 可直接注册为可调用(invokable)控制器,Laravel 因此把它当作 action@__invoke 解析。
Route::post('/articles/{id}/publish', PublishArticle::class);
__invoke 由 AsController trait 提供(等价于 $action->handle(...))。若要自定义,需要把 trait 方法别名化后再覆写:
class MyAction
{
use AsAction {
__invoke as protected invokeFromLaravelActions;
}
public function __invoke()
{
// 自定义行为...
}
}
请求适配方法
asController 在 Action 作为控制器被调用时执行,负责从 Request/路由参数取数据、调用 handle(...) 并返回响应;缺省时回退到 handle(...)。
public function asController(User $user, Request $request): Response
{
$article = $this->handle(
$user,
$request->get('title'),
$request->get('body')
);
return redirect()->route('articles.show', [$article]);
}
响应可进一步按内容协商拆分:
jsonResponse($result, Request $request):请求期望 JSON 时在asController之后调用,例如返回new ArticleResource($article);htmlResponse($result, Request $request):请求期望 HTML 时调用,例如redirect()->route(...)。
控制器中间件与就地路由
public function getControllerMiddleware(): array
{
return ['auth', MyCustomMiddleware::class];
}
public static function routes(Router $router)
{
$router->get('author/{author}/articles', static::class);
}
使用就地 routes() 时,需要在某个 ServiceProvider 中注册路由发现:
use Lorisleiva\Actions\Facades\Actions;
Actions::registerRoutes();
Actions::registerRoutes('app/MyCustomActionsFolder');
Actions::registerRoutes([
'app/Authentication',
'app/Billing',
'app/TeamManagement',
]);
校验与授权钩子(ActionRequest)
控制器入口把 Laravel FormRequest 的能力搬进了 Action,全部钩子及其职责如下:
| 钩子 | 作用 |
|---|---|
prepareForValidation(ActionRequest $request) |
在授权与校验之前执行,可 $request->merge(...) 预填数据 |
authorize(ActionRequest $request): bool | Response |
授权逻辑;可返回 Response::allow() / Response::deny('...') |
rules(): array |
校验规则 |
withValidator(Validator $v, ActionRequest $request) |
通过 $validator->after(...) 追加自定义校验 |
afterValidator(Validator $v, ActionRequest $request) |
withValidator 的另一种写法 |
getValidator(Factory $f, ActionRequest $request) |
完全自定义 Validator,绕开默认 rules 管线 |
getValidationData(ActionRequest $request) |
定义参与校验的数据(默认 $request->all()) |
getValidationMessages(): array |
自定义错误消息 |
getValidationAttributes(): array |
请求字段的人性化名称 |
getValidationRedirect(UrlGenerator $url) |
校验失败时的自定义重定向 |
getValidationErrorBag(): string |
自定义错误 bag 名(默认 default) |
getValidationFailure() |
覆盖校验失败行为(如抛自定义异常) |
getAuthorizationFailure() |
覆盖授权失败行为 |
典型组合示例:
public function authorize(ActionRequest $request): bool
{
return $request->user()->role === 'author';
}
public function rules(): array
{
return [
'title' => ['required', 'min:8'],
'body' => ['required', IsValidMarkdown::class],
];
}
public function withValidator(Validator $validator, ActionRequest $request): void
{
$validator->after(function (Validator $validator) use ($request) {
if (! Hash::check($request->get('current_password'), $request->user()->password)) {
$validator->errors()->add('current_password', 'Wrong password.');
}
});
}
核心铁律:HTTP 响应/重定向/校验逻辑一律放在
asController及其响应适配方法中,严禁塞进handle(...)。
六、作为事件监听器运行(Listener Entrypoint)
Action 也可直接充当事件监听器。事件对象的数据在 asListener(Event $event) 中解包并映射成 handle(...) 参数;缺省时回退到 handle(...)(事件属性需与参数天然匹配)。
class SendOfferToNearbyDrivers
{
use AsAction;
public function handle(Address $source, Address $destination): void
{
// ...
}
public function asListener(TaxiRequested $event): void
{
$this->handle($event->source, $event->destination);
}
}
监听映射在事件服务提供者中显式注册(Coolify 的对应文件为 app/Providers/EventServiceProvider.php):
protected $listen = [
TaxiRequested::class => [
SendOfferToNearbyDrivers::class,
],
];
在 Coolify 中,这类模式与 app/Events 下的领域事件(如 ApplicationStatusChanged、ServerReachabilityChanged、ScheduledTaskDone)天然配套:事件触发、监听器 Action 接收领域对象后执行副作用。
监听器测试
use Illuminate\Support\Facades\Event;
Event::fake();
TaxiRequested::dispatch($source, $destination);
Event::assertDispatched(TaxiRequested::class);
七、作为 Artisan 命令运行(Command Entrypoint)
Action 可通过属性或方法声明命令签名/描述/帮助/隐藏,再用 asCommand 处理控制台 I/O。
use Illuminate\Console\Command;
class UpdateUserRole
{
use AsAction;
public string $commandSignature = 'users:update-role {user_id} {role}';
public function handle(User $user, string $newRole): void
{
$user->update(['role' => $newRole]);
}
public function asCommand(Command $command): void
{
$this->handle(
User::findOrFail($command->argument('user_id')),
$command->argument('role')
);
$command->info('Done!');
}
}
命令元数据(属性/方法两种写法)
| 元数据 | 属性写法 | 方法写法 |
|---|---|---|
| 签名 | public string $commandSignature |
getCommandSignature(): string(必填,若未设属性) |
| 描述 | public string $commandDescription |
getCommandDescription(): string |
| 帮助文本 | public string $commandHelp |
getCommandHelp(): string(--help 显示) |
| 是否隐藏 | public bool $commandHidden |
isCommandHidden(): bool(默认 false) |
注册与聚焦测试
在 app/Console/Kernel.php 中注册:
protected $commands = [
UpdateUserRole::class,
];
聚焦的 Artisan 测试:
$this->artisan('users:update-role 1 admin')
->expectsOutput('Done!')
->assertSuccessful();
Coolify 的 35 个控制台命令(见 app/Console/Commands)中同样存在"业务委托、命令只做 I/O"的同类分层思想,二者可以互相印证。
八、基于内部属性的 Action(WithAttributes)
当一个 Action 需要"先收集输入、后批量校验、再执行"时,可用 WithAttributes trait 把输入存为内部属性,而不是方法参数。它复用了与 AsController 完全相同的校验/授权钩子。
属性生命周期 API
| 方法 | 语义 |
|---|---|
setRawAttributes([...]) |
用给定负载整体替换全部属性 |
fill([...]) |
将给定属性合并进现有属性 |
fillFromRequest($request) |
合并请求输入 + 路由参数;键冲突时请求输入优先于路由参数 |
all() |
返回全部属性 |
only('title','body') |
仅返回指定键 |
except('body') |
排除指定键后返回 |
has('title') |
判断键是否存在 |
get('title', $default) |
取值,可带默认值 |
set('title', $value) |
设值 |
__get / __set / __isset |
支持对象属性式读写,如 $action->title |
validateAttributes() |
用 Action 属性跑授权 + 校验,返回校验后数据 |
端到端示例
class CreateArticle
{
use AsAction;
use WithAttributes;
public function rules(): array
{
return [
'title' => ['required', 'string', 'min:8'],
'body' => ['required', 'string'],
];
}
public function handle(array $attributes): Article
{
return Article::create($attributes);
}
}
$action = CreateArticle::make()->fill([
'title' => 'My first post',
'body' => 'Hello world',
]);
$validated = $action->validateAttributes();
$article = $action->handle($validated);
WithAttributes 复用 AttributeValidator,可用的钩子与控制器完全一致:prepareForValidation、authorize、rules、withValidator、afterValidator、getValidator、getValidationData、getValidationMessages、getValidationAttributes、getValidationRedirect、getValidationErrorBag、getValidationFailure、getAuthorizationFailure。
两个易错点:
fillFromRequest中请求输入永远盖过路由参数(别假设相反);使用外部输入时务必在副作用前调用validateAttributes()。
九、两层测试策略与 AsFake 动作替身
两层策略
- 业务层:直接调用
handle(...),用真实依赖 + 工厂验证业务正确性; - 入口/接线层:分别对
asController、asJob、asListener、asCommand验证编排与接线是否正确。
AsFake 全部方法(2.x)
| 方法 | 语义与适用场景 |
|---|---|
mock() |
用完整 mock 替换 Action,适合严格期望 + 参数断言,快速失败 |
partialMock() |
保留大部分真实行为、只 stub 某昂贵/内部方法 |
spy() |
事后验证("是否以 X 被调用"),无需预先穷举期望 |
shouldRun() |
mock()->shouldReceive('handle') 的简写,适合紧凑编排断言 |
shouldNotRun() |
mock()->shouldNotReceive('handle') 的简写,适合守卫分支测试 |
allowToRun() |
spy + 放行 handle,执行真实代码但允许事后断言交互 |
isFake() |
检查该类当前是否已被替换为 fake |
clearFake() |
清除 fake,防止跨测试泄漏 |
// mock:严格期望
PublishArticle::mock()
->shouldReceive('handle')
->once()
->with(42)
->andReturnTrue();
// partialMock:只挡一个内部方法
PublishArticle::partialMock()
->shouldReceive('fetchRemoteData')
->once()
->andReturn(['ok' => true]);
// spy:事后断言
$spy = PublishArticle::spy()->allows('handle')->andReturnTrue();
// 触发 Action 的代码...
$spy->shouldHaveReceived('handle')->with(42);
// shouldRun / shouldNotRun:分支可读性最佳
PublishArticle::shouldRun()->once()->with(42)->andReturnTrue();
PublishArticle::shouldNotRun();
// allowToRun:保留真实执行 + 事后断言
$spy = PublishArticle::allowToRun()->andReturnTrue();
// ...
$spy->shouldHaveReceived('handle')->once();
// isFake / clearFake:生命周期管理
expect(PublishArticle::isFake())->toBeFalse();
PublishArticle::mock();
expect(PublishArticle::isFake())->toBeTrue();
PublishArticle::clearFake();
expect(PublishArticle::isFake())->toBeFalse();
推荐测试矩阵
| 层次 | 做法 |
|---|---|
| 业务规则测试 | 直接用真实依赖/工厂调用 handle(...) |
| HTTP 接线测试 | 请求路由/控制器,用 shouldRun / shouldNotRun fake 下游 Action |
| 队列接线测试 | 以 Job 形式分发 Action,断言预期的下游 Action 调用 |
| 事件监听测试 | 分发事件,经 fake/spy 断言 Action 交互 |
| 控制台测试 | 运行 artisan 命令,断言 Action 调用与输出 |
实用默认值
- 分支测试优先
shouldRun()/shouldNotRun(); - 行为大体真实、只需调用验证时,优先
spy()/allowToRun(); - 交互契约严格、需快速失败时,优先
mock(); - 存在泄漏风险时在清理阶段
clearFake(); - 只 fake 被测边界上的 Action,不要 fake 一切,保持副作用隔离。
Pest 风格示例
it('dispatches the downstream action', function () {
SendInvoiceEmail::shouldRun()->once()->withArgs(fn (int $invoiceId) => $invoiceId > 0);
FinalizeInvoice::run(123);
});
it('does not dispatch when invoice is already sent', function () {
SendInvoiceEmail::shouldNotRun();
FinalizeInvoice::run(123, alreadySent: true);
});
先跑最小相关套件,例如:
php artisan test --compact --filter=PublishArticle
Coolify 在 tests 下配有完整的 Feature 与 Unit 测试树(tests/Feature 含 500+ 用例),任何 Action 改动都应在对应测试文件中补充或更新入口用例。
十、排障清单与常见误区
快速检查
- 类确实
use AsAction,且命名空间与 autoload 匹配; - 入口接线已注册:路由、队列 worker/配置、事件映射、命令注册;
- 方法签名与参数类型与调用方期望一致。
典型失败模式
- 控制器路由指向了错误的类;
- 队列 worker/配置不匹配;
- 监听器映射未被加载;
- 命令签名不匹配或命令未在 Console Kernel 注册。
调试流程
- 先写一个聚焦的失败测试复现问题;
- 先验证接线层,再验证领域行为;
- 需要时用 fake/spy 隔离依赖。
常见坑
- 把 HTTP 响应/重定向逻辑写进
handle(...)而不是asController(...); - 在
as*方法中复制业务规则,而不是委托给handle(...); - 依赖隐式监听接线,却未在需要处显式注册;
- 只测入口、跳过对
handle(...)的直接行为测试; - 对一次性、单上下文、无复用压力的逻辑过度 Action 化。
十一、总结
围绕 .cursor/skills/laravel-actions/SKILL.md,可以把 Coolify 的 Action 化实践概括为一条主线:handle(...) 是唯一业务真理,五个入口只是它的传输层镜像。当你在 Coolify 仓库中新增能力时,推荐的落地顺序是:先写 handle(...) 与直接测试 → 按入口需要补 asJob/asController/asListener/asCommand → 用 Queue::fake()、Event::fake()、Bus::fake() 与 AsFake 替身补齐接线测试。这样既能在多入口复用同一业务规则,又能在队列重试、幂等、超时与 HTTP 校验/授权等横切面上获得框架级的一等支持。
进一步阅读
SKILL 目录按入口/主题拆分了下钻参考,可在仓库中继续阅读:
- 对象入口:.cursor/skills/laravel-actions/references/object.md
- 控制器入口:.cursor/skills/laravel-actions/references/controller.md
- 队列入口:.cursor/skills/laravel-actions/references/job.md
- 监听器入口:.cursor/skills/laravel-actions/references/listener.md
- 命令入口:.cursor/skills/laravel-actions/references/command.md
- 属性化 Action:.cursor/skills/laravel-actions/references/with-attributes.md
- 测试与替身:.cursor/skills/laravel-actions/references/testing-fakes.md
- 排障:.cursor/skills/laravel-actions/references/troubleshooting.md
同时可直接阅读 Coolify 的 app/Actions 源码树(Database、Application、Server、Docker 等子目录)作为大型项目真实样例,观察领域 Action 是如何命名、组合与挂接队列的。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00