OpenChronology(暂定名)开源项目完整设计方案

目标:构建一个语言无关、数据优先、可社区穷尽扩展的全球历法与纪年知识库 + 计算框架,系统收录全世界文献中出现的历法与纪年体系,并妥善处理无法(或不适合)完全映射到儒略日(JD)的情况。采用 MIT 协议。

1. 项目愿景与成功标准

  • 愿景:成为历史学家、程序员、语言学家、业余年代学爱好者共同维护的“全球时间本体”权威开放数据仓库。
  • 核心目标:
    • 穷尽(持续追求)文献中的历法与纪年。
    • 支持绝对时间(JD/RD)与非绝对时间(相对、循环、文学、不确定区间)。
    • 最大程度降低特定编程语言依赖。
    • 高可维护性与可验证性。
  • 成功标准(5 年内):
    • 覆盖主流 + 大量冷门历法/年号(目标 200+ 体系)。
    • 所有数据有文献来源与置信度。
    • 任何语言都能直接消费核心数据。
    • 活跃贡献者社区。

2. 核心设计原则

  1. 数据优先(Data-first):90% 以上内容是结构化数据,计算逻辑最小化并插件化。
  2. 语言无关(Language-agnostic):核心资产 = JSON/YAML + JSON Schema + Markdown。计算层可选(参考实现 + WASM)。
  3. 可列举 vs 不可列举:
    • 可列举(年号、切换点、对照表、固定节日)→ 纯 JSON 数据。
    • 不可列举(算术/天文规则)→ 计算插件或声明式规则。
  4. 非强制 JD:允许 jd_mappable: false/partial,支持本地时间线。
  5. 文献可追溯:每个条目必须附带来源、适用时间、已知局限、置信度。
  6. Schema 强制:所有数据必须通过 JSON Schema 验证。
  7. 渐进穷尽:先做高质量骨架,再社区补充。

3. 整体架构

用户 / 工具    ↓查询 / 转换 API(可选,多语言绑定)    ↓┌─────────────────────────────────────┐│  计算插件层(可选)                  ││  - 算术历法插件                      ││  - 天文计算插件                      ││  - WASM 通用实现                     │└─────────────────────────────────────┘    ↓统一中间表示(TemporalID)    - 优先 JD / Rata Die    - 支持 local-timeline-id / interval / relative    ↓┌─────────────────────────────────────┐│  数据层(核心,语言无关)            ││  - calendars/                        ││  - eras/                             ││  - chronologies/                     ││  - transitions/                      ││  - non-jd/                           ││  - sources/                          │└─────────────────────────────────────┘

TemporalID 是关键抽象:可以是精确 JD、JD 区间、相对表达式或纯本地标识。

4. 数据模型设计(JSON Schema 为核心)

主要 Schema(放在 schemas/):

  • calendar.schema.json:历法定义(类型、组件、算法引用、数据文件、范围、局限)。
  • era.schema.json:纪年/年号(支持嵌套、重叠、废立、起止对应)。
  • chronology.schema.json:完整时间线或对照表。
  • transition.schema.json:历法切换点(按地区/政权)。
  • temporal-expression.schema.json:时间表达(绝对/相对/区间/循环/文学)。
  • source.schema.json:文献元数据(书名、作者、页码、DOI、置信度)。
  • conversion-rule.schema.json:声明式转换规则(进一步减少代码)。

示例关键字段(历法):

json

{  "id": "chinese-qing-official",  "names": {"en": "...", "zh": "清代官方历"},  "type": ["lunisolar", "historical", "hybrid"],  "jd_mappable": "partial",  "range": {"from": "1644-01-01", "to": "1911-12-31", "certainty": "high"},  "algorithm": "plugin:chinese-astronomical@1.2" 或 "tabular",  "data_refs": ["data/calendars/chinese-qing/months.json"],  "sources": ["src:xxx"],  "limitations": ["部分年份与现代推算有 ±1 日差异"],  "tags": ["east-asia", "imperial"]}

非 JD 体系单独放在 data/non-jd/,明确标记 expression_type 和对应关系说明。

5. 计算与插件系统

  • 统一接口(用 OpenAPI 或简单 JSON 描述,语言无关):
    • to_temporal(date, calendar_id) → TemporalID
    • from_temporal(id, target_calendar) → date
    • validate(date, calendar_id)
    • list_components(calendar_id)
  • 实现策略:
    • 参考实现:Python(易读 + 科学计算)或 TypeScript。
    • 通用运行时:编译为 WebAssembly,实现真正跨语言。
    • 简单规则:支持纯 JSON 声明式规则(例如固定置闰周期),无需代码。
    • 插件注册:通过 plugins/manifest.json 声明支持的历法与版本。

6. 仓库结构

text

omnichronos/├── LICENSE                 # MIT├── README.md├── CONTRIBUTING.md├── CODE_OF_CONDUCT.md├── schemas/                # JSON Schema(强制)├── data/│   ├── calendars/│   ├── eras/│   ├── chronologies/│   ├── transitions/│   ├── non-jd/│   └── sources/├── rules/                  # 声明式规则(可选)├── plugins/│   ├── reference/          # 参考实现│   ├── wasm/│   └── bindings/           # 其他语言示例├── tools/                  # 验证、生成、测试脚本├── docs/│   ├── design.md│   ├── ontology.md│   ├── handling-non-jd.md│   └── how-to-add-calendar.md├── tests/│   ├── schema/│   ├── fixtures/           # 黄金测试用例│   └── crosschecks/└── .github/workflows/      # CI:Schema 校验 + 测试

7. 贡献与质量控制流程

  1. 新增/修改必须通过对应 Schema 验证。
  2. 必须提供至少 2 个独立文献来源。
  3. 必须附带测试用例(fixtures)。
  4. 非 JD 条目必须详细说明对应关系与局限。
  5. CI 自动运行 Schema 校验 + 转换一致性测试。
  6. 人工审核(初期由维护者,后期可引入领域专家标签)。
  7. 数据与 Schema 独立语义化版本(例如 data v1.2.0 + schema v0.9.0)。

8. 技术选型(最大化通用性)

  • 数据格式:JSON(主)+ YAML(人类友好)+ Markdown(文档)。
  • 验证:JSON Schema Draft 2020-12。
  • 工具链:任意语言(推荐 Python/Node 写验证脚本),但运行时零依赖。
  • 计算:参考实现可选;优先提供 WASM。
  • 发布:数据可独立打包(npm、PyPI、crates、纯 git 子模块)。
  • 查询界面(后期):静态站点或简单 API,非核心。

9. 处理非 JD 情况的专门设计

  • 分类:relative、cyclical、interval、literary/mythical、observational-historical、fragmentary。
  • 每个条目声明 jd_mappable 和 correspondence(可能的 JD 范围 + 置信度 + 假说)。
  • 支持“本地时间线 ID”,允许纯内部推演而不强制外部锚点。
  • 文档强制要求写清“为什么不能完全映射”以及已知外部对照点。

10. 版本、治理与社区

  • 协议:MIT(数据与代码均适用)。
  • 治理:初期单维护者 + 明确贡献指南;后期可成立小型核心团队 + 领域专家顾问。
  • 版本策略:数据与 Schema 分开版本;破坏性变更需 major。
  • 社区:GitHub Discussions + 定期数据质量报告;鼓励历史学者直接贡献 JSON。

11. 启动路线图(建议)

Phase 0(1–2 周)
确定最终名称、创建仓库、写完核心 Schema 与设计文档。

Phase 1(1–2 月)
实现 5–8 个代表性例子(格里高利、中国年号、伊斯兰表格历、一个非 JD 神话体系、一个历史切换点、希伯来、玛雅),搭建完整 CI。

Phase 2
完善文档与贡献模板,公开 v0.1,开始接受外部贡献。

Phase 3+
持续扩充数据、增加 WASM、多语言绑定、简单查询界面、与现有工具(HistoryCal、pycalcal 等)互操作。

12. 名称候选

  • OmniChronos
  • ChronoLexicon
  • UniversalChronology
  • Calendria
  • TemporalAtlas
  • WorldEra

这个设计把“穷尽文献 + 非 JD 支持 + 语言无关 + 高可维护”落到了可执行的架构上。它填补了当前空白,同时保持足够弹性,让历史学家和程序员都能参与。

附:OpenChronology 项目的 README.md 和 CONTRIBUTING.md 初稿

README.md 初稿

markdown

# OpenChronology
**A language-agnostic, data-first open knowledge base for the world’s calendars and chronologies.**
OmniChronos aims to systematically collect, structure, and make interoperable every calendar system and era-dating scheme attested in historical and contemporary literature — including those that cannot be fully mapped to the Julian Day Number (JD).
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)[![Schema Validation](https://github.com/your-org/omnichronos/actions/workflows/validate.yml/badge.svg)](https://github.com/your-org/omnichronos/actions)
## Why OpenChronology?
Existing calendar libraries focus on algorithmic conversion of a limited set of well-known systems (usually 10–40 calendars) and almost always force everything through Julian Day / Rata Die.  
No current open project systematically:
- Targets **exhaustive** coverage of calendars and era systems found in world literature- Properly handles **non-JD-mappable** cases (relative dating, cyclical systems, literary/mythical timelines, fragmentary records, pure observational calendars)- Keeps the core as pure, language-agnostic structured data- Makes it easy for historians and domain experts (not just programmers) to contribute
OmniChronos fills this gap.
## Key Features
- **Data-first architecture**: Most content lives in validated JSON/YAML files- **Language-agnostic**: Core data can be consumed by any programming language- **Full support for non-absolute time**: relative, cyclical, interval, literary, and uncertain expressions- **Strict provenance**: Every entry requires bibliographic sources and confidence information- **Plugin system** for algorithmic calendars (with reference implementations and WebAssembly targets)- **MIT licensed**
## Project Structure

omnichronos/ ├── schemas/ # JSON Schema definitions (the contract) ├── data/ │ ├── calendars/ # Calendar definitions │ ├── eras/ # Era / regnal / year-numbering systems │ ├── chronologies/ # Full timelines and conversion tables │ ├── transitions/ # Calendar change points by region │ ├── non-jd/ # Systems that cannot fully map to JD │ └── sources/ # Bibliographic records ├── plugins/ # Calculation plugins (optional) ├── tools/ # Validation and utility scripts └── docs/ # Design documents and guides


## Quick Start
### 1. Use the data directly
All data files are plain JSON and validated against the schemas in `/schemas`.  You can load them with any language that supports JSON.
### 2. Validate locally
```bash# Example with ajv (Node.js)npm install -g ajv-cliajv validate -s schemas/calendar.schema.json -d data/calendars/**/*.json

3. Reference implementation (optional)

See /plugins/reference for a Python (or TypeScript) reference implementation of the conversion interface.

Status

Early design / v0.1 preparation

We currently provide:

  • Complete JSON Schema drafts
  • Core architecture documentation
  • Contribution guidelines

The first concrete data sets and reference plugins will be added in the coming weeks.

Contributing

We warmly welcome contributions from historians, philologists, astronomers, and developers.

Please read CONTRIBUTING.md [blocked] before submitting data or code.

The most valuable contributions right now are:

  • High-quality calendar / era definitions with solid sources
  • Tabular data for historical systems
  • Careful documentation of non-JD cases

License

This project is licensed under the MIT License.
See LICENSE [blocked] for details.

Data and schemas are also released under MIT so they can be freely reused in any context.

Acknowledgments

This project stands on the shoulders of many earlier efforts, especially:

  • Calendrical Calculations by Dershowitz & Reingold
  • HistoryCal
  • Various East Asian calendar authority databases
  • The broader open chronological and calendrical community

Maintainer note: This is an ambitious long-term project. Progress will be steady rather than explosive. Quality and provenance are valued over speed of coverage.


---
### CONTRIBUTING.md 初稿
```markdown# Contributing to OpenChronology
Thank you for your interest in contributing!
OmniChronos is a **data-first** project. The most valuable contributions are carefully researched calendar and era definitions with proper sources. Code contributions (plugins, tools, bindings) are also welcome.
## Ways to Contribute
1. **Add or improve calendar / era / chronology data** (highest priority)2. **Improve or extend JSON Schemas**3. **Write or improve calculation plugins**4. **Improve documentation**5. **Report issues or suggest missing systems**6. **Help with validation tooling and CI**
## Before You Start
1. Read the design documents in `/docs`2. Familiarize yourself with the schemas in `/schemas`3. Search existing issues and pull requests to avoid duplication
## Adding a New Calendar or Era
### Required steps
1. Create a new JSON file following the appropriate schema (`calendar.schema.json` or `era.schema.json`).2. Provide **at least two independent scholarly sources**.3. Clearly state the `jd_mappable` status (`true` / `false` / `partial`).4. Document limitations and known discrepancies.5. Add corresponding entries to `/data/sources/` if the sources are new.6. Include at least a few test fixtures if conversion is possible.
### File naming
- Use lowercase kebab-case: `chinese-qing-official.json`- Place files in the correct subdirectory under `/data`
### Validation
All submissions must pass schema validation.  You can validate locally with any JSON Schema validator (ajv, check-jsonschema, etc.).
Example:
```bashajv validate -s schemas/calendar.schema.json -d data/calendars/my-new-calendar.json

Handling Non-JD Cases

If a system cannot be reliably mapped to Julian Day:

  • Set "jd_mappable": "false" or "partial"
  • Use the temporal-expression structure carefully
  • Explain in the notes and limitations fields why full mapping is impossible or problematic
  • Record any known external anchor points and their confidence

We explicitly welcome literary, mythical, cyclical, and fragmentary systems.

Code Contributions (Plugins & Tools)

  • Prefer clear, well-documented code
  • Reference implementations should stay readable (Python or TypeScript preferred)
  • WebAssembly builds are highly encouraged for language independence
  • Follow the plugin interface defined in /docs/plugin-interface.md (to be finalized)

Pull Request Process

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Ensure all schemas validate and tests pass
  5. Open a Pull Request with a clear description
  6. Link related issues if applicable

Maintainers will review for:

  • Schema compliance
  • Source quality
  • Clarity of limitations
  • Consistency with existing data

Code of Conduct

This project follows a standard inclusive Code of Conduct (see CODE_OF_CONDUCT.md).
Be respectful, especially when discussing historical or cultural interpretations.

Questions?

Open a GitHub Discussion or an Issue with the question label.

Thank you for helping build a more complete and honest map of human timekeeping!

附:OmniChronos 项目的完整 JSON Schema 草案(基于 JSON Schema Draft 2020-12)

这些 Schema 设计遵循数据优先、语言无关、支持非 JD 映射、强制文献可追溯的原则。所有 Schema 都放在 schemas/ 目录下使用。

1. source.schema.json(文献来源)

json

{  "$schema": "https://json-schema.org/draft/2020-12/schema",  "$id": "https://omnichronos.org/schemas/source.schema.json",  "title": "Source",  "description": "Bibliographic or digital source reference for calendars, eras, and chronologies.",  "type": "object",  "required": ["id", "title", "type"],  "additionalProperties": false,  "properties": {    "id": {      "type": "string",      "pattern": "^src:[a-z0-9][a-z0-9_-]*$",      "description": "Unique source identifier, e.g. src:reingold-dershowitz-2018"    },    "title": {      "type": "string"    },    "type": {      "type": "string",      "enum": ["book", "article", "database", "website", "manuscript", "inscription", "official", "other"]    },    "authors": {      "type": "array",      "items": { "type": "string" }    },    "year": {      "type": "integer"    },    "publisher": { "type": "string" },    "isbn": { "type": "string" },    "doi": { "type": "string" },    "url": {      "type": "string",      "format": "uri"    },    "pages": { "type": "string" },    "language": {      "type": "string",      "description": "ISO 639-1 or 639-3 code"    },    "notes": { "type": "string" },    "accessed": {      "type": "string",      "format": "date"    }  }}

2. temporal-expression.schema.json(时间表达,核心支持非 JD)

json

{  "$schema": "https://json-schema.org/draft/2020-12/schema",  "$id": "https://omnichronos.org/schemas/temporal-expression.schema.json",  "title": "Temporal Expression",  "description": "Flexible representation of a point, interval, or relative time, including non-JD-mappable cases.",  "type": "object",  "required": ["expression_type"],  "additionalProperties": false,  "properties": {    "expression_type": {      "type": "string",      "enum": [        "absolute",        "relative",        "interval",        "cyclical",        "literary",        "observational",        "fragmentary",        "uncertain"      ]    },    "calendar_ref": {      "type": "string",      "description": "Reference to a calendar or era id"    },    "value": {      "description": "The actual temporal value. Structure depends on expression_type and calendar.",      "oneOf": [        { "type": "object" },        { "type": "string" },        { "type": "number" },        { "type": "array" }      ]    },    "jd": {      "type": "number",      "description": "Exact Julian Day Number if fully mappable"    },    "jd_range": {      "type": "object",      "properties": {        "min": { "type": "number" },        "max": { "type": "number" }      },      "required": ["min", "max"]    },    "confidence": {      "type": "number",      "minimum": 0,      "maximum": 1,      "description": "0.0–1.0 confidence in the correspondence"    },    "jd_mappable": {      "type": "string",      "enum": ["true", "false", "partial"]    },    "notes": { "type": "string" },    "sources": {      "type": "array",      "items": { "type": "string", "pattern": "^src:" }    },    "hypotheses": {      "type": "array",      "items": { "type": "string" },      "description": "Alternative interpretations when uncertain"    }  }}

3. calendar.schema.json(历法定义)

json

{  "$schema": "https://json-schema.org/draft/2020-12/schema",  "$id": "https://omnichronos.org/schemas/calendar.schema.json",  "title": "Calendar",  "description": "Definition of a calendar system.",  "type": "object",  "required": ["id", "names", "type", "jd_mappable"],  "additionalProperties": false,  "properties": {    "id": {      "type": "string",      "pattern": "^[a-z0-9][a-z0-9_-]*$",      "description": "Unique calendar identifier, e.g. chinese-qing-official"    },    "names": {      "type": "object",      "additionalProperties": { "type": "string" },      "description": "Multilingual names. Keys are language codes (en, zh, ja, etc.)",      "minProperties": 1    },    "type": {      "type": "array",      "items": {        "type": "string",        "enum": [          "solar", "lunar", "lunisolar", "arithmetic", "astronomical",          "observational", "tabular", "hybrid", "historical", "proposed",          "literary", "cyclical", "other"        ]      },      "minItems": 1,      "uniqueItems": true    },    "jd_mappable": {      "type": "string",      "enum": ["true", "false", "partial"]    },    "range": {      "type": "object",      "properties": {        "from": { "$ref": "temporal-expression.schema.json" },        "to": { "$ref": "temporal-expression.schema.json" },        "certainty": {          "type": "string",          "enum": ["high", "medium", "low", "unknown"]        }      }    },    "components": {      "type": "array",      "items": { "type": "string" },      "description": "e.g. year, month, leap-month, day, ganzhi, weekday"    },    "epoch": {      "$ref": "temporal-expression.schema.json"    },    "algorithm": {      "type": "string",      "description": "Plugin reference, e.g. plugin:gregorian@1.0 or 'tabular' or 'declarative'"    },    "data_refs": {      "type": "array",      "items": { "type": "string" },      "description": "Paths to tabular data files"    },    "rules_ref": {      "type": "string",      "description": "Reference to declarative rules file"    },    "sources": {      "type": "array",      "items": { "type": "string", "pattern": "^src:" },      "minItems": 1    },    "limitations": {      "type": "array",      "items": { "type": "string" }    },    "tags": {      "type": "array",      "items": { "type": "string" }    },    "related": {      "type": "array",      "items": { "type": "string" },      "description": "Related calendar or era ids"    },    "notes": { "type": "string" }  }}

4. era.schema.json(纪年 / 年号)

json

{  "$schema": "https://json-schema.org/draft/2020-12/schema",  "$id": "https://omnichronos.org/schemas/era.schema.json",  "title": "Era",  "description": "A named era, regnal year system, or year-numbering scheme (e.g. Chinese nianhao, Japanese nengō).",  "type": "object",  "required": ["id", "names", "jd_mappable"],  "additionalProperties": false,  "properties": {    "id": {      "type": "string",      "pattern": "^[a-z0-9][a-z0-9_-]*$"    },    "names": {      "type": "object",      "additionalProperties": { "type": "string" },      "minProperties": 1    },    "type": {      "type": "array",      "items": {        "type": "string",        "enum": [          "regnal", "dynastic", "religious", "political", "cyclical",          "olympiad", "consular", "era", "other"        ]      }    },    "jd_mappable": {      "type": "string",      "enum": ["true", "false", "partial"]    },    "parent": {      "type": "string",      "description": "Parent dynasty or higher-level era id"    },    "start": {      "$ref": "temporal-expression.schema.json"    },    "end": {      "$ref": "temporal-expression.schema.json"    },    "year_counting": {      "type": "string",      "enum": ["ascending", "descending", "regnal", "fixed", "other"],      "description": "How years are numbered within the era"    },    "calendar_ref": {      "type": "string",      "description": "The underlying calendar this era is expressed in"    },    "successors": {      "type": "array",      "items": { "type": "string" }    },    "predecessors": {      "type": "array",      "items": { "type": "string" }    },    "sources": {      "type": "array",      "items": { "type": "string", "pattern": "^src:" },      "minItems": 1    },    "limitations": {      "type": "array",      "items": { "type": "string" }    },    "tags": {      "type": "array",      "items": { "type": "string" }    },    "notes": { "type": "string" }  }}

5. transition.schema.json(历法切换点)

json

{  "$schema": "https://json-schema.org/draft/2020-12/schema",  "$id": "https://omnichronos.org/schemas/transition.schema.json",  "title": "Calendar Transition",  "description": "A point or period when a region or polity changed calendar systems.",  "type": "object",  "required": ["id", "from_calendar", "to_calendar", "when", "region"],  "additionalProperties": false,  "properties": {    "id": {      "type": "string",      "pattern": "^[a-z0-9][a-z0-9_-]*$"    },    "from_calendar": { "type": "string" },    "to_calendar": { "type": "string" },    "when": {      "$ref": "temporal-expression.schema.json"    },    "region": {      "type": "object",      "properties": {        "names": {          "type": "object",          "additionalProperties": { "type": "string" }        },        "modern_codes": {          "type": "array",          "items": { "type": "string" },          "description": "ISO 3166 or historical place identifiers"        }      }    },    "days_skipped": {      "type": "integer",      "description": "Number of days skipped or inserted (can be negative)"    },    "sources": {      "type": "array",      "items": { "type": "string", "pattern": "^src:" },      "minItems": 1    },    "notes": { "type": "string" }  }}

6. chronology.schema.json(完整时间线 / 对照表)

json

{  "$schema": "https://json-schema.org/draft/2020-12/schema",  "$id": "https://omnichronos.org/schemas/chronology.schema.json",  "title": "Chronology",  "description": "A structured timeline or conversion table linking multiple systems.",  "type": "object",  "required": ["id", "names", "entries"],  "additionalProperties": false,  "properties": {    "id": {      "type": "string",      "pattern": "^[a-z0-9][a-z0-9_-]*$"    },    "names": {      "type": "object",      "additionalProperties": { "type": "string" },      "minProperties": 1    },    "description": { "type": "string" },    "range": {      "type": "object",      "properties": {        "from": { "$ref": "temporal-expression.schema.json" },        "to": { "$ref": "temporal-expression.schema.json" }      }    },    "entries": {      "type": "array",      "items": {        "type": "object",        "required": ["temporal"],        "properties": {          "temporal": { "$ref": "temporal-expression.schema.json" },          "labels": {            "type": "object",            "additionalProperties": { "type": "string" }          },          "notes": { "type": "string" }        }      },      "minItems": 1    },    "sources": {      "type": "array",      "items": { "type": "string", "pattern": "^src:" },      "minItems": 1    },    "tags": {      "type": "array",      "items": { "type": "string" }    }  }}

7. conversion-rule.schema.json(声明式规则,可选)

json

{  "$schema": "https://json-schema.org/draft/2020-12/schema",  "$id": "https://omnichronos.org/schemas/conversion-rule.schema.json",  "title": "Conversion Rule",  "description": "Declarative rules for simple arithmetic calendars to reduce code dependency.",  "type": "object",  "required": ["id", "calendar_ref", "rules"],  "additionalProperties": false,  "properties": {    "id": {      "type": "string",      "pattern": "^[a-z0-9][a-z0-9_-]*$"    },    "calendar_ref": { "type": "string" },    "rules": {      "type": "object",      "description": "Key-value rules, e.g. leap_year_cycle, month_lengths, epoch_offset"    },    "notes": { "type": "string" }  }}

使用说明

  1. 所有数据文件必须通过对应 Schema 验证(CI 强制)。
  2. $ref 使用相对或绝对 URI,实际项目中可用本地文件引用。
  3. names 强制多语言支持(至少一种语言)。
  4. sources 强制至少一条文献来源。
  5. jd_mappable 是强制字段,明确处理非 JD 情况。
  6. temporal-expression 是整个系统的灵活性核心。

附:OpenChronology 插件接口定义(Plugin Interface Specification)

以下是正式的插件接口草案(v0.1)。设计目标是:

  • 语言无关(可用任何语言实现,推荐提供 WebAssembly 版本)
  • 统一以 TemporalID 作为中间表示
  • 同时支持可完全映射到 JD 的历法和不能完全映射的历法
  • 清晰、最小化、易测试

1. 核心概念

TemporalID
统一的中间时间标识,优先使用儒略日,但允许更灵活的形式。

ts

type TemporalID = {  // 优先使用  jd?: number;                    // Julian Day Number(可带小数表示时刻)  rd?: number;                    // Rata Die(可选)
  // 非 JD 或补充信息  local_id?: string;              // 本地时间线标识  expression?: object;            // 完整的 temporal-expression  confidence?: number;            // 0–1  notes?: string;}

CalendarDate
某个具体历法下的日期表示(结构由该历法自己定义,通常是对象)。

ts

type CalendarDate = {  [key: string]: number | string | boolean | null;  // 例如:  // { year: 2026, month: 10, day: 8 }  // { cycle: 78, year: 3, month: 5, leap: false, day: 12 }}

2. 插件必须实现的接口

每个插件必须实现以下方法(名称可因语言惯例略有调整,但语义必须一致):

2.1 元信息

ts

getInfo(): PluginInfo

返回:

ts

interface PluginInfo {  id: string;                     // 插件唯一 ID,例如 "gregorian"  name: string;                   // 人类可读名称  version: string;                // 语义化版本  calendars: string[];            // 此插件支持的 calendar id 列表  jd_mappable: "true" | "false" | "partial";  description?: string;  author?: string;  license?: string;}

2.2 核心转换方法

ts

toTemporal(date: CalendarDate, calendarId: string): TemporalID

把指定历法的日期转换为 TemporalID。

ts

fromTemporal(temporal: TemporalID, calendarId: string): CalendarDate

把 TemporalID 转换为目标历法的日期。

2.3 验证

ts

validate(date: CalendarDate, calendarId: string): ValidationResult

ts

interface ValidationResult {  valid: boolean;  errors?: string[];              // 人类可读错误信息}

2.4 组件与元数据(推荐实现)

ts

getComponents(calendarId: string): string[]// 返回该历法使用的字段列表,例如 ["year", "month", "day", "leap"]
getMonthLengths?(year: number, calendarId: string): number[]isLeap?(year: number, calendarId: string): boolean

3. 错误处理约定

  • 转换失败或输入非法时,应抛出明确的错误(或返回 Result 类型)。
  • 推荐错误类型:
    • InvalidDateError
    • UnsupportedCalendarError
    • NonMappableError(当要求精确 JD 但无法提供时)
    • OutOfRangeError

4. 插件清单文件(manifest.json)

每个插件目录下必须包含 manifest.json:

json

{  "id": "gregorian",  "name": "Gregorian Calendar Plugin",  "version": "1.0.0",  "calendars": ["gregorian", "proleptic-gregorian"],  "jd_mappable": "true",  "languages": ["python", "wasm", "typescript"],  "entry_points": {    "python": "gregorian.py:GregorianPlugin",    "wasm": "gregorian.wasm",    "typescript": "dist/index.js"  },  "dependencies": [],  "description": "Standard proleptic Gregorian calendar implementation"}

5. 推荐实现优先级

  1. Python 参考实现(易读、方便测试)
  2. WebAssembly 版本(实现真正的语言无关)
  3. TypeScript / JavaScript
  4. 其他语言绑定(Rust、Go、C 等)

6. 接口使用示例(伪代码)

python

plugin = load_plugin("gregorian")
# 公历 → TemporalIDtemporal = plugin.to_temporal(    {"year": 2026, "month": 10, "day": 8},    "gregorian")print(temporal.jd)        # 2460960.5 之类
# TemporalID → 目标历法hebrew_date = plugin.from_temporal(temporal, "hebrew")

7. 扩展点(可选但鼓励)

插件可以额外实现:

  • add_duration(date, duration, calendarId)
  • diff(date1, date2, calendarId)
  • holidays(year, calendarId)
  • format(date, locale, calendarId)

这些不属于核心接口,但会提升实用性。

8. 版本与兼容性

  • 接口本身使用语义化版本(当前为 0.1.0)。
  • 破坏性变更会提升主版本号。
  • 插件应声明自己兼容的接口版本。

附:X.包容争议、兼容冲突:项目的核心价值与最低目标

X.1 核心立场

OpenChronology 不追求建立唯一正确的全球时间线,也不试图裁决历史争议。

本项目的最大价值,在于系统性地包容争议、兼容冲突。

同一事件、同一历法、同一纪年在不同文献、不同语言、不同学术传统中常常存在互相矛盾的记载。我们选择把这些矛盾本身作为一等公民进行结构化保存,而不是强行消解它们。

项目明确拒绝“唯一权威时间”的幻想,转而提供一个可计算、可比较、可溯源的多视角时间知识层。

X.2 最低可执行目标

在追求长远愿景的同时,项目设定清晰的最低目标:

至少把维基百科(多语言版本)和 Anna’s Archive 等大型资料库中出现的时间相关信息,进行结构化标注与关联。

具体包括但不限于:

  • 人物生卒年
  • 在位/执政时间
  • 事件发生日期
  • 历法改革与切换点
  • 年号起止
  • 文献自身使用的纪年方式
  • 不同来源对同一时间点的冲突记载

这一目标将“穷尽全世界文献”的宏大愿景,落实为可验证、可分阶段推进的工程任务。

X.3 设计原则(针对争议与冲突)

  1. 多假说并存
    任何时间表达都允许存在多个互相竞争的 claims,每个 claim 必须绑定来源与置信度。
  2. 冲突显式化
    数据模型必须能明确标记“这些说法存在冲突”,而不是静默覆盖或取平均值。
  3. 来源至上
    所有时间信息都必须可追溯至具体来源(维基页面、书籍、论文、铭文等)。没有来源的数据不予收录。
  4. 降级而非拒绝
    当无法可靠映射到儒略日时,系统支持相对、区间、文学性、循环性表达,而不是强制放弃。
  5. 中立记录
    项目本身不站队。用户可根据自己的需求选择采信哪些来源或哪些假说。

X.4 对数据模型的直接影响

  • temporal-expression 升级为支持 claims 数组与 conflicts 标志。
  • 所有日历、纪年、事件条目均预留多来源字段。
  • 新增“来源冲突报告”机制,方便后续研究与可视化。
  • 非 JD 体系与争议时间线享有与精确 JD 时间线同等的一等公民地位。

X.5 实施优先级(基于本立场)

  1. 完善支持多 claims 与冲突标记的 Schema。
  2. 建立维基百科时间信息抽取与人工校验流水线。
  3. 探索 Anna’s Archive 等大型书库中时间元数据的合法、可行提取方式。
  4. 在此基础上再扩展其他文献来源与计算插件。

X.6 成功标准(阶段性)

  • 能系统记录并展示同一时间点的多种冲突说法。
  • 维基百科主要命名空间中的时间信息得到较高覆盖的结构化标注。
  • 用户可以清晰看到“这个日期在不同来源中是如何被记载的”,而不是只得到一个被清洗过的单一结果。

本章总结
OpenChronology 的独特价值不在于提供“正确答案”,而在于诚实、结构化地保存人类记录时间时产生的所有矛盾与多样性。把维基百科与 Anna’s Archive 等大型资料库中的时间信息优先标注出来,是实现这一价值的最务实起点。

备注:初定名OmniChronos调整为OpenChronology,代码中的域暂未更新。

如何识别ai生成的视频

一、视觉层面的AI痕迹(技术识别)

特征说明如何检测
1. 画面局部不连贯(帧间抖动)扩散模型是逐帧生成,缺乏全局物理建模,物体形状/位置在相邻帧轻微变形播放慢速(0.25x)或逐帧翻看,观察手、脸、头发、背景物体的微小闪烁/变形
2. 手指/面部畸变CLIP引导的图像生成对手部、牙齿、眼睛建模差放大看手(常多指/少指/融合)、脸部表情僵硬、牙齿不齐
3. 文字渲染错误AI很难生成正确文字(尤其是中文)视频中出现标牌、书、屏幕 → 文字模糊、乱码、拼写错误
4. 光影不一致光源方向、强度、反射不统一观察多个物体的阴影方向是否矛盾
5. 背景与前景融合异常自动配图常“硬贴”,深度感错误人物与背景边缘生硬,或人物“浮”在背景上
6. 运动轨迹不自然缺少真实物理惯性物体移动路径突兀、速度不匀、没有预期加速度

二、内容逻辑层面的AI痕迹(语义识别)

特征说明如何检测
1. 画面与文本“似是而非”关键词命中,但细节错位文本说“老人坐在公园长椅上看书”,画面却是“年轻人站在操场拿书”
2. 叙事缺乏因果镜头切换无逻辑上一秒下雨,下一秒晴天无过渡;人突然换衣服
3. 重复动作/静态感扩散模型倾向生成“循环小动作”人物反复点头、眨眼、手微动,像“活照片”
4. 缺乏交互细节真实视频有微交互(风吹头发、手扶物体)AI视频中头发静止、衣服无褶皱反应

三、技术检测方法(可自动化)1. 频域分析(FFT / 高频噪声)

  • 真实视频:压缩噪声、自然纹理
  • AI视频:高频噪声模式异常(扩散模型残留的“网格状”或“云雾状”噪声)
  • 工具:用Python + OpenCV做FFT,观察频谱图是否有规则条带

python

import cv2
import numpy as np
import matplotlib.pyplot as plt

frame = cv2.imread("frame.jpg", 0)
f = np.fft.fft2(frame)
fshift = np.fft.shift(f)
magnitude = 20 * np.log(np.abs(fshift))

# AI视频常有“环形”或“网格”高频 artifact

2. CLIP语义一致性检测

  • 提取每帧图像,用CLIP计算图像-文本相似度
  • 真实视频:相似度波动小且高
  • AI视频:相似度高但分布异常(局部匹配,整体不连贯)

python

# 伪代码
for frame in video:
    sim = clip_similarity(frame, prompt)
    if sim < 0.6 or 剧烈波动: → 疑似AI

3. 光学流(Optical Flow)分析

  • 计算相邻帧像素运动向量
  • AI视频:运动场不连续,有“跳跃”或“噪声块”
  • 工具:RAFT、FlowNet2

4. 元数据与编码分析

  • 检查视频编码器:AI工具常输出固定码率、特定容器(如WebM/VP9)
  • 缺少相机EXIF、镜头畸变、传感器噪声

四、实用识别流程(人工+工具结合)

1. 慢放视频 → 看手、脸、文字、光影
2. 截帧放大 → 找手指畸变、文字乱码
3. 看运动 → 是否有物理惯性?风吹反应?
4. 对比文本 → 画面是否“只沾边”?
5. 用工具:
   - https://hive.moderation.com/ (AI内容检测API)
   - https://illuminarty.ai/ (免费检测)
   - 本地跑CLIP + 光学流脚本

五、当前最强AI视频也难逃的弱点(2025年)

模型仍存在的破绽
Sora / Runway Gen-3复杂交互(多人握手、物体传递)失败
Luma Dream Machine文字几乎全错
Pika 1.5背景穿模严重

只要不是电影级特效,99%的“文本+配图”视频都能被识破。


总结:识别口诀(5秒判断法)

“手乱、字花、光不对、动不真、意不准”

  • 手乱 → 手指畸形
  • 字花 → 文字模糊/错
  • 光不对 → 阴影矛盾
  • 动不真 → 物理假
  • 意不准 → 画面不贴文本

只要满足3条以上,基本可判定为 AI生成。

Langfuse 与 Agenta 的详细比较

Langfuse 和 Agenta 都是专注于 LLM(大型语言模型)应用的工具平台,但它们的核心定位略有不同。Langfuse 是一个开源的 LLM 可观测性(observability)平台,主要强调跟踪、调试和监控 LLM 应用及代理的运行时行为,帮助开发者快速识别问题并优化性能。Agenta 则是一个更全面的 LLMOps 平台,侧重于提示工程(prompt engineering)、评估和端到端应用构建,支持从开发到生产的完整生命周期管理。两者都支持自托管,并适用于构建 AI 应用的工程师和团队,但 Langfuse 更偏向于后端监控,而 Agenta 更注重前端实验和协作。以下是从多个维度进行的详细比较,基于官方文档和第三方评测。比较数据来源于 2025 年的最新信息。1. 核心功能比较两者都提供可观测性和评估,但 Agenta 在提示管理和协作上更强,Langfuse 在跟踪深度上更胜一筹。

维度LangfuseAgenta
跟踪与可观测性核心功能:自动捕获 LLM 应用的完整 traces(跟踪),支持嵌套调用链接、延迟/成本指标可视化。基于 OpenTelemetry,支持代理图(agent graphs)。 langfuse.com提供 traces 和调试工具,用于根因分析、边缘案例识别和金标准数据集 curation。监控使用量和质量。 agenta.ai
提示管理支持提示版本管理和实验,但非核心;通过 SDK 集成 OpenAI 等 wrapper。 langfuse.com强项:Prompt Registry 支持版本控制、输出跟踪、生产部署和回滚;Playground 允许跨场景比较 prompts 和模型。 agenta.ai
评估与实验Evals 功能用于构建评估数据集和失败分析;支持指标计算。 langfuse.com系统评估工具,从 UI 运行评估;洞察变化对输出质量的影响;支持非代码用户实验。 agenta.ai
其他独特功能用户活动时间线、LLM 代理集成(如 LlamaIndex);开源优先,自定义性强。 research.aimultiple.com团队协作优化、工作流简化;支持自定义 playground 和自托管。 deepchecks.com

2. 定价与部署模式Langfuse 更注重免费开源,自托管门槛低;Agenta 的定价更灵活,但入门门槛可能更高(来源间有轻微差异,可能因更新)。

维度LangfuseAgenta
免费/开源选项完全开源,自托管免费,无限数据和功能限制。 langfuse.com支持自托管(FAQ 确认),Hobby 计划免费。 f6s.com
云版定价– Core:免费(含 100k units/月,额外 $8/100k units)。 – Hobby/Team:$0-29/月。 – Production:使用量计费($49/月起)。 – Enterprise:自定义。 langfuse.com +1– Hobby:$0/月。 – Pro:$49/月。 – Enterprise:自定义(需求为基础)。 部分来源显示起步 $399/月,可能为团队版。 agenta.ai +1
计费单位基于 traces/units(输入/输出 token),卷积折扣。 langfuse.com基于使用量、团队规模和支持级别。 agenta.ai
试用/限制免费层支持小规模实验,无限自托管。 blog.promptlayer.com免费 Hobby 计划支持入门;企业版提供试用。 f6s.com

3. 目标受众与用例

  • Langfuse:适合独立开发者或工程团队,专注于 LLM 应用的调试和监控。用例包括:代理系统故障诊断、性能优化、构建 eval 数据集。特别适用于开源爱好者和自托管场景。 langfuse.com
  • Agenta:针对产品和工程团队,强调协作和快速迭代。用例包括:提示实验、团队提示部署、生产 LLM app 构建。适合非纯代码用户(如提示专家)参与。 aiagentsdirectory.com +1

4. 集成与生态

  • Langfuse:强集成支持,包括 OpenAI wrapper、LlamaIndex、Python/JS SDK;兼容 OpenTelemetry,便于与其他监控工具结合。 langfuse.com +1
  • Agenta:集成细节较少公开,但支持 LLM 库的提示注入;强调与现有工作流的兼容(如 GitHub、Slack 社区支持)。 agenta.ai

5. 优缺点与适用场景

  • Langfuse 的优势:开源免费门槛低,跟踪深度强,适合技术驱动的监控需求。缺点:提示管理和 UI 协作不如 Agenta 直观。 agenta.ai
  • Agenta 的优势:端到端 LLMOps 更完整,支持 UI 驱动的实验和团队协作,加速从原型到生产。缺点:定价可能更高,集成文档较少。 agenta.ai +1
  • 选择建议:
    • 如果您需要纯监控和调试,选择 Langfuse(尤其是自托管)。
    • 如果焦点是提示工程和团队开发,选择 Agenta。
    • 两者可互补:用 Langfuse 监控,用 Agenta 构建。 agenta.ai

总体而言,在 2025 年的 LLM 工具生态中,Langfuse 以开源可观测性领先,而 Agenta 在 LLMOps 完整性上更具竞争力。

by: Grok4

截至目前最好用的語音轉文字方案依然是aadnk/faster-whisper-webui

地址:https://huggingface.co/spaces/aadnk/faster-whisper-webui

對比了幾個更新一點的方案,有的增加了隊列和資源可視化,但是效率比較低,尤其是沒有優化顯存佔用,比如https://github.com/jhj0517/Whisper-WebUI,使用v3模型時需要25G顯存,我的3090還跑不起來了,而且並不支持詞級標註。

爲了更方便的使用aadnk/faster-whisper-webui,可以在其文件目錄中增加一個docker-compose.yml

services:
  faster-whisper:
    image: registry.gitlab.com/aadnk/whisper-webui:latest
    container_name: faster-whisper
    deploy:
      resources:
        reservations:
          devices:
            - capabilities: [gpu]
    ports:
      - "7001:7860"
    volumes:
      - ./cache/whisper:/root/.cache/whisper
      - ./cache/huggingface:/root/.cache/huggingface
    restart: on-failure:15
    environment:
      - HTTP_PROXY=http://192.168.1.200:16236
      - HTTPS_PROXY=http://192.168.1.200:16236
      - NO_PROXY=localhost,127.0.0.1,::1
    command: >
      app.py
      --whisper_implementation whisper
      --input_audio_max_duration -1
      --server_name 0.0.0.0
      --auto_parallel True
      --default_vad silero-vad
      --default_model_name large-v2

注意其中的large-v2也可以改爲large-v3,最新版已經支持。另外,HTTP_PROXY相關設置是爲了啓動時通過代理訪問gradio,否則會啓動失敗,通過environment來設置代理的方式比較靈活,不會影響其他docker容器,詳細情況參加我前面一篇博客。

用Caddy部署wordpress

年前把公司网站的服务器换到了caddy上,今天想写一篇博客,发现证书过期了,之前用了certbot但是配置自动任务还是比较麻烦的,尤其是用了docker。索性一起换掉。

docker-compose.yml中的配置如下:

  caddy:
    image: registry.cn-beijing.aliyuncs.com/futuremeng/caddy:1.1
    container_name: caddy
    restart: unless-stopped
    environment:
      - TZ=Asia/Shanghai
    volumes:
      - ./services/caddy/config:/config
      - ${DATA_DIR}/caddy:/data
      - ${SOURCE_DIR}:/www/:rw
      - ${LOGS_DIR}/caddy:/var/log/caddy
    ports:
      - "80:80"
      - "443:443"
    networks:
      - default

其中的env变量请自行脑补。

caddyfile:

https://WordPress.com {
        root * /www/WordPress
        php_fastcgi php80:9000 {
                trusted_proxies private_ranges
        }
        file_server
        encode gzip
        @disallowed {
                path /xmlrpc.php
                path *.sql
                path /wp-content/uploads/*.php
        }
        rewrite @disallowed '/index.php'
}

详情可见:

https://github.com/futuremeng/dnmp

Inkscape是一个免费开源的矢量图形编辑软件

Inkscape是什么?

Inkscape是一个免费开源的矢量图形编辑软件,它适用于GUN/Linux,Windows或MacOS X系统平台。Inkscape提供了一套丰富的功能,被广泛用于艺术和技术插图中,例如:卡通,剪贴画,logo,排版,图表和流程图。不同于像素图,Inkscape使用的是矢量图,因此并不会被固定的像素所限制的,从而可以得到无限尺度清晰的打印输出和渲染。Inkscape使用标准化的SVG格式作为其主要文件格式(许多应用都支持SVG格式,包括网页浏览器)。

Inkscape支持导入和导出多种文件格式,包括SVG,AI,EPS,PDF,PS和 PNG。它有着全面的功能、简单的界面,支持多种语言并被设计为可扩展的;用户可以用附加组件定制自己的Inkscape的功能。

Inkscape项目有着不断增长的全球性用户社区。有许多学习资料 可以帮助你开始自己的创作。帮助和支持是由社区提供的,如果你想帮助Inkscape项目变得更好,这里有许多方式可以供你参与进来 。

Inkscape是Software Freedom Conservancy(一个 美国501(c)(3)非盈利组织)中的一员。在美国,对Inkscape的贡献可以免税。

谁创造了Inkscape?

Inkscape是由许多作者共同创造的,每个作者都保留自己的版权,这些作者们也同样地参与了Inkscape技术和项目目标的设定。此外,还有许多非编程类的贡献者,他们也是Inkscape项目的重要一部分。

如果你想提及Inkscape的创作者或组织,你可以分别用 “Inkscape的贡献者们”和”Inkscape项目” 来区分Inkscape项目和Inkscape软件。

https://inkscape.org/zh-hans/simplified-chinese-about/

创维VT-E03安装泰捷视频电视版应用App方法

到泰捷www.togic.com下载应用存到U盘或移动硬盘,然后插到盒子上;

打开设置,应用程序,屏幕右上角有三个点,按遥控上的鼠标,移动上去按确定,可以看到安装应用的菜单,到移动硬盘或优盘相应位置找到apk文件,点确定安装即可。

20140415-222526.jpg

基于TeamSNS的猎头团队协作系统

TeamSNS是一个轻型的团队协作工具,基于PHP语言和sqlite数据库,配置方便,界面简洁,操作方便。在此基于TeamSNS开了一个猎头团队协作系统,以供使用者参考。TeamSNS的开发者页面http://ftqq.com/teamsns/

1. 团队成员由管理员进行设置;

2. 每个求职者作为一个项目进行管理,添加新项目:

继续阅读“基于TeamSNS的猎头团队协作系统”

信任是最大的优势:大谷打工网的虚假招聘信息识别系统

大谷打工网是经一位美国朋友介绍的,由于发音的问题,我一直以为是大姑网。

大谷打工网的口号是“在家靠父母,打工靠大谷”,要的就是一个信任,这种感觉是现在这个社会最缺失的,也是最有意义的,正如郎咸平一直在讲发达社会最有价值的就是信托责任。 继续阅读“信任是最大的优势:大谷打工网的虚假招聘信息识别系统”