img2threejs 规范化规格词汇表:面向本地规格检索的 JSONL 记录契约、实现与实战指南
2026/9/21 2:16:59 网站建设 项目流程
  • 人工智能
  • AI 技能
  • 3D渲染

【免费下载链接】img2threejs

Rebuild the object in a reference image as a code-only, procedural, quality-gated, animation-ready Three.js model. Token-efficient image-to-3D.

项目地址:https://gitcode.com/gh_mirrors/im/img2threejs
点击查看免费下载

本文档基于 docs/specs/vocabulary/README.md 展开,系统讲解 img2threejs 项目中"规范化规格词汇表(Normalized spec-record vocabulary)"的数据契约:如何以 JSONL 文件承载经过评审、可提交入库的规格记录,每条记录如何被校验、摄取、分词并进入本地 BM25 检索。读者学完后,将能够理解该目录下所有.jsonl记录的字段语义与稳定类型约束,掌握load_jsonl_records校验入口的错误行为,并能写出符合契约、可被 forge/stage1_intake/search_specs.py 检索命中的合格记录。

一、词汇表在 img2threejs 中的作用

img2threejs 的核心目标是把参考图中的物体重建为"纯代码、程序化、质量门控、可动画"的 Three.js 模型,并强调 Token 高效。在推理阶段,模型需要把一张参考图分解为组件、材质、约束、测量值等结构化知识;这些知识如果每次都由大模型现场"记忆",既消耗 Token 又不稳定。本目录正是为此服务的**本地规格检索(local specification search)**语料库:

  • 目录中存放的是**已评审、已提交(reviewed, committed)**的 JSONL 记录,每一条都是一个经过蒸馏的、带溯源的规格陈述;
  • 每个非空行恰好是一个 UTF-8 JSON 对象(docs/specs/vocabulary/README.md第 3-6 行);
  • 一个集合(collection)可以暂时没有记录文件,但只要记录文件存在,其每一行都必须满足本契约。

从仓库现状看,该目录下已有四个经过评审的语料文件:core_3d.jsonl、core_3d_reconstruction.jsonl、cs2.jsonl、cs2_reconstruction.jsonl,分别覆盖通用 3D 规格词汇与 CS2 武器/材质专项词汇。

二、记录文件的基本格式契约

词汇表目录的格式约束极为严格,任何提交的记录都必须遵守:

  1. 文件为 UTF-8 编码的JSONL(每行一个 JSON 对象);
  2. 空行允许存在并被忽略,但非空行必须整体是一个合法的 JSON 对象
  3. 不允许出现"半行"或跨行的 JSON 对象;
  4. 一旦存在记录文件,其所有行都必须通过字段级校验(详见下文"必填字段"),不存在豁免。

对应的读取与校验入口在 forge/_shared/spec_search.py 中已经落地实现(README 中称为"未来接入点",当前仓库已完成):

  • load_jsonl_records(path: Path)(forge/_shared/spec_search.py#L684-L698):逐行读取 UTF-8 文件,跳过空白行,对每一行执行json.loads_parse_record字段校验;
  • 任何失败都会抛出SpecRecordValidationError(forge/_shared/spec_search.py#L341-L348),该异常的字符串形式为{path}:{line_number}: {reason},即文件路径 + 从 1 开始的行号 + 具体原因
  • 契约明确:无效行永远不会被跳过或静默修复("Invalid rows are never skipped or silently repaired")。

测试 forge/tests/test_search_specs.py#L345-L352 专门验证了这一行为:向 fixture 追加一行残缺 JSON{"record_id":后,读取会抛出形如broken.jsonl:2: invalid JSON object的命名错误,而不是悄悄丢弃该行。

三、规范行(Canonical Row)逐字段解读

README 给出了完整的规范示例行(来自 CS2 武器解剖学的"Karambit 安全环"记录),这是所有记录必须对齐的骨架:

{ "record_id": "cs2.karambit.safety-ring", "collection": "cs2", "domain": "weapon-anatomy", "kind": "component", "entity": "karambit safety ring", "title": "Karambit safety ring / Vòng ngón Karambit", "aliases": ["safety ring", "finger ring", "vòng ngón"], "content": "A retention ring at the Karambit's pommel.", "constraints": ["Preserve the opening as a distinct component."], "measurements": [ {"name": "opening diameter", "value": "source-dependent", "unit": "mm"} ], "source_refs": [ { "path": "docs/cs2/3D_Technical_Mapping.json", "key_path": "karambit.components.safety_ring" }, {"path": "docs/cs2-anatomy/karambit.md", "heading": "Safety ring"} ], "evidence_refs": [ {"kind": "source", "ref": "docs/cs2/3D_Technical_Mapping.json"} ], "observation_status": "observed", "confidence": 0.9, "assumptions": [] }

关键语义(README 第 49-54 行):

  • record_id稳定、小写、点分隔的标识符,绝不从展示标题派生,且必须在措辞变化时保持稳定;
  • collection选择所属检索集合;
  • domainkindentity对记录做分类,但不强制全局统一的分类法(每个领域可用自己的分组习惯);
  • titlealiasescontent是可搜索文本;aliases保留作者编写的英/越双语术语,归一化与查询扩展发生在之后的处理阶段(即分词器与别名展开)。

3.1 规范行的源码映射

上述 15 个字段在源码中以 TypedDict 形式固化为SpecRecord(forge/_shared/spec_search.py#L95-L110),校验逻辑_parse_record(forge/_shared/spec_search.py#L656-L681)按固定顺序提取并强类型检查每个字段。字段级校验由_record_string(非空字符串,content例外允许为空)、_record_string_list(字符串数组)、_measurements_source_refs_evidence_refs等辅助函数完成,任何一个类型不符都会定位到具体的路径:行号:字段

四、必填字段与稳定类型表

README 以表格形式给出全部 15 个必填字段的稳定类型与语义,这是编写记录时的第一手参考:

字段类型语义
record_id非空字符串集合内稳定且唯一的标识符。
collection非空字符串拥有该记录的集合键。
domain非空字符串领域分组,如weapon-anatomypbr
kind非空字符串记录类别,如componentmaterialconstraint
entity非空字符串规范的实体或概念名。
title非空字符串人类可读的可搜索标题。
aliases字符串数组零或多个作者编写的同义词,已知时包含双语别名。
content字符串有来源支撑的简明描述;仅当结构化字段已承载可检索细节时才允许为空。
constraints字符串数组要求、禁止事项或注意事项。
measurements对象数组每个对象含非空字符串namevalue;可选unitcontext为字符串。数值保持为来源原文,而非杜撰数字。
source_refs非空对象数组蒸馏陈述的出处。每个对象含非空字符串path,可含非空字符串heading和/或key_path
evidence_refs对象数组辅助性出处。每个对象含非空字符串kindref;可选note为字符串。
observation_status字符串取值为observedinferredunverified三者之一。
confidence数字闭区间0.01.0;表示对蒸馏陈述本身的置信度,而非检索相关性。
assumptions字符串数组限定该记录的显式假设。

4.1 表内约束在源码中的落地

  • measurements:源码_measurements(forge/_shared/spec_search.py#L606-L621)强制namevalue为非空字符串,unitcontext若出现则必须是字符串(允许空串)。
  • source_refs:源码_source_refs(forge/_shared/spec_search.py#L624-L636)强制数组非空且每个元素必须有非空pathheadingkey_path任选其一或同时出现。
  • evidence_refs:源码_evidence_refs(forge/_shared/spec_search.py#L639-L653)强制kindref为非空字符串,note可选。
  • observation_statusconfidence_parse_record中,observation_status必须命中{observed, inferred, unverified}白名单;confidence必须为数字且0 <= confidence <= 1,且布尔值会被显式拒绝type(confidence) is bool直接报错)。

五、溯源(Provenance)设计:source_refs 与 evidence_refs

README 第 76-80 行强调:记录必须保留原始的源位置。这是词汇表"事实准确"原则的根基:

  • heading定位 Markdown 章节;
  • key_path定位 JSON 位置;
  • 当一种源格式同时提供两种定位形式时,一个 source reference 可以同时包含两者;
  • 所有路径均为仓库相对路径,使用正斜杠(/);
  • evidence_refs可以指向源文件、外部标识符或评审产物,但不能替代source_refs

两类引用的分工是:source_refs承载"蒸馏陈述的直接出处",evidence_refs承载"支撑性证据"。在 core_3d.jsonl 中可以看到实际用法:例如core.pbr-roughness记录同时引用grimoire/glossary/3d_vocabulary.mdheading: "Material And PBR")、grimoire/intake/image_analysis.mdheading: "Layer 5 — Materials & surface (PBR)")以及docs/raw/img2threejs-skill-dataset.jsonkey_path: "categories.material_pbr[1]")三类来源,并在evidence_refs中标注notebooklm-research类型的评审产物引用及其 note。

从源码看,SourceRefEvidenceRef的运行时形态是冻结数据类SourceReference/EvidenceReference(forge/_shared/spec_search.py#L165-L176),摄取 JSONL 时在_ingest_jsonl(forge/_shared/spec_search.py#L867-L898)中逐条重建,并透传到缓存与检索结果序列化中。

六、观察状态与置信度:如何表达"确定性"

README 第 82-86 行给出了三档观察状态的精确含义,这是整份契约中最需要纪律性的部分:

  • observed:直接由所引用源或参考产物支持;
  • inferred:有依据的合理解读,必须连同其假设一起保留;
  • unverified:有用的术语或候选主张,但仍需确认。

核心原则是:不要编码未经支持的确定性("Do not encode unsupported certainty")。当证据不足时,正确的做法是降低confidence、选择恰当的状态、并写下限定性的assumptions,而不是虚报为observed

6.1 真实语料中的实践

在 cs2.jsonl 中可以看到差异化实践:

  • cs2.karambit.safety-ring记录observation_status: "observed"confidence: 0.85,因为源文档明确提及该安全环为关键指孔细节;
  • cs2.knife.pommel记录observedconfidence: 0.9,其 measurement 直接来自技术映射(metalness 1.0、roughness 0.35);
  • cs2.wear-float-ranges记录在constraints中写明"将记录的区间视为术语支持,而非对未见物品磨损程度的断言",体现了"陈述与解释分离"的边界意识。

七、源码级实现:从记录文件到可检索索引

7.1 接入点load_jsonl_records

README 规划的"未来接入点"在当前仓库中已完整实现。load_jsonl_records(path: Path)(forge/_shared/spec_search.py#L684-L698)的行为与契约逐条对应:

  1. 以 UTF-8 读取文件,若文件不可读或编码非法,抛出带路径:0定位的SpecRecordValidationError
  2. 逐行枚举(从 1 开始的行号),跳过空白行;
  3. 单行json.loads失败 →SpecRecordValidationError(path, line_number, "invalid JSON object")
  4. _parse_record逐字段强类型校验(对象、非空字符串、字符串数组、measurements/source_refs/evidence_refs 嵌套结构、状态白名单、置信度区间);
  5. 返回list[SpecRecord]

契约中"错误识别输入路径与从 1 开始的行号""无效行永不跳过"的承诺,正是由上述第 3、4 步的实现保证的。

7.2 后续流水线:摄取 → 分词 → BM25

记录文件只是起点。spec_search模块把三种来源(Markdown、JSON、JSONL)统一摄取为SourceDocument(forge/_shared/spec_search.py#L179-L190),其中 JSONL 记录的titlecontentaliasessource_refsevidence_refs被原样保留。之后:

  • 分词器tokenize,forge/_shared/spec_search.py#L739-L772)执行 Unicode 归一化(默认 NFKC)、casefold、越南语声调折叠(accent_fold: "vi",如độ同时产生donhám同时产生nham),并可选保留标识符与数字(如AK-470.05-0.15各成一个 token);
  • BM25 检索build_index/search_index,forge/_shared/spec_search.py#L1011-L1084)以默认k1=1.5b=0.75构建倒排索引,按(-score, record_id)排序;
  • 缓存生命周期load_or_build_index,forge/_shared/spec_search.py#L1752-L1792)通过 schema/tokenizer/config/source 四类指纹判断缓存命中(hit)或重建(rebuilt,原因可为missing/stale/corrupt/forced),并采用临时文件 +os.replace的原子写入。

从源码结构可以推断,词汇表记录、原始文档与配置文件最终在同一套索引管道中统一检索,这正是"本地规格检索"的完整闭环。

八、集合配置:spec_search_profiles.json

记录属于哪个集合、以哪些原始文档为可选源、缓存写到哪里,由 forge/_shared/spec_search_profiles.json 统一声明。当前仓库内置两个集合:

集合键optional_source_rootsdistilled_records缓存路径
cs2docs/cs2/docs/cs2-anatomy/docs/specs/vocabulary/cs2.jsonlcs2_reconstruction.jsonlcore_3d.jsonlcore_3d_reconstruction.jsonl.cache/spec-search/cs2.json
core_3ddocs/specs/vocabulary/core_3d.jsonlcore_3d_reconstruction.jsonl.cache/spec-search/core_3d.json

defaults中的全局默认值即前文所述的 tokenizer(NFKC / casefold / vi 声调折叠 / 保留标识符与数字)、aliases(enabled: truemax_expansions: 1)与 BM25(k1: 1.5b: 0.75)。配置文件本身由load_profiles(forge/_shared/spec_search.py#L489-L556)严格解析,任何字段类型不符或profile_schema_version非法都会抛出ProfileValidationError;缓存路径与源路径均强制为仓库内相对路径,绝对路径或含..的穿越路径会被拒绝(防止索引越界写入)。

九、CLI 实战:搜索已入库的规格记录

仓库提供了命令行检索工具 forge/stage1_intake/search_specs.py,可直接对已评审的词汇表记录做本地 BM25 检索:

# 默认在 cs2 集合中检索(默认 limit=3,snippet-chars=250) python3 forge/stage1_intake/search_specs.py safety ring vòng ngón # 指定集合与输出条数,并输出结构化 JSON python3 forge/stage1_intake/search_specs.py --collection core_3d roughness độ nhám --limit 5 --json # 强制重建索引缓存 python3 forge/stage1_intake/search_specs.py --reindex karambit

CLI 行为要点(forge/stage1_intake/search_specs.py#L95-L254):

  • 参数:位置参数query(可多个词,空格拼接)、--collection(默认cs2)、--limit(默认 3)、--snippet-chars(默认 250,最小 5)、--reindex--json
  • 人类可读输出打印Query / Collection / Index(status+reason+fingerprint),每个匹配项输出record_idscoresource(含headingkey_path定位)与首条 snippet;
  • --json输出稳定结构:{query, collection, index, matches},每个 match 含record_idfile_pathheadingkey_pathscoresnippetssource_refsevidence_refs
  • 错误以结构化码区分:参数类错误(empty_queryinvalid_limitinvalid_snippet_charsunknown_collection)退出码 2;配置/源/缓存类错误(profile_failuresource_failureindex_failurecache_failure)退出码 3;
  • 无匹配是正常成功(退出码 0、matches为空数组),错误信息不会泄漏绝对路径(测试 forge/tests/test_search_specs.py#L884-L937 验证了路径穿越场景下既无越界写入、也不在输出中出现 Traceback 或仓库根路径)。

十、测试如何守护契约

forge/tests/test_search_specs.py 是这份契约的"活文档",其中与词汇表直接相关的断言包括:

  • test_future_jsonl_loader_api_is_documented(L326-L330):直接读取本 README,断言其中必须出现load_jsonl_records(path: Path)SpecRecordValidationError,保证文档与实现不脱节;
  • test_cs2_record_round_trips_with_bilingual_aliases_and_provenance(L332-L343):规范行写出再读回必须逐字段相等,且双语别名与key_path/heading定位完整保留;
  • test_malformed_jsonl_raises_named_validation_error_instead_of_skipping(L345-L352):残缺行按路径:行号:原因报错;
  • test_reviewed_bilingual_records_are_complete_and_source_backed(L356-L400):core_3d至少 12 条、cs2至少 8 条,record_id全局唯一,所有记录字段集合不得超过契约字段,source_refs非空,且双语别名集合与源路径集合必须覆盖既定清单。

这意味着:如果你向该目录提交一条新记录,测试套件会立即校验它的字段完整性、类型正确性、双语别名与溯源要求——契约不是纸面约定,而是可执行的回归门禁。

十一、编写合格记录的操作清单

结合 README 契约与源码校验逻辑,编写一条可入库的规格记录请按以下清单自检:

  1. 格式:UTF-8、每行一个 JSON 对象、无尾随解释文字;
  2. record_id:小写、点分隔、集合内唯一、不随标题措辞变化;
  3. 分类collection用既有集合键(cs2/core_3d),domainkindentity保持领域内一致的分组习惯;
  4. 可搜索文本title人类可读,aliases尽量补充已知双语同义词(英语 + 越南语),content必须由来源支撑,仅在结构化字段已承载检索细节时才允许留空;
  5. 溯源source_refs非空,路径为仓库相对路径、使用正斜杠,Markdown 用heading、JSON 用key_path定位,两种定位可并存;evidence_refs只作辅助,不能替代source_refs
  6. 测量值measurementsvalue保留来源原文(如"source-dependent""0.05–0.15"),绝不编造数字;
  7. 确定性表达:按证据强度选择observed/inferred/unverifiedconfidence落在0.0–1.0闭区间且反映陈述置信度而非检索相关性;不确定时降低置信度、写明assumptions
  8. 提交前验证:运行 forge/tests/test_search_specs.py 相关用例,或直接调用load_jsonl_records,确认无SpecRecordValidationError

十二、小结

本目录的词汇表契约本质上是把"模型推理时需要的事实知识"工程化为可评审、可溯源、可检索、可版本化的数据资产:15 个稳定字段约束结构,source_refs/evidence_refs约束事实出处,observation_status/confidence/assumptions约束确定性边界,而 forge/_shared/spec_search.py 中的严格校验、分词器与 BM25 索引则把这份契约变成可运行的本地规格检索能力。任何一条新增记录,只有同时满足格式、类型、溯源与确定性四层要求,才能进入检索管线,为 img2threejs 的"Token 高效"目标提供可靠的事实底座。

  • 人工智能
  • AI 技能
  • 3D渲染

【免费下载链接】img2threejs

Rebuild the object in a reference image as a code-only, procedural, quality-gated, animation-ready Three.js model. Token-efficient image-to-3D.

项目地址:https://gitcode.com/gh_mirrors/im/img2threejs
点击查看免费下载

相关推荐

上一篇:Freqtrade外部消息消费者:第三方系统集成接口
下一篇:一键导出云架构图:diagrams全格式输出与高效协作指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询