tmb 调用 LLM 把应用代码(Java / Python / C++ / Go / JavaScript / C# / PHP / Ruby;Kotlin & Scala 走 Java 指南)和SQL / 存储过程迁移并现代化到腾讯云:代码 → 腾讯云 SDK + TencentDB(云原生现代化),SQL → TDSQL for PostgreSQL / TDSQL-C / TencentDB for MySQL。
还能打包上云与架构改造:containerize-tencent 把应用(或拆分后的每个服务)容器化并部署到腾讯云 TKE —— TCR 镜像、12-factor 配置外置、健康探针、无状态 / 优雅关停 / 可观测性,产出全新 Dockerfile / compose / k8s 清单;monolith-to-microservices 按有界上下文把单体拆成微服务 —— 服务间 HTTP/gRPC/CKafka、各自数据、API 契约。两者均为附加 / 结构性产出(经 plan 的 creates[] 生成全新文件)。
curl -fsSL https://tmb.slowpapa.com/install.sh | sh
一条命令把一个存量项目从「别的云 / 别的数据库 / 本地中间件」迁移并现代化到腾讯云 —— 不只是搬代码,而是重平台为云原生(腾讯云 SDK + 托管服务 + 云数据库),产出可审阅的迁移计划、转换后的代码树、测试计划与执行报告。
AWS / Azure / GCP / 阿里云 SDK → 腾讯云 SDK + TencentDB;本地中间件(MySQL/Redis/Kafka/ES/Celery/MinIO/RabbitMQ/MongoDB)→ 腾讯云托管服务(再平台化);同语言版本现代化升级。
Oracle / SQL Server / MySQL → TDSQL for PostgreSQL(Oracle 兼容 / 纯 PG 模式)/ TDSQL-C / TencentDB for MySQL,含 PL/SQL → PL/pgSQL 及同方言现代化。
对标腾讯迁移工具兼容性报告:🔵 蓝不改、🟢 绿自动转、🔴 红保留原样并标 tmb-uncertain,从不强转。
转换后跑硬门禁(残留源 SDK 扫描 / sqlfluff / pglast);不过就进入工具调用 Agent 循环自修,直到验证通过。
LLM 调用之前,先算好 8 语言的依赖图(扇入/扇出)、圈复杂度、入口点、疑似死代码与重复文件;LLM 只负责定级与规划。执行后逐文件追溯「计划怎么说的、实际改了什么」——未覆盖文件数目标为 0,报告里每文件一行审计结论。所有代码分析跑在 server/tmb-ast(Go + tree-sitter,12 种语法):一次 /analyze 调用返回完整事实字典,本机部署零配置自动探测,不可达则静默回退到内置正则层(语义逐行对齐)。
containerize-tencent:容器化 + 腾讯云 TKE 部署(TCR 镜像、12-factor 配置外置、健康探针、无状态 / 优雅关停 / 可观测性),新增 Dockerfile / compose / k8s 清单;monolith-to-microservices:按有界上下文拆单体为微服务(服务间 HTTP/gRPC/CKafka、各自数据、API 契约)。均为附加 / 结构性产出,经 plan 的 creates[] 生成全新文件。
引擎、知识、配方分离 —— 加一种迁移能力只需新增一个 SKILL.md,无需改代码。
Assess → Plan → Transform → Heal → Report 流水线,所有配方共用;附加 / 结构性配方经 04b-create.md 生成全新文件。
源→目标映射表与腾讯云 SDK 用法参考,按文件语言注入;另有 container.md / microservice.md 两个跨切面 base_guide,对容器化 / 拆分配方恒定注入。
薄配方清单(target / intensity / scope / red-flag),即用户调用的单元。
一次运行的组装:
# system = prompts/00-system.md
# user = prompts/0N-<phase>.md
# {{DOMAIN_GUIDE}} <- domains/<x>.md (来自配方)
# {{FACTS}} <- 本地盘点 / 文件内容
# {{CHANGE_SPEC}} <- plan.json
四阶段流水线:
零外部依赖(纯 Python 3.8+ 标准库)。一行装好 tmb 命令:
# 一键安装(下载源码树 + 建立命令软链) curl -fsSL https://tmb.slowpapa.com/install.sh | sh # 装成正式 Python 包(可选,获得全局 tmb + tab 补全) pip install -e ~/.tmb-cli/tmb-cli
或直接克隆源码原地跑:
git clone https://github.com/awaili/tmb-cli cd tmb-cli ./bin/tmb --help
配置(指向你的 LLM 后端)——任选其一:
# A) 腾讯云 TokenHub(推荐,零本地搭建,OpenAI 兼容) tmb config use tokenhub # 广州;海外用 tokenhub-intl tmb config set api_key <TokenHub-API-Key> # B) 本地 Ollama-gateway(默认) tmb config use local tmb config set api_key <key-or-dummy> # C) 自建 TokenHub / 任意 OpenAI 兼容网关(无需改代码) tmb config set endpoint https://<your-tokenhub>/v1 # 如 https://th.quickpapa.com/v1 tmb config set api_key <your-API-Key> tmb config set model <模型 id> # 你们 TokenHub 上实际部署的模型 id # 配置存于 ~/.tmb/config.json;env 覆盖: TMB_ENDPOINT / TMB_MODEL / TMB_API_KEY
腾讯云 TokenHub 模型 id:glm-5.3 · deepseek-v4-pro · kimi-k3 · qwen3.5-plus · minimax-m3 · hy3(tmb config set model <id>)。API Key 在 TokenHub 控制台获取。
tmb 的引擎(tmb/llm.py)只按 OpenAI Chat Completions 协议说话——把 endpoint 拼上 /chat/completions,加一个 Authorization: Bearer <key> 头,没有一点腾讯官方 TokenHub 的私有逻辑。所以任何 OpenAI 兼容网关都能直接接。下面以你们自建的 th.quickpapa.com(一个 OpenAI / Claude 双协议的大模型中转站)为例,从零到跑通。
① 注册账号
② 新建 API Key
/api/keys),点 「新建密钥」,可填备注名(如 tmb-prod)。sk-…);之后列表只显示前缀。可随时吊销。③ 配置 tmb 指向这个网关
# 持久写入配置(推荐) tmb config set endpoint https://th.quickpapa.com/v1 tmb config set api_key sk-xxxxxxxx # 上一步复制的密钥 tmb config set model tokenhub-pro # 见下方模型 id;也可 glm-5.3 / deepseek-v4.1-flash / kimi-k3 / qwen3.5 / minimax-m3 等 tmb config # 确认三连 tmb models # 拉取网关可用模型,验证连通 # 临时用(环境变量,不落盘): # export TMB_ENDPOINT=https://th.quickpapa.com/v1 TMB_API_KEY=sk-… TMB_MODEL=tokenhub-pro # 团队共享:在 tmb/config.py 的 PRESETS 里加一条,之后一句切换 # tmb config use tokenhub-self # 预设只带 endpoint+model,api_key 不覆盖
快速自检(不走 tmb 也能验):curl -H "Authorization: Bearer sk-…" https://th.quickpapa.com/v1/models 能正常列出模型即连通。
④ 注意点
/v1。tmb 会自动拼 /chat/completions 和 /models,填到 /v1 为止,不要带 /chat/completions。tmb models 或上面的 curl 看可用列表(如 tokenhub-pro、glm-5.3、deepseek-v4.1-flash、kimi-k3、qwen3.5、minimax-m3、claude-sonnet-4-5、gpt-5 等)。tmb config use <name> 只改 endpoint+model,key 保留——方便在官方 / 自建 TokenHub 之间来回切而不用重输 key。run 前先 tmb plan 看一眼规模。/v1/messages + x-api-key)与 OpenAI Responses 协议(/v1/responses),Claude Code 设 ANTHROPIC_BASE_URL=https://th.quickpapa.com + ANTHROPIC_API_KEY 即可。tmb 只用 OpenAI 协议那条路。creates[] / services[]、Agent 自愈循环,对所有后端完全相同。tmb models # 列出网关模型 tmb skills list # 列出已装配方 tmb skills show <id> # 查看配方清单 tmb assess [PATH] -r <skill> [-o DIR] # 产出 overview.md tmb plan [PATH] -r <skill> [-o DIR] # plan.json + plan.md + test-plan.md tmb transform [PATH] [--plan F|--job TS] [--apply] [--heal-rounds N] [--build CMD] [--test CMD] tmb run [PATH] -r <skill> [flags] # assess + plan + transform + report 一把梭 tmb resume [--job TS] [--max-steps N] # 续跑 Agent 修复循环 tmb report [--job TS] # (重)生成执行报告 tmb restore [--job TS] # 从备份回滚源码(--apply 任务) tmb config get|set|use <k> <v> # endpoint / model / api_key;use local|tokenhub|tokenhub-intl 切后端
-r/--recipe 接配方 id(如 aws-sdk-to-tencent、containerize-tencent、monolith-to-microservices);transform/run 标志:--apply(写回源码,默认提示)、--yes(跳过提示)、--model(覆盖模型)、--heal-rounds N、--agent(工具调用 Agent 修复循环)、--max-steps N、--build CMD、--test CMD、--jobs N(按文件并行)、--mem-threshold / --mem-keep(Agent 记忆压缩)。
容器化 / 拆分(附加 / 结构性配方)—— 用法相同,但 out/ 会多出源码里没有的全新 creates[] 文件:
# 容器化一个服务 + 产出 TKE 清单(Dockerfile / docker-compose / k8s/*.yaml) tmb run ./my-svc -r containerize-tencent tmb plan ./my-svc -r containerize-tencent # 只出计划,先看 creates[] tmb transform ./my-svc --apply --yes # 把 Dockerfile + k8s/ 写进源码 # 拆单体为微服务(services[] + 每服务模块 + 契约) tmb run ./monolith -r monolith-to-microservices # 配对:先拆,再各自容器化 tmb run ./monolith -r monolith-to-microservices --apply --yes tmb run ./monolith/services/order-svc -r containerize-tencent
这两个配方的 --build / --test 校验新构件(非 mvn / sqlfluff):--build "docker build -t verify ."、--test "kubectl apply --dry-run=client -f k8s/"。结构门禁:容器化查 Dockerfile + Deployment+Service + TCR 镜像 + 无字面密钥;微服务查 ≥2 自包含服务 + 跨服务无 in-process import。
每次调用 = 共享 system(00-system.md)+ 一个阶段 user prompt。Transform 有两个 user 模板:
04-transform.md → items[] 改写【已有】源文件(带 {{FILE_CONTENT}} 原文,原地改)
04b-create.md → creates[] 生成【全新】文件(无原文,凭 CHANGE_SPEC 产出)
例 1 — 容器化生成 Dockerfile(containerize-tencent · kind=containerfile)
File: Dockerfile Kind: containerfile CHANGE_SPEC: Multi-stage: builder FROM maven:3.9-eclipse-temurin-21 mvn -q -o package -DskipTests; runtime FROM eclipse-temurin:21-jre COPY target/*.jar; ENTRYPOINT java -jar; EXPOSE 8080; HEALTHCHECK /actuator/health; USER 1000 GLOBAL_CONVENTIONS: 镜像→TCR; 凭据仅 Secret/env 不得字面量; /actuator/health 探针; 12-factor(PORT/DB_URL 外置) DOMAIN_GUIDE: domains/container.md(base only) → 输出完整 Dockerfile,无注释 / 围栏
例 2 — 微服务拆分生成 OpenAPI 契约(monolith-to-microservices · kind=contract)
File: contracts/order-svc.openapi.yaml Kind: contract
CHANGE_SPEC: OpenAPI 3: POST /orders, GET /orders/{id};
schemas; auth; idempotency-key header
GLOBAL_CONVENTIONS: 每服务自包含; 跨服务不得 in-process import;
各自 DB/schema; 共享代码放 common-lib
DOMAIN_GUIDE: domains/microservice.md(base only)
对照 —— 改写已有 OrderService.java(billingService.charge() → 对 billing-svc /charge 的 HTTP 调用)走 04-transform.md,额外注入 {{FILE_CONTENT}} 原文,原地改而非凭空生成。
每个配方是一个 skills/<id>/SKILL.md 清单。新增迁移能力只需 mkdir skills/<new-id>,不改代码。其中 containerize-tencent 与 monolith-to-microservices 为附加 / 结构性配方,经 plan 的 creates[] 产出全新 Dockerfile / compose / k8s 清单与拆分后的服务模块。
| 配方 id | 语言 | 迁移目标 |
|---|---|---|
aws-sdk-to-tencent | java · python · cpp · go · javascript · csharp · php · ruby | 腾讯云 SDK + TencentDB |
azure-sdk-to-tencent | java · python · cpp · go · javascript · csharp · php · ruby | 腾讯云 SDK + TencentDB |
gcp-sdk-to-tencent | java · python · cpp · go · javascript · csharp · php · ruby | 腾讯云 SDK + TencentDB |
aliyun-sdk-to-tencent | java · python · cpp · go · javascript · csharp · php · ruby | 腾讯云 SDK + TencentDB |
onprem-to-tencent | java · python · cpp · go · javascript · csharp · php · ruby | 腾讯云托管服务 + TencentDB |
lang-modernize | java · python · cpp · go · javascript · csharp · php · ruby | 同语言升级到新版本 |
oracle-to-tdsql-pg-ora | sql | TDSQL for PostgreSQL(Oracle 兼容模式) |
oracle-to-tdsql-pg-pure | sql | TDSQL for PostgreSQL(PG 模式)/ 社区 PG |
oracle-to-tdsql-c | sql | TDSQL-C PostgreSQL |
sqlserver-to-tdsql-pg | sql | TDSQL for PostgreSQL |
mysql-to-tdsql-pg | sql | TDSQL for PostgreSQL |
mysql-to-tencentdb-mysql | sql | TencentDB for MySQL / TDSQL for MySQL |
sql-modernize-tencent | sql | 同 TencentDB 方言现代化 |
containerize-tencent | java · python · cpp · go · javascript · csharp · php · ruby | 腾讯云 TKE + TCR(容器化部署,12-factor) |
monolith-to-microservices | java · python · cpp · go · javascript · csharp · php · ruby | 腾讯云 TKE 微服务(按有界上下文拆分) |
真实上云很少照搬配方名。下面用真实夹具(test/ 下可直接跑)演示:现状代码 → 该用哪个配方 → 具体命令 → 输出长什么样。
| 你的情况 | 配方 |
|---|---|
| 应用代码用 AWS / Azure / GCP / 阿里云 SDK | aws-sdk-to-tencent / azure-… / gcp-… / aliyun-… |
| 自建中间件(MySQL/Redis/Kafka/ES/MinIO/MQ) | onprem-to-tencent |
| Oracle / SQL Server / MySQL 存储过程 | oracle-to-tdsql-pg-ora\|-pure\|-c / sqlserver-to-tdsql-pg / mysql-to-tdsql-pg\|-tencentdb-mysql |
| 同方言 SQL 现代化 | sql-modernize-tencent |
| 语言版本升级(不上云) | lang-modernize |
| 打包成容器上 TKE | containerize-tencent |
| 单体拆成微服务 | monolith-to-microservices |
# 现状 test/py-aws-multi/app.py
import boto3
s3 = boto3.client("s3", region_name="us-east-1")
sqs = boto3.client("sqs", region_name="us-east-1")
dyn = boto3.client("dynamodb", region_name="us-east-1")
源云=AWS、应用代码 → aws-sdk-to-tencent。S3→COS、SQS→CKafka/CMQ、DynamoDB→TencentDB。DB 是 NoSQL,无 SQL 方言迁移 —— 一个配方搞定。门禁:残留 boto3=0。
tmb run ./py-aws-multi -r aws-sdk-to-tencent
# 现状 test/java-aws-s3/S3Uploader.java
static AmazonS3 s3 = AmazonS3ClientBuilder.standard().withRegion("us-east-1").build();
Class.forName("oracle.jdbc.OracleDriver");
DriverManager.getConnection("jdbc:oracle:thin:@dbhost:1521:ORCL", "u", "p");
要点:应用 SDK 迁移(S3→COS)用 aws-sdk-to-tencent;但 Oracle 库是 SQL 迁移,不在此配方范围。嵌入式 SQL 在应用内转;存储过程 / 包要单独跑 oracle-to-tdsql-pg-ora。DB 不同方言就要拆成「应用 + SQL」两步。
tmb run ./java-aws-s3 -r aws-sdk-to-tencent # 应用 + 嵌入式 SQL tmb run ./db -r oracle-to-tdsql-pg-ora # PL/SQL 包
# 现状 test/onprem-py-app/app.py
DB_URL = "mysql+pymysql://app:secret@127.0.0.1:3306/orders"
r = redis.Redis(host="localhost", port=6379, db=0)
producer = KafkaProducer(bootstrap_servers="localhost:9092")
minio_client = Minio("localhost:9000", access_key="miniokey", secret_key="miniosecret")
celery_app = Celery("worker", broker="redis://localhost:6379/1", ...)
自建中间件 → 托管 → onprem-to-tencent。MySQL→TencentDB for MySQL、Redis→TencentDB for Redis、Kafka→CKafka、ES→腾讯云 ES、MinIO→COS、Celery 保留(broker→Redis/CKafka)。多数数据面库不变,只换连接配置;MinIO→COS 换 SDK。门禁:不得残留 127.0.0.1 / localhost 自建端点。
tmb run ./onprem-py-app -r onprem-to-tencent
同是 Oracle,目标不同配方不同:TDSQL PG Oracle 兼容模式 → oracle-to-tdsql-pg-ora(轻改,大量 PL/SQL 保持);纯 PG / 社区 PG → oracle-to-tdsql-pg-pure(严格 PL/pgSQL);TDSQL-C → oracle-to-tdsql-c。UTL_FILE 等不可移植 → 红,保留 + tmb-uncertain。门禁:sqlfluff + pglast。
tmb run ./db -r oracle-to-tdsql-pg-ora
# 现状 test/java-springboot/application.yml
server:
port: 8080
spring:
datasource:
url: jdbc:postgresql://localhost:5432/orders
password: changeme
这是打包,不是 SDK 迁移 → containerize-tencent。产出全新 creates[]:多阶段 Dockerfile、k8s/deployment.yaml + service.yaml、Secret;并把配置外置(port→${PORT:8080}、url→${DB_URL}、password→${DB_PASS})。镜像→TCR,探针打 /actuator/health。--build/--test 校验新构件。
tmb run ./java-springboot -r containerize-tencent \ --build "docker build -t v ." --test "kubectl apply --dry-run=client -f k8s/"
# 现状 test/java-monolith/OrderService.java —— 进程内跨边界调用
private final BillingService billingService = new BillingService();
private final InventoryService inventoryService = new InventoryService();
public String placeOrder(String order) {
inventoryService.check(order);
billingService.charge(order);
return "ok";
}
结构改造 → monolith-to-microservices(按 orders/billing/inventory 有界上下文拆)。creates[]:每服务 pom+入口、OpenAPI 契约、common-lib;items[]:billingService.charge() → 对 billing-svc /charge 的 HTTP 调用(超时 / 重试 / 幂等);services[] 是分解图。跨上下文 @Transactional → 红(saga/outbox)。拆完每个服务再跑 containerize-tencent。
tmb run ./java-monolith -r monolith-to-microservices --apply --yes tmb run ./java-monolith/services/order-svc -r containerize-tencent
要三步,每步吃上一步输出:① lang-modernize(javax→jakarta,8→21)② aws-sdk-to-tencent(SDK 迁云)③ containerize-tencent(打包上 TKE)。
tmb run ./app -r lang-modernize --apply --yes # 1. 语言 tmb run ./app -r aws-sdk-to-tencent --apply --yes # 2. 云 tmb run ./app -r containerize-tencent --apply --yes # 3. 打包
对标腾讯迁移工具兼容性报告 —— 不强转,把该人工处理的留给人工。
完全兼容,无需改动。
由 tmb 自动转换。
人工处理:原样保留 + tmb-uncertain 标注,从不强转。
--agent 把修复阶段变成真正的工具调用 Agent 循环:模型拿到 read_file / write_file / list_dir / grep / run_build / run_verify / read_plan / spawn_subagent 等工具,自驱 观察→行动→观察,直到 run_verify(及 run_build / run_test)通过才停。
模型可调 spawn_subagent(task) 生成深度受限(1 层)的子 Agent 跑独立子任务,返回摘要给父 Agent。
--jobs N 按文件并行转换,N 个 worker 各自独立 LLM 调用写到不同路径。
超 --mem-threshold 时把较早的完整轮次 LLM 摘要成一个紧凑块;系统提示与目标永不压缩。transcript 落 agent_transcript.json,tmb resume 从压缩态续跑。
循环受 --max-steps 封顶,transcript 持久化,tmb resume --job <ts> 续跑暂停/触顶的任务。
转换默认落在 .tmb/out/<job>/out/(完整镜像);--apply 才写回源码,且先备份到 .tmb/backup/<ts>/。tmb restore 一键回滚。
--agent 下 write_file 只写 out/,从不直接写源码;run_build 在 out/ 内执行,跑前请审命令。
残留源 SDK 扫描是硬门禁:代码输出不得含 boto3/aws-sdk/oss2/aliyun-sdk/google-cloud/azure-sdk/oracle.jdbc 等;SQL 跑 sqlfluff/pglast/psql 校验。门禁不过 CLI 退出码 2。
两层、都可离线跑。
python3 -m pytest # 396/396 单测,无需网关 python3 test/run_tests.py # 30/30 真网关 E2E demo
bin/tmb 跑完整 run(assess→plan→transform→verify→report→restore),test_creates.py(附加 creates[] 流水线、base_guide 注入、容器化 / 微服务门禁)、test_facts.py(8 语言确定性事实层 + 符号级复杂度热点)、test_trace.py(追溯矩阵)、test_astsvc.py(服务端分析客户端、端点解析含本机自动探测、符号透传、整体回退契约)、test_parity.py(对等性守卫:本机服务在线时,断言服务端与内置正则两层产出语义一致的事实字典——静默回退永不改变结果)。全部 LLM 调用被 mock。Go 服务自带 go test ./... 提取断言。java-springboot → containerize-tencent、java-monolith → monolith-to-microservices)。真网关并发跑,断言交付物、计划配方、门禁、源标记消失 / 目标标记出现。