news 2026/9/18 23:53:24

将 1.5B CAD 生成放进 CI,TaoToken 作为请求出口

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
将 1.5B CAD 生成放进 CI,TaoToken 作为请求出口

1. 把 CAD 参数级生成放进 CI,先解决请求出口和 Key 注入

如果你正在把 CAD 参数级生成塞进 GitHub Actions 或 GitLab CI,大概率会遇到几个很具体的问题:脚本在本地能跑,到了 Runner 里却因为请求出口不稳定、模型名写死、JSON 参数漂移而失败;或者把 Key 塞进 workflow 后,才发现每次生成的板厚、孔径、圆角、约束关系都散落在日志里,没有统一归档。近期围绕 1.5B 量级 CAD 生成模型的讨论,核心并不是“画一个好看的曲面”,而是把 CAD 意图落到可校验的参数树上。参数级输出的好处是:它天然适合 CI,因为你可以用 JSON Schema、数值范围和回归快照来断言结果。

这篇内容围绕一个可跟做的 CI 集成路径展开:先到 TaoToken 官网 获取 API Key,再把请求出口统一填成https://taotoken.net/api,最后在 CI 里完成 CAD 参数生成、测试命令执行和生成结果归档。整个流程不依赖本地图形界面,所有命令都可以在 CI Runner 或读者自己的终端里执行。

需要提前明确三个配置事实:

  • TaoToken 的 Base URL 是https://taotoken.net/api,这个地址用于工具和 SDK 的请求出口,不加 UTM 参数。
  • API Key 用占位符YOUR_API_KEY表示,实际使用时请从 CI Secret 或本地环境变量注入。
  • Claude Code、Codex、CC Switch 的配置方式不同,不能把ANTHROPIC_*环境变量套到 Codex 的config.toml上。

下面的目标很明确:让每次 PR 或手动触发 CI 时,都能通过 TaoToken 调用模型,生成一份 CAD 参数 JSON,跑完 Schema 与范围校验,并把原始响应、参数文件、manifest 一起归档。

2. 在 TaoToken 创建 Key 并做最小连通性验证

第一步不是直接写 workflow,而是先确认请求出口可用。到 TaoToken 官网 进入控制台相关入口,创建 API Key。也可以直接打开 API Keys 页面:创建 Key。创建完成后,把 Key 保存到本地环境变量或 CI Secret 中,命名建议用TAOTOKEN_API_KEY

本地最小验证可以用 Python + OpenAI 兼容 SDK。先安装依赖:

python -m venv .venv source .venv/bin/activate pip install openai jsonschema pytest export TAOTOKEN_API_KEY="YOUR_API_KEY" export TAOTOKEN_BASE_URL="https://taotoken.net/api" export TAOTOKEN_MODEL="YOUR_MODEL"

然后运行一个最小脚本,确认 Key、Base URL 和模型名三者匹配:

import os from openai import OpenAI client = OpenAI( base_url=os.environ["TAOTOKEN_BASE_URL"], api_key=os.environ["TAOTOKEN_API_KEY"], ) resp = client.chat.completions.create( model=os.environ["TAOTOKEN_MODEL"], messages=[ {"role": "system", "content": "你只输出 JSON,不要输出解释。"}, {"role": "user", "content": "输出一个 CAD 参数测试对象:外径 80,内径 30,厚度 6。"}, ], temperature=0, timeout=60, ) print(resp.choices[0].message.content)

如果这里返回 401,优先检查TAOTOKEN_API_KEY是否被正确注入,以及请求头是否为 Bearer 形式。如果返回模型不存在或 404,请到 模型对话 里确认当前可用模型名,再写入TAOTOKEN_MODEL。不要凭记忆写死模型名,也不要把 Claude Code 的ANTHROPIC_MODEL直接复制到 Codex 配置里。

为了让 CAD 参数生成在 CI 里可重复,建议把输入规格整理成 fixtures JSON。例如:

{ "part_type": "flange", "unit": "mm", "outer_diameter": 80, "inner_diameter": 30, "thickness": 6, "holes": { "count": 4, "diameter": 6, "pattern": "equally_spaced" }, "constraints": [ "孔中心圆直径等于外径减 2 倍边距", "所有孔均布在中心圆上", "厚度大于 0 且小于外径的 0.2 倍" ] }

模型的任务不是画图,而是把自然语言规格和约束转成结构化参数。输出可以约定为:

{ "part_type": "flange", "unit": "mm", "parameters": { "outer_diameter": 80, "inner_diameter": 30, "thickness": 6, "hole_count": 4, "hole_diameter": 6, "hole_pattern": "equally_spaced" }, "constraints": [ { "name": "hole_pcd", "expression": "outer_diameter - 2 * edge_margin", "value": 68 } ], "operations": [ "create_cylinder", "cut_inner_cylinder", "cut_holes", "apply_fillet" ] }

这个 JSON 就是后续测试和归档的核心产物。

3. GitHub Actions 配置片段:让 1.5B CAD 参数生成随 PR 跑起来

建议在仓库里建立如下目录,避免把生成逻辑散落在 workflow 内联脚本里:

cad-ci/ fixtures/ cad_specs/ flange_001.json baseline/ flange_001.params.json prompts/ cad_param_prompt.txt schemas/ cad_params.schema.json scripts/ generate_cad_params.py write_manifest.py diff_params.py tests/ test_cad_params.py artifacts/ .gitkeep .github/ workflows/ cad-param-ci.yml

generate_cad_params.py负责读取输入规格、拼接 prompt、调用 TaoToken、校验 JSON 并写入artifacts/。示例:

import argparse import hashlib import json import os import pathlib import sys import time from openai import OpenAI BASE_URL = os.environ.get("TAOTOKEN_BASE_URL", "https://taotoken.net/api") API_KEY = os.environ["TAOTOKEN_API_KEY"] MODEL = os.environ.get("TAOTOKEN_MODEL", "YOUR_MODEL") client = OpenAI(base_url=BASE_URL, api_key=API_KEY) PROMPT_TEMPLATE = """你是 CAD 参数化生成器。 请根据输入规格输出严格 JSON,字段必须符合: - part_type: string - unit: string - parameters: object - constraints: array - operations: array 不要输出 Markdown,不要输出解释,不要输出代码块。 输入规格: {spec} """ def load_json(path: str) -> dict: return json.loads(pathlib.Path(path).read_text(encoding="utf-8")) def save_json(path: str, data: dict) -> None: p = pathlib.Path(path) p.parent.mkdir(parents=True, exist_ok=True) p.write_text(json.dumps(data, ensure_ascii=False, indent=2), encoding="utf-8") def prompt_hash(text: str) -> str: return hashlib.sha256(text.encode("utf-8")).hexdigest()[:16] def generate(spec: dict) -> dict: prompt = PROMPT_TEMPLATE.format(spec=json.dumps(spec, ensure_ascii=False)) last_error = None for attempt in range(3): try: resp = client.chat.completions.create( model=MODEL, messages=[ {"role": "system", "content": "只输出合法 JSON。"}, {"role": "user", "content": prompt}, ], temperature=0, response_format={"type": "json_object"}, timeout=90, ) content = resp.choices[0].message.content return json.loads(content) except Exception as exc: last_error = exc time.sleep(2 ** attempt) raise RuntimeError(f"CAD 参数生成失败: {last_error}") def main() -> int: parser = argparse.ArgumentParser() parser.add_argument("--input", required=True) parser.add_argument("--output", required=True) args = parser.parse_args() spec = load_json(args.input) result = generate(spec) save_json(args.output, result) print(json.dumps({ "input": args.input, "output": args.output, "model": MODEL, "base_url": BASE_URL, "prompt_hash": prompt_hash(json.dumps(spec, ensure_ascii=False)), }, ensure_ascii=False)) return 0 if __name__ == "__main__": sys.exit(main())

workflow 可以这样写:

name: cad-param-ci on: pull_request: paths: - "cad-ci/**" workflow_dispatch: env: TAOTOKEN_BASE_URL: https://taotoken.net/api jobs: generate-and-validate: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: python-version: "3.11" - name: Install deps run: | pip install openai jsonschema pytest - name: Generate CAD params env: TAOTOKEN_API_KEY: ${{ secrets.TAOTOKEN_API_KEY }} TAOTOKEN_MODEL: ${{ vars.TAOTOKEN_MODEL }} run: | python cad-ci/scripts/generate_cad_params.py \ --input cad-ci/fixtures/cad_specs/flange_001.json \ --output cad-ci/artifacts/flange_001.params.json - name: Validate schema and ranges run: | pytest -q cad-ci/tests/test_cad_params.py - name: Write manifest run: | python cad-ci/scripts/write_manifest.py \ --artifacts cad-ci/artifacts \ --out cad-ci/artifacts/manifest.json - uses: actions/upload-artifact@v4 with: name: cad-param-artifacts path: cad-ci/artifacts/

这段配置里,TAOTOKEN_API_KEY来自仓库 Secret,TAOTOKEN_MODEL来自仓库变量。不要把 Key 写进 YAML,也不要提交.env。Base URL 统一使用https://taotoken.net/api,所有请求出口都从这里走。

4. 测试命令与生成结果归档:把参数级输出变成可回归快照

CI 里最值得投入的部分不是“调用一次模型”,而是让生成结果可验证。对于 CAD 参数级生成,建议至少做四类断言:

  1. JSON Schema 校验:字段是否齐全,类型是否正确。
  2. 数值范围校验:外径、内径、厚度、孔数、孔径是否落在合理区间。
  3. 约束一致性校验:孔中心圆、边距、均布关系是否被表达。
  4. 回归快照校验:与基线 JSON 对比,允许少量浮点误差。

tests/test_cad_params.py示例:

import json import pathlib import jsonschema import pytest SCHEMA = { "type": "object", "required": ["part_type", "unit", "parameters", "constraints", "operations"], "properties": { "part_type": {"type": "string"}, "unit": {"type": "string"}, "parameters": { "type": "object", "required": ["outer_diameter", "inner_diameter", "thickness", "hole_count", "hole_diameter"], "properties": { "outer_diameter": {"type": "number", "minimum": 10}, "inner_diameter": {"type": "number", "minimum": 0}, "thickness": {"type": "number", "minimum": 0.5}, "hole_count": {"type": "integer", "minimum": 1}, "hole_diameter": {"type": "number", "minimum": 0.5}, }, }, "constraints": {"type": "array"}, "operations": {"type": "array"}, }, } def load_params(): path = pathlib.Path("cad-ci/artifacts/flange_001.params.json") return json.loads(path.read_text(encoding="utf-8")) def test_schema(): jsonschema.validate(load_params(), SCHEMA) def test_ranges(): data = load_params() p = data["parameters"] assert p["outer_diameter"] > p["inner_diameter"] assert p["thickness"] < p["outer_diameter"] * 0.2 assert p["hole_count"] >= 3 assert p["hole_diameter"] < p["outer_diameter"] - p["inner_diameter"] def test_constraints_not_empty(): data = load_params() assert isinstance(data["constraints"], list) assert len(data["constraints"]) >= 1 def test_operations_contain_cut_holes(): data = load_params() assert any("hole" in op.lower() for op in data["operations"])

测试命令可以在本地和 CI 中一致执行:

pytest -q cad-ci/tests/test_cad_params.py -k "schema or ranges or constraints"

如果需要做回归对比,可以用diff_params.py比较基线:

import json import pathlib import sys def load(path): return json.loads(pathlib.Path(path).read_text(encoding="utf-8")) def main(current_path, baseline_path, tol=0.01): current = load(current_path) baseline = load(baseline_path) cur_p = current["parameters"] base_p = baseline["parameters"] failures = [] for key in base_p: if key not in cur_p: failures.append(f"缺少参数: {key}") continue if isinstance(base_p[key], (int, float)) and isinstance(cur_p[key], (int, float)): if abs(cur_p[key] - base_p[key]) > tol: failures.append(f"{key}: {cur_p[key]} != {base_p[key]}") elif cur_p[key] != base_p[key]: failures.append(f"{key}: {cur_p[key]} != {base_p[key]}") if failures: print("\n".join(failures)) sys.exit(1) print("参数回归通过") if __name__ == "__main__": main(sys.argv[1], sys.argv[2])

执行命令:

python cad-ci/scripts/diff_params.py \ cad-ci/artifacts/flange_001.params.json \ cad-ci/fixtures/baseline/flange_001.params.json

归档部分建议至少保存:

  • flange_001.params.json:模型返回并解析后的参数。
  • raw_response.txt:原始响应文本,方便排查 JSON 漂移。
  • manifest.json:模型名、Base URL、prompt hash、Git SHA、时间戳。
  • pytest.log:测试输出。

manifest 脚本可以写成:

import argparse import datetime import hashlib import json import os import pathlib def sha256_file(path): h = hashlib.sha256() h.update(pathlib.Path(path).read_bytes()) return h.hexdigest()[:16] def main(): parser = argparse.ArgumentParser() parser.add_argument("--artifacts", required=True) parser.add_argument("--out", required=True) args = parser.parse_args() artifacts = pathlib.Path(args.artifacts) files = [] for p in sorted(artifacts.glob("*")): if p.is_file() and p.name != "manifest.json": files.append({ "name": p.name, "sha256_16": sha256_file(p), "size": p.stat().st_size, }) manifest = { "model": os.environ.get("TAOTOKEN_MODEL", "YOUR_MODEL"), "base_url": os.environ.get("TAOTOKEN_BASE_URL", "https://taotoken.net/api"), "git_sha": os.environ.get("GITHUB_SHA", "local"), "created_at": datetime.datetime.utcnow().isoformat() + "Z", "files": files, } pathlib.Path(args.out).write_text( json.dumps(manifest, ensure_ascii=False, indent=2), encoding="utf-8", ) print(json.dumps(manifest, ensure_ascii=False, indent=2)) if __name__ == "__main__": main()

这样每次 CI 结束后,cad-param-artifacts里都有一份可追溯的参数生成记录。

5. CI Runner 上的 Claude Code、Codex 与 CC Switch 配置

虽然 CAD 参数生成主要走 Python 脚本,但在本地开发或 CI 排障时,很多人会用 Claude Code、Codex 或 CC Switch 辅助检查 prompt、日志和配置。这里必须把配置方式分开。

Claude Code 使用settings.jsonANTHROPIC_*环境变量。示例:

{ "env": { "ANTHROPIC_BASE_URL": "https://taotoken.net/api", "ANTHROPIC_AUTH_TOKEN": "YOUR_API_KEY", "ANTHROPIC_MODEL": "YOUR_CLAUDE_MODEL" } }

注意:ANTHROPIC_BASE_URLANTHROPIC_AUTH_TOKENANTHROPIC_MODEL只用于 Claude Code 这一侧。不要把这些变量写进 Codex 的配置。

Codex 使用config.toml,配置形式不同。示例:

model = "YOUR_CODEX_MODEL" model_provider = "taotoken" [model_providers.taotoken] name = "TaoToken" base_url = "https://taotoken.net/api" env_key = "TAOTOKEN_API_KEY" wire_api = "chat"

Codex 侧的关键是model_providerbase_urlenv_key,而不是ANTHROPIC_*。如果你在 CI Runner 上同时装了 Claude Code 和 Codex,建议把 API Key 统一放在TAOTOKEN_API_KEY,再按工具要求映射。

CC Switch 三件套通常可以理解为:

供应商名称:TaoToken-CI Base URL:https://taotoken.net/api API Key:YOUR_API_KEY

在 CC Switch 中新建或切换配置时,把这三项填好,再选择对应的 Claude Code 或 Codex profile。Claude Code 文档可以参考:Claude Code 文档。如果只是跑 CAD 参数生成流水线,不需要在 CI 里启动交互式工具,只需要保证 Python 脚本使用的https://taotoken.net/api和 Key 可用即可。

6. 常见报错排查:401、404、超时、JSON 漂移

CI 集成里最常见的四类问题可以按下面顺序排查。

第一类:401 或鉴权失败。检查 Secret 是否注入到当前 step,环境变量名是否为TAOTOKEN_API_KEY。如果是手动 curl,确认请求头是Authorization: Bearer $TAOTOKEN_API_KEY。不要在 YAML 里明文写 Key。需要新建 Key 时,到 创建 Key 处理。

第二类:404 或模型不可用。通常是TAOTOKEN_MODEL写错,或者模型名与当前账号可用范围不匹配。到 模型对话 里确认模型名,再更新 CI 变量。不要把 Claude Code 的模型名填到 Codex 配置里,也不要反向复制。

第三类:超时或间歇性失败。CI Runner 出网波动、模型排队、单次生成时间过长都会导致超时。建议设置timeout=90,失败重试 3 次,指数退避。对于 CAD 参数生成,单次请求不应无限重试,否则会掩盖 prompt 或 Schema 问题。

第四类:JSON 漂移。模型有时会返回 Markdown 代码块、注释或多余字段。处理方式包括:在 prompt 中要求“只输出合法 JSON”;使用response_format={"type": "json_object"};解析失败时保留原始响应;用jsonschema严格校验;把失败样本写入 artifacts,方便下一次调整 prompt。

可以在 workflow 里加一个失败时上传日志的步骤:

- name: Upload failed artifacts if: failure() uses: actions/upload-artifact@v4 with: name: cad-param-failed path: cad-ci/artifacts/

这样即使流水线失败,也能拿到原始输出和 manifest,而不是只看到一行红色报错。

7. 文末 CTA:模型对话 → Coding Plan → 创建 Key → Claude Code 文档

把 1.5B CAD 参数生成放进 CI,关键不是一次调用成功,而是把请求出口、Key 注入、测试断言和归档做成可重复流程。推荐按下面路径完成接入:

  1. 先到 模型对话 确认可用模型和参数级输出效果。
  2. 如果要把这类生成任务长期放进流水线,可以查看 Coding Plan。
  3. 然后到 创建 Key 生成YOUR_API_KEY
  4. 需要配置 Claude Code 时,参考 Claude Code 文档。

统一请求出口仍然是https://taotoken.net/api。更多入口可以从 TaoToken 官网 进入。把 Key 放进 Secret,把 Base URL 放进环境变量,把 CAD 参数 JSON 放进 artifacts,你的 CI 就具备了可追溯、可回归、可排障的 CAD 参数级生成能力。

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

grep转义完全指南:BRE、ERE与-F模式下的正则符号处理

我最早意识到“grep转义”是个值得单独写一篇的东西&#xff0c;是因为一次特别丢人的线上操作。当时我在排查一个Nginx日志里的来源IP分布&#xff0c;想精确统计192.168.1.10这个地址出现了多少次&#xff0c;于是很自然地敲了这条命令&#xff1a;grep "192.168.1.10&q…

作者头像 李华
网站建设 2026/9/18 23:51:20

ChromeDriver 116-119 驱动安装全解:版本匹配与多平台配置

做自动化测试这行的人&#xff0c;几乎都被 ChromeDriver 的版本问题绊过一跤。前阵子帮同事看一个跑了两年的采集脚本&#xff0c;报错只有一行SessionNotCreatedException: This version of ChromeDriver only supports Chrome version 114&#xff0c;但本机 Chrome 早就自动…

作者头像 李华
网站建设 2026/9/18 23:49:35

跑 Codex 自动改文件,TaoToken 只提供 Key

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/18 23:46:45

Monolith 3步跑通电影推荐模型:从训练到上线全解

Monolith 3步跑通电影推荐模型&#xff1a;从训练到上线全解 【免费下载链接】monolith A Lightweight Recommendation System 项目地址: https://gitcode.com/GitHub_Trending/monolith4/monolith 刷短视频时&#xff0c;你是否注意过刚点开一部电影&#xff0c;它马上…

作者头像 李华