news 2026/8/30 4:05:48

GitHub Actions 中临时数据库环境配置与常见故障排查

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
GitHub Actions 中临时数据库环境配置与常见故障排查

一个很常见的场景:本地跑得好好的,一提交代码,CI 却报数据库连接失败。很多开发者第一次把项目接入 GitHub Actions 时,都会在这类问题上卡住。原因是本地开发环境里数据库是“常驻服务”,程序启动就能连上;而 GitHub Actions 的 runner 是一台全新临时机器,任务是跑完即销毁的。你不能默认数据库“总在那里”。

这篇文章要讲清楚的核心问题是:如何在 GitHub Actions 里获得一个干净、可重复、按需销毁的数据库环境。我会从概念原理讲起,给出 MySQL、PostgreSQL、Redis 的实际接入示例,再列出常见的连接失败场景和排查思路。读完你会得到一个判断:GitHub Actions 中的数据库,不是传统意义上的“数据库运维”,而是一个临时的、隔离的、服务于代码验证的测试资源。

1. 这篇文章真正要解决的问题

GitHub Actions 里使用数据库,最常见的诉求有三个。

第一类是单元测试或集成测试需要真实数据库。很多项目在本地开发时用 SQLite 或者 Docker 容器跑数据库,只要把代码推到 GitHub 上,就需要在 CI 中还原一个可用的数据库,否则测试会跳过、报错或无法覆盖 SQL 逻辑。

第二类是数据库迁移和脚本验证。比如你写了一个schema.sql、一套 Flyway 或 Liquibase 迁移脚本,或者一个存储过程,你需要确认它在全新数据库上能正常执行。本地数据库可能已经“脏”了,数据残留会让脚本跑过头;而 CI 每次给的是一个全新库,恰好能暴露迁移脚本不幂等、依赖历史数据的问题。

第三类是验证应用与数据库的兼容性。比如 ORM 的实体映射、方言配置、字符集、事务隔离级别、数据库驱动版本是否匹配。这些问题往往在本地开发时被忽略,等上了测试环境或者生产环境才炸出来。

我的核心判断是:GitHub Actions 里的数据库,核心价值不是“部署数据库”,而是“提供可重复的数据库验证环境”。它要解决的是三个矛盾:本地数据库状态不可控、生产数据库不能被 CI 随便碰、多任务并行时互相污染。理解这一点后,你选择哪种接入方式、怎么配置服务、怎么处理数据,都会有更清晰的思路。

这篇文章适合正在搭建 CI 的前后端开发者、把老项目迁移到 GitHub Actions 的团队,以及想用自动化测试提升代码质量的个人开发者。不需要你精通数据库运维,但希望你已经了解 GitHub Actions 的基本语法,比如workflowjobstep这些概念。

2. GitHub Actions 与数据库的核心逻辑

要理解 GitHub Actions 中的数据库,先要理解它的执行模型。

一个 GitHub Actions 工作流由若干job组成,每个job在一个全新的 runner 上执行。只要用的是官方托管的 runner,这台机器在任务结束后就会被回收。所以你在 job 里安装的软件、写入的文件、启动的进程,都不会保留到下一次运行。这是它和传统 Jenkins 等常驻 CI 服务器最大的区别。

数据库也一样。如果你在 job 的 step 里手动执行apt-get install mysql-server,再启动 MySQL 服务,这个数据库只存在于当前 job 的生命周期内。下一次运行又是全新机器,一切重来。

GitHub Actions 针对这类依赖服务,提供了更优雅的写法:services服务容器。你可以在 job 定义里声明一个或多个 Docker 容器,比如 MySQL、PostgreSQL、Redis。GitHub Actions 会为这个 job 启动一个专用的虚拟网络,把服务容器和应用步骤放在同一个网络中,让它们通过服务名互相访问。

这里有一个很容易踩的坑:服务容器内部的端口,默认不会映射到 runner 宿主机的localhost。如果在 step 里写mysql -h 127.0.0.1,可能连不上,因为 3306 只在服务容器里监听。正确做法是用服务名,比如mysql这个服务名本身就代表容器的网络地址。当然,你也可以显式声明ports把端口映射到宿主机,这样就能用localhost访问了。两种写法我会在后面的示例里分别演示。

还有一个重要概念是“临时性”。GitHub Actions 的数据库每次都是全新初始化的,数据不会跨 job 保留。这看起来像个限制,但其实是优点:

  • 测试结果是可重复的,不会因为上一次运行残留数据而失败。
  • 多分支并行跑互不干扰,每个 job 有独立数据库。
  • 测试数据不会污染生产环境。

因此,你不需要编写复杂的清理逻辑,也不用担心“CI 数据库垃圾越来越多”。每次跑完,一切归零,这正是自动化测试追求的效果。

3. 环境准备与前置条件

开始实操之前,先确认几项基础条件。

第一,你需要一个 GitHub 账号和一个 Git 仓库。仓库的 Actions 功能默认是开启的,一般不需要额外配置。如果你的仓库是企业私有仓库,确认管理员没有禁用 Actions 即可。

第二,代码仓库中需要创建.github/workflows目录。GitHub 会自动识别这个目录下的 YAML 文件作为工作流配置。文件路径大概是:

.github/workflows/mysql-test.yml

第三,确认你的项目需要哪种数据库。选择标准很简单:尽量与生产环境保持一致。生产用 MySQL 8,就不要在 CI 里用 MySQL 5.7;生产用 PostgreSQL,就不要为了“省事”换成 SQLite。因为很多 SQL 特性和行为在数据库之间差异极大,名字相同的功能,实际语义可能完全不同。

第四,了解 GitHub 托管 runner 的软件环境。官方托管的ubuntu-latest镜像里预装了很多软件,但是版本会随着镜像更新而变化。不要依赖“runner 自带 MySQL”这种假设,更可靠的方式是通过services声明一个指定版本的数据库镜像,或者通过setup-*动作安装你需要的版本。本文示例中会用mysql:8.0postgres:16作为演示镜像,具体版本请以你的项目实际依赖为准。

第五,如果你需要连接 GitHub Actions 之外的资源,比如云数据库、私有制品库,要提前把访问凭证配置为仓库的Secrets。工作流中通过${{ secrets.XXX }}引用,不要把明文密码写进 YAML 文件。

4. 数据库接入 CI 的三种方式

GitHub Actions 中接入数据库,主流方式有三种。它们的适用场景、隔离性和运维成本差很多。

4.1 方式一:Service Container(推荐)

jobs.<job_id>.services下定义一个服务容器,这是最接近 GitHub Actions 设计意图的方式。写法简洁,隔离性最好,容器只服务于当前 job。

jobs: test: runs-on: ubuntu-latest services: mysql: image: mysql:8.0 env: MYSQL_ROOT_PASSWORD: root ports: - 3306:3306 steps: # 这里可以访问数据库

这种方式的好处是:数据库镜像版本可控、启动参数可控、健康检查可控。缺点是需要了解 Docker 镜像的基本配置方式,比如 MySQL 的MYSQL_ROOT_PASSWORD、PostgreSQL 的POSTGRES_PASSWORD等环境变量。

4.2 方式二:在 Runner 上直接安装

也可以在 step 里通过sudo apt-get install安装数据库,并手动启动服务。这样可以访问 runner 上完整的系统能力,和传统 CI 服务器更像。但问题也很明显:安装时间更长、版本取决于 runner 镜像源、每次都要重新安装、服务启动方式会比较绕。

一般情况下,只有找不到官方 Docker 镜像,或者需要和 runner 系统上某个组件深度集时时,才推荐这种方式。

4.3 方式三:连接外部数据库

第三种方式是在 CI 中直接连接一个外部数据库,比如云数据库、公司内网数据库或已有的测试环境。这种方式省去了安装和初始化的时间,但风险很高:CI 每次运行都会向共享数据库写入数据,可能导致数据污染;并发跑多个 job 时可能互相冲突;数据库凭证一旦进入 secrets,管理不善很容易泄露。

我的建议是:默认不要用外部数据库。如果你的场景真的需要,比如验证某个数据库驱动和云数据库的兼容性,那一定要使用独立的测试库、隔离的账号,并且保证执行的操作可回滚、可幂等。不要把生产数据库或其他团队共用的数据库作为 GitHub Actions 的目标库。

三种方式的对比:

方式隔离性启动速度版本可控性风险推荐度
Service Container推荐
Runner 直接安装部分场景
连接外部数据库不推荐

5. 完整示例:MySQL 数据库工作流

下面用一个最小但完整的示例,演示如何在 GitHub Actions 中启动 MySQL,执行 SQL 脚本,并验证数据库可用。

先创建文件.github/workflows/mysql-test.yml

name: MySQL Integration Test on: push: branches: [ main ] pull_request: jobs: mysql-test: runs-on: ubuntu-latest services: mysql: image: mysql:8.0 env: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: demo MYSQL_USER: demo MYSQL_PASSWORD: demo ports: - 3306:3306 options: >- --health-cmd="mysqladmin ping -h 127.0.0.1 -u root -proot" --health-interval=10s --health-timeout=5s --health-retries=10 steps: - name: Checkout repository uses: actions/checkout@v4 - name: Wait for MySQL to be ready run: | for i in $(seq 1 30); do if mysqladmin ping -h 127.0.0.1 -u root -proot --silent; then echo "MySQL is ready" exit 0 fi echo "Waiting for MySQL..." sleep 2 done echo "MySQL did not become ready in time" >&2 exit 1 - name: Run schema script run: mysql -h 127.0.0.1 -u demo -pdemo demo < scripts/schema.sql - name: Run smoke query run: | mysql -h 127.0.0.1 -u demo -pdemo demo -e \ "SELECT COUNT(*) AS table_count FROM information_schema.tables WHERE table_schema='demo';"

这段配置里有几个关键点。

services.mysql.env中的环境变量是 MySQL Docker 镜像初始化的依据,包括 root 密码、默认数据库、默认用户。GitHub Actions 会等容器启动后再执行下面的 steps,但“启动”不等于“数据库可接受连接”,所以需要健康检查。options中的health-cmd是 Docker 的健康检查指令,health-intervalhealth-retries控制检查频率和重试次数。

ports将容器的 3306 端口映射到 runner 宿主机,因此 step 中可以用127.0.0.1访问。如果你去掉ports配置,那么 step 里应该使用服务名mysql而不是127.0.0.1,例如:

mysql -h mysql -u demo -pdemo demo -e "SELECT 1"

这里真正容易踩坑的地方是“端口映射”和“服务名访问”的混用。很多初学者明明配置了services,却仍然在代码里写localhost,导致应用连不上。一个简单经验:配了ports,用127.0.0.1;没配ports,用服务名

scripts/schema.sql是项目中的一个 SQL 文件,比如:

-- 文件路径:scripts/schema.sql CREATE TABLE users ( id BIGINT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(64) NOT NULL UNIQUE, email VARCHAR(128) NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP );

在 CI 中,这条 SQL 会在一台全新 MySQL 实例上执行。如果脚本中存在“先删除表再建表”之类的逻辑,也要保证它在新库上能正确执行,因为新库里本来就没有表。

运行这个工作流后,你会看到控制台输出类似:

MySQL is ready smoke query +-------------+ | table_count | +-------------+ | 1 | +-------------+

table_count为 1,说明users表创建成功。如果输出 0,说明 schema 脚本没有执行或者执行到了别的数据库,需要检查-d参数指定的库名是否正确。

6. 完整示例:PostgreSQL 应用测试与迁移

接下来演示一个更贴近实际项目的场景:Node.js 应用连接 PostgreSQL,先执行迁移文件,再运行一个检查数据库状态的脚本。

先看工作流文件.github/workflows/node-postgres.yml

name: Node.js PostgreSQL Test on: push: branches: [ main ] jobs: test: runs-on: ubuntu-latest services: postgres: image: postgres:16 env: POSTGRES_USER: app POSTGRES_PASSWORD: app POSTGRES_DB: appdb ports: - 5432:5432 options: >- --health-cmd="pg_isready -U app -d appdb" --health-interval=10s --health-timeout=5s --health-retries=5 steps: - name: Checkout repository uses: actions/checkout@v4 - name: Set up Node.js uses: actions/setup-node@v4 with: node-version: '20' cache: npm - name: Install dependencies run: npm ci - name: Run database migration run: | PGPASSWORD=app psql -h 127.0.0.1 -U app -d appdb \ -f db/migrations/001_create_users.sql - name: Run database check script run: node src/check-db.js env: DATABASE_URL: postgres://app:app@127.0.0.1:5432/appdb

这里PGPASSWORD=app是给 psql 客户端提供的密码环境变量。如果你不想在命令里写密码,也可以在 step 的env中配置:

- name: Run database migration env: PGPASSWORD: app run: | psql -h 127.0.0.1 -U app -d appdb -f db/migrations/001_create_users.sql

迁移文件内容:

-- 文件路径:db/migrations/001_create_users.sql CREATE TABLE IF NOT EXISTS users ( id SERIAL PRIMARY KEY, username VARCHAR(64) NOT NULL UNIQUE, email VARCHAR(128) NOT NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() );

数据库检查脚本,文件路径src/check-db.js

const { Client } = require('pg'); async function main() { const client = new Client({ connectionString: process.env.DATABASE_URL, }); await client.connect(); const res = await client.query( 'SELECT COUNT(*) AS total FROM users' ); console.log('users count:', res.rows[0].total); await client.end(); } main().catch((err) => { console.error('database check failed:', err); process.exit(1); });

项目依赖中需要包含pg驱动,package.json中至少要有:

{ "name": "github-actions-db-demo", "version": "1.0.0", "private": true, "dependencies": { "pg": "^8.11.3" } }

这个示例的核心是:应用代码通过DATABASE_URL环境变量拿到连接串,连接的是 CI 中临时启动的 PostgreSQL。迁移脚本先创建表,应用脚本再查询表。如果迁移文件、驱动版本、SQL 语法有任何问题,这个工作流都会报错。

预期输出是:

users count: 0

如果users表不存在,node src/check-db.js会抛出类似relation "users" does not exist的错误,说明迁移没有执行成功,或者迁移执行到了错误的数据库。

6.1 顺便接入 Redis 服务

如果项目还依赖 Redis,只需要在同一个 job 的services里再加一个配置:

redis: image: redis:7-alpine ports: - 6379:6379 options: >- --health-cmd="redis-cli ping" --health-interval=10s --health-timeout=5s --health-retries=5

然后在应用测试脚本中设置:

env: REDIS_URL: redis://127.0.0.1:6379/0

需要注意的是:Redis 默认没有密码,GitHub Actions 的临时网络环境里这样使用是可行的,但在外部网络环境或自托管 runner 上,一定要开启认证并限制访问。

7. 常见问题与排查思路

GitHub Actions 里使用数据库,报错场景高度集中。我把常见问题和排查方式整理成表格,你可以直接对照定位。

问题现象可能原因排查方式解决方案
连接被拒绝,报ECONNREFUSED数据库容器尚未就绪,或端口映射不对查看 step 日志、用健康检查命令探测配置 health check,等待服务 ready 后再跑访问命令
Access denied for user数据库账号密码、主机或权限配置错误检查 services 中的 env 和连接命令中的用户统一账号密码;使用 root 账号调试;确认 MySQL 8 认证插件兼容性
PostgreSQL 报database "appdb" does not existPOSTGRES_DB未设置或连接串中的库名拼写错误查看容器环境变量和连接串显式设置POSTGRES_DB;仔细核对连接串
数据库启动很慢,应用连接超时容器健康检查未生效,或镜像冷启动较慢观察 job 启动耗时、查看容器日志增加健康检查重试次数;在应用层增加连接重试
本地能连,CI 连不上本地用了 localhost,但 CI 中的服务容器没映射端口检查 YAML 中是否有ports配置没有ports时改用服务名;有ports时才能使用127.0.0.1
某些框架报无法识别数据库类型,如couldn't deduct database type应用层的数据库方言或类型配置缺失,只给了 JDBC/连接串还不够查看应用启动日志,确认数据库类型配置项在环境变量中补充数据库类型/方言参数
SQL Server 相关报错,如wait on the database engine recovery handle failedSQL Server 容器初始化失败或系统资源不足查看容器日志、检查内存和磁盘避免在低配 runner 上跑重型 SQL Server;增加健康检查并等待恢复
Redis 可视化工具连不上 Actions 里的 Redis临时服务容器生命周期短且网络对外不可达不要在 CI 中依赖外部可视化工具CI 中直接用 redis-cli 验证;本地复现用本地 Redis
每次运行都要重新拉取镜像,耗时很长托管 runner 是全新机器,镜像无缓存查看日志中镜像拉取时间使用自托管 runner 并预热镜像;或使用更小的镜像减少拉取耗时

还有一个常见误区:很多人喜欢在 step 里写sleep 30来等数据库就绪。这其实并不可靠——机器负载高时 30 秒可能不够,空闲时又白白浪费时间。更稳妥的做法是用健康检查命令写一个轮询脚本,比如前面 MySQL 示例中那样,或者直接信任 Docker 的health-cmd配合health-retries。如果容器一直不能进入 healthy,再考虑用docker logs查看容器内部日志。

8. 安全、成本与最佳实践

8.1 安全边界

在 GitHub Actions 中使用数据库,安全的第一原则是:临时数据库永远不要和生产环境混为一谈。临时库的密码写在 YAML 里问题不大,因为整个环境是隔离的、用完即毁的;但如果是连接外部数据库,就必须把所有凭证放进secrets,并设置最小权限账号。

举几个必须遵守的底线:

  • 不要把生产数据库的连接字符串写进 workflow 文件。
  • 不要在 CI 中对共享数据库执行DROP DATABASETRUNCATE等破坏性操作。
  • 如果需要把部分真实数据导入临时库做测试,必须先脱敏,禁止直接导出生产数据到 CI 环境。
  • 使用第三方 Marketplace Action 时要评估供应链风险,尽量锁定版本或 commit SHA,不要直接引用一个不定期更新的master分支。

8.2 成本控制

GitHub Actions 的托管 runner 按分钟计费,数据库相关的镜像拉取和容器启动都会计入 job 时长。以下几点可以帮助控制成本:

  • 在允许的情况下,使用较小的数据库镜像,比如alpine变体。
  • 尽量在一个 job 中复用一个数据库服务,而不是拆成多个 job 各自启动数据库。
  • 不要为了“图方便”在 CI 中跑需要大量资源的分析型数据库任务。
  • 自托管 runner 虽然需要自己维护,但可以预拉镜像、缓存依赖,长期看更省钱。

8.3 工程实践建议

从项目工程质量角度看,数据库接入 GitHub Actions 后,有几点建议值得长期坚持。

数据库镜像版本要与生产环境一致。CI 的价值在于提前发现兼容性问题,如果 CI 用 MySQL 5.7、生产用 MySQL 8.0,那很多问题只能在更晚的阶段暴露。一致性越高,CI 越有价值。

数据库迁移脚本要保证幂等。GitHub Actions 每次使用全新数据库,看起来“幂等”不是必须的,但一旦你需要把 CI 测试数据扩展到预发环境,或者同一个 job 重试多次,非幂等脚本会立刻变成麻烦。CREATE TABLE IF NOT EXISTSINSERT ... ON CONFLICT DO NOTHING这类写法更安全。

每个 job 使用独立的数据库。如果同一个 workflow 里有多个 job 需要跑测试,不要共享同一个服务容器或外部数据库。GitHub Actions 的 job 默认互相隔离,你只需要在每个 job 下分别定义services即可。这样并行执行时不会因为数据竞争导致随机失败。

日志和错误信息要保留。当 CI 数据库报错时,第一步永远是看日志。GitHub Actions 的网页控制台中可以看到每个 step 的完整输出。把关键查询的日志打出来,把数据库容器状态打印出来,能显著缩短排错时间。

8.4 更合理的自动化策略

在项目早期就把数据库纳入 CI,是成本最低的选择。很多团队第一个 CI 只跑编译和单元测试,数据库相关的集成测试留到人工阶段,结果每次发版前都要靠人工点一遍。更好的做法是:新建仓库时就把数据库服务写进标准 workflow 模板,让每次 PR 都自动跑一轮真实数据库集成测试。

如果你用的是 ORM 或数据库迁移工具,比如 Flyway、Liquibase、Prisma、TypeORM,建议在 CI 中直接执行项目自己的迁移命令,而不是手动复制 SQL 执行。例如前一个示例中,如果项目用 TypeORM,可以直接在 step 中运行npm run typeorm:migration:run,这样验证的是开发者真实使用的迁移路径,而不是“CI 里另写的那份 SQL”。

配置数据库连接时,把连接串统一收敛到环境变量。你的应用代码不应该知道数据库是临时容器还是外部库,它只需要读取DATABASE_URL或类似配置。这样本地开发、CI、预发、生产四个环境之间切换时,改动都在配置层,代码层没有任何差异。

9. 总结与后续学习方向

GitHub Actions 与数据库的结合,本质上是把“数据库环境”从隐式依赖变成显式配置。你在 workflow 中明确声明数据库版本、初始化参数、端口和健康检查,然后让测试代码在干净环境中运行。这种模式看起来只是 CI 配置的细节,实际影响的是整个团队的发布节奏和代码质量。

本文中,我们从概念开始,了解了 Service Container 的工作方式,然后通过 MySQL、PostgreSQL 两个完整示例跑通了“启动数据库、执行迁移、验证数据”这条链路,最后整理了常见的连接失败原因和安全实践。按这个思路,你可以把任意一个依赖数据库的项目接入 GitHub Actions,并让它稳定运行。

如果你是从零开始,建议先在自己的项目中加入一个最小的 MySQL 或 PostgreSQL workflow,只跑一条 SQL 查询,确认服务能正常起停。再逐步加入迁移、种子数据、ORM 映射、事务测试。每次扩展都保持“跑得通、看得见输出、失败了能查日志”这三个标准。

后续值得深入学习的方向包括:自托管 runner 上的数据库镜像缓存、不同数据库镜像的健康检查参数差异、数据库迁移工具在 CI 中的标准接入方式,以及如何用混沌测试验证数据库高可用逻辑。当然,这些都是在基础链路稳定之后再考虑的事。建议先收藏本文,动手跑通一个示例,再回头对照自己的项目需求做调整。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/30 4:00:23

孙哥同款:从0到1搭建AI财务决策系统

孙哥有多少资产&#xff0c;我没算过&#xff0c;说有 85 亿美元。但到了他这个量级&#xff0c;碰上 5000 万美元&#xff0c;还是先让 Claude Code 把现金资产跑了一遍。算完一遍&#xff0c;又核一遍。我们没有 5000 万美元。但我们有房贷、信用卡、基金、股票、工资&#x…

作者头像 李华
网站建设 2026/8/30 3:57:42

OpenAI人事变动背后:开发者如何应对API与Agent工具链的变局

最近技术社区里最热闹的消息&#xff0c;不是某个模型又刷榜了&#xff0c;而是 OpenAI 的人事变动&#xff1a;一个月内传出 4 名高管离开&#xff0c;前 COO 离场&#xff0c;安全相关团队几乎被“掏空”。很多开发者看到这类新闻的第一反应是“和我有什么关系”&#xff0c;…

作者头像 李华
网站建设 2026/8/30 3:56:58

图解八股文面试网:用可视化方式高效备战程序员面试

1. 项目概述八股文&#xff0c;这三个字在程序员圈子里有多重的分量&#xff0c;经历过校招、社招的人心里都有数。有人骂它死板&#xff0c;有人靠它保命&#xff0c;但不可否认的是&#xff0c;它仍然是目前国内技术面试最有效的“复习框架”。我也算是靠着一份份前辈整理的题…

作者头像 李华
网站建设 2026/8/30 3:56:55

基于Qt的UDP网络通信实战:从原理到实现

简介&#xff1a;本资源是一个基于Qt框架实现UDP网络通信的完整入门级开发示例&#xff0c;面向C与Qt初学者、嵌入式/物联网通信模块开发者及跨平台实时数据传输应用学习者。项目聚焦UDP无连接通信核心流程&#xff0c;涵盖QUdpSocket绑定监听、异步收发、信号槽驱动的数据处理…

作者头像 李华
网站建设 2026/8/30 3:55:57

真实代码驱动的放置游戏: Coding-Agent 如何让游戏进度源于实际开发劳动

一个桌面放置游戏&#xff0c;进度不是靠定时器模拟&#xff0c;而是由一个真实的 coding-agent 在后台写代码、改文件、跑测试来推动。这个项目把“玩家点击——游戏产出”变成了“玩家下发任务——AI 代理真实完成——游戏结算奖励”。核心不是游戏画面多精致&#xff0c;而是…

作者头像 李华
网站建设 2026/8/30 3:52:33

Transformer核心原理与本地部署实战指南

Transformer 这个词&#xff0c;现在基本就是大模型的代名词。GPT、BERT、T5、ViT、Whisper&#xff0c;甚至图像生成里常见的 Stable Diffusion&#xff0c;核心网络都建立在 2017 年论文《Attention Is All You Need》提出的架构之上。这篇论文的第一作者是 Ashish Vaswani&a…

作者头像 李华