# AGENTS.md 给接手这个项目的 AI Agent / 开发者看的说明。**要做任何事之前先读完本文件。** --- ## 1. 这是什么 `tripocli` —— 把 Tripo AI 的 3D 生成与加工能力封装成命令行工具,供 Agent 与开发者调用。 纯 Python 3 标准库,**零第三方依赖**。 覆盖能力:文生 3D、图生 3D、多视图、批量生成,以及重拓扑、绑定、动画、智能分割、纹理、PBR、 智能 UV、部件补全、格式导出与下载。 ## 2. 代码结构(重要约定) **一个功能 = 一个文件。** 新增能力不要往单个大文件里塞。 ``` tripocli.py # 入口薄壳(只有十几行) tripo/ ├── cli.py # argparse 装配 + 分发 + 错误处理 ├── client.py # HTTP:请求头、重试、凭据解析、轮询、下载 ├── auth.py # cookie → JWT(纯 HTTP) ├── accounts.py # 多账号凭据存储 ├── config.py # 全局设置(API 地址 / device id) ├── s3.py # SigV4 直传 ├── server.py + web/ # tripocli serve(本地账号管理页) ├── update.py # 自我更新(tripocli update) └── features/ # 每个功能一个模块 ``` 新增一个命令的标准做法: 1. 在 `tripo/features/` 下新建 `xxx.py`; 2. 模块里定义 `NAME`、`HELP`、`add_arguments(parser)`、`run(ctx)`(多子命令的模块改用 `register(subparsers)`); 3. 在 `tripo/features/__init__.py` 的 import 和 `MODULES` 列表里各加一行; 4. 用真实请求验证后再交付。 ## 3. 安装 ```bash cd <项目目录> pip install . # 装成全局命令 pyenv rehash # ← pyenv 用户必须执行,否则报 tripocli: command not found ``` 不想安装也可以直接用项目里的入口:`<项目目录>/tripocli --version`。 > 若 `pip install .` 报 `invalid command 'bdist_wheel'`,说明环境缺打包后端,执行 `pip install wheel` 后重试。 > (`tripocli` 本体零依赖,这只影响安装过程。) ## 4. 更新(本节是「更新怎么做」的唯一依据) **首选:一条命令。** ```bash tripocli update # 从记住的源码目录重装全局 CLI(pyenv 会自动 rehash) tripocli update --check # 只看状态:源码目录 / 已安装版本 / 是否需要更新 tripocli update --dry-run # 只打印将执行的命令 tripocli update --from <项目目录> # 首次指定源码目录(会记住,之后不用再传) ``` 改完源码后跑一次 `tripocli update`,全局命令就更新到最新。 源码目录首次自动识别(运行 `tripocli` 时所处的项目目录),并记录在 `~/.tripo/config.json` 的 `install_source`。 ### 4.1 手工方式(等价,update 不可用时) ```bash cd <项目目录> git pull # 若有 git 仓库 pip install . && pyenv rehash # 重新安装 ``` 只拿到新目录/压缩包(未用 git)时:用新目录**整体覆盖**旧目录,再执行上面的安装命令; 如果一直是「直接用项目里的入口」的方式,覆盖完即生效,无需安装。 ### 4.2 更新后必须做的验证 ```bash tripocli --version # 版本号是否为预期 tripocli account list # 凭据是否仍在(在 ~/.tripo/accounts.json,更新代码不会动它) tripocli balance # 能否正常调通接口 ``` ### 4.3 两个容易踩的坑 - **副本优先级**:在项目目录内执行 `tripocli` 会优先用**项目里的代码**(cwd 优先); 在其它目录执行才用 `pip` 装的那份。所以「更新后行为没变」多半是在项目目录里跑到了旧副本,或没重新安装。 - **pyenv rehash**:装/卸命令后不 `rehash`,pyenv 的 shim 找不到新命令(`tripocli update` 会自动做)。 ## 5. 凭据 凭据在 `~/.tripo/accounts.json`(权限 600),与代码分离,**更新代码不会丢失**。 只需一次浏览器 cookie,CLI 自行续期 15 分钟的 JWT(cookie 约 30 天有效)。 ```bash tripocli account add --cookie "ory_kratos_session=..." tripocli account list tripocli serve --open # 网页版账号管理 ``` 多账号时默认会在「当前账号额度不足」时自动切换下一个账号重试;如需关闭,传 `--no-fallback`(或设 `TRIPO_AUTO_FALLBACK=0`)。 **永远不要把 cookie / token 写进代码、文档或提交记录。** ## 6. 验证改动(真实调用,不要只做静态检查) ```bash tripocli --json balance # 最快连通性检查 tripocli --json text -p "a wooden crate" --smart-mesh --wait -o /tmp/t.glb tripocli --json project # 拿 model_url ``` 注意:后处理算子(remesh/rig/pbr/texture/uv…)会为项目新建 operator, **同一项目必须等上一个算子 `success`** 才能提交下一个,否则报 `2021`。 ## 7. 构建游戏场景与 3D 应用的性能与工程红线(必读) 当用户要求用 `tripocli` 生成资产并搭建游戏场景(Web Three.js / Godot / Unity)时,必须遵守以下已验证规范: 1. **严禁把未减面的 200 万面默认高模直接批量塞进场景**: - 生成场景建筑/树木/道具时优先加 `--face-limit 15000` 或 `--smart-mesh` 从源头控制面数; - 对已下载的高模做本地减面时,**不要只跑 `gltf-transform optimize`**(其默认 `--simplify-error 0.0001` 过严,几乎不减面,只做 Draco 压缩,解压后显存里仍是七八十万面/个);必须显式执行 `npx gltf-transform simplify in.glb tmp.glb --ratio 0.025 --error 0.06 && npx gltf-transform draco tmp.glb out.glb`(角色蒙皮网格用 `--ratio 0.12 --error 0.02`)。 2. **严禁在 `normalize` 后用 `position.set(x, 0, z)` 覆盖 `position.y`**: - Tripo 模型原点在几何中心,必须用外层 `Group` 包装后再设 `(x, groundY, z)`,否则所有建筑和树木会半截埋入地下。 3. **骨骼动画**:`animate` 产出的 GLB 在 `project.operator.retarget[]` 中,且只含骨骼轨道不含 Mesh,需与 `rig` 本体模型合并播放;测量 `SkinnedMesh` 高度时必须用 `isBone` 的世界坐标而非默认 `Box3.setFromObject`。 4. **文生图额度保护**:`tripocli img` 默认 `--amount 1`(一次一张),除非用户明确要求多张,否则不要调高。 ## 8. 建议的下一步(尚未做,需项目所有者决定) 1. `git init` + 首次提交,推到私有仓库 → 更新变成 `git pull`; 2. 需要对外分发时发布到 PyPI → 别人可用 `pip install -U tripocli`(当前该名字在 PyPI 上未被占用); 3. 接口契约见 `TRIPO_API_SPEC.md`;命令说明见 `README.md`。