{
  "canonical_name": "vostride/id-agent",
  "compilation_id": "pack_c0e6ec4637d74225adc0967eb05c2eaf",
  "created_at": "2026-05-19T13:58:52.301485+00:00",
  "created_by": "project-pack-compiler",
  "feedback": {
    "carrier_selection_notes": [
      "viable_asset_types=skill, recipe, host_instruction, eval, preflight",
      "recommended_asset_types=skill, recipe, host_instruction, eval, preflight"
    ],
    "evidence_delta": {
      "confirmed_claims": [
        "identity_anchor_present",
        "capability_and_host_targets_present",
        "install_path_declared_or_better"
      ],
      "missing_required_fields": [],
      "must_verify_forwarded": [
        "Run or inspect `npm install id-agent` in an isolated environment.",
        "Confirm the project exposes the claimed capability to at least one target host."
      ],
      "quickstart_execution_scope": "allowlisted_sandbox_smoke",
      "sandbox_command": "npm install id-agent",
      "sandbox_container_image": "node:22-slim",
      "sandbox_execution_backend": "docker",
      "sandbox_planner_decision": "llm_execute_isolated_install",
      "sandbox_validation_id": "sbx_0cec860cd1894c9287f52c4a2dc503b5"
    },
    "feedback_event_type": "project_pack_compilation_feedback",
    "learning_candidate_reasons": [],
    "template_gaps": []
  },
  "identity": {
    "canonical_id": "project_80ddc2f48c02469668f26c1051abebbe",
    "canonical_name": "vostride/id-agent",
    "homepage_url": null,
    "license": "unknown",
    "repo_url": "https://github.com/vostride/id-agent",
    "slug": "id-agent",
    "source_packet_id": "phit_687f60efbb2247689a5fb53b0252ea33",
    "source_validation_id": "dval_2a0852d5fef348169093f1e032291cfc"
  },
  "merchandising": {
    "best_for": "需要软件开发与交付能力，并使用 local_cli的用户",
    "github_forks": null,
    "github_stars": null,
    "one_liner_en": "<p align=\"center\">",
    "one_liner_zh": "<p align=\"center\">",
    "primary_category": {
      "category_id": "software-development",
      "confidence": "medium",
      "name_en": "Software Development",
      "name_zh": "软件开发与交付",
      "reason": "matched_keywords:git, cli"
    },
    "target_user": "使用 local_cli 等宿主 AI 的用户",
    "title_en": "id-agent",
    "title_zh": "id-agent 能力包",
    "visible_tags": [
      {
        "label_en": "Browser Agents",
        "label_zh": "浏览器 Agent",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "product_domain-browser-agents",
        "type": "product_domain"
      },
      {
        "label_en": "Web Task Automation",
        "label_zh": "网页任务自动化",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "user_job-web-task-automation",
        "type": "user_job"
      },
      {
        "label_en": "Browser Automation",
        "label_zh": "浏览器自动化",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "core_capability-browser-automation",
        "type": "core_capability"
      },
      {
        "label_en": "Node-based Workflow",
        "label_zh": "节点式流程编排",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "workflow_pattern-node-based-workflow",
        "type": "workflow_pattern"
      },
      {
        "label_en": "Agent-controlled Browser",
        "label_zh": "Agent 控制浏览器",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "selection_signal-agent-controlled-browser",
        "type": "selection_signal"
      }
    ]
  },
  "packet_id": "phit_687f60efbb2247689a5fb53b0252ea33",
  "page_model": {
    "artifacts": {
      "artifact_slug": "id-agent",
      "files": [
        "PROJECT_PACK.json",
        "QUICK_START.md",
        "PROMPT_PREVIEW.md",
        "HUMAN_MANUAL.md",
        "AI_CONTEXT_PACK.md",
        "BOUNDARY_RISK_CARD.md",
        "PITFALL_LOG.md",
        "REPO_INSPECTION.json",
        "REPO_INSPECTION.md",
        "CAPABILITY_CONTRACT.json",
        "EVIDENCE_INDEX.json",
        "CLAIM_GRAPH.json"
      ],
      "required_files": [
        "PROJECT_PACK.json",
        "QUICK_START.md",
        "PROMPT_PREVIEW.md",
        "HUMAN_MANUAL.md",
        "AI_CONTEXT_PACK.md",
        "BOUNDARY_RISK_CARD.md",
        "PITFALL_LOG.md",
        "REPO_INSPECTION.json"
      ]
    },
    "detail": {
      "capability_source": "Project Hit Packet + DownstreamValidationResult",
      "commands": [
        {
          "command": "npm install id-agent",
          "label": "Node.js / npm · 官方安装入口",
          "source": "https://github.com/vostride/id-agent#readme",
          "verified": true
        }
      ],
      "display_tags": [
        "浏览器 Agent",
        "网页任务自动化",
        "浏览器自动化",
        "节点式流程编排",
        "Agent 控制浏览器"
      ],
      "eyebrow": "软件开发与交付",
      "glance": [
        {
          "body": "判断自己是不是目标用户。",
          "label": "最适合谁",
          "value": "需要软件开发与交付能力，并使用 local_cli的用户"
        },
        {
          "body": "先理解能力边界，再决定是否继续。",
          "label": "核心价值",
          "value": "<p align=\"center\">"
        },
        {
          "body": "未完成验证前保持审慎。",
          "label": "继续前",
          "value": "publish to Doramagic.ai project surfaces"
        }
      ],
      "guardrail_source": "Boundary & Risk Card",
      "guardrails": [
        {
          "body": "Prompt Preview 只展示流程，不证明项目已安装或运行。",
          "label": "Check 1",
          "value": "不要把试用当真实运行"
        },
        {
          "body": "local_cli",
          "label": "Check 2",
          "value": "确认宿主兼容"
        },
        {
          "body": "publish to Doramagic.ai project surfaces",
          "label": "Check 3",
          "value": "先隔离验证"
        }
      ],
      "mode": "skill, recipe, host_instruction, eval, preflight",
      "pitfall_log": {
        "items": [
          {
            "body": "README/documentation is current enough for a first validation pass.",
            "category": "能力坑",
            "evidence": [
              "capability.assumptions | hn_item:48191852 | https://news.ycombinator.com/item?id=48191852 | README/documentation is current enough for a first validation pass."
            ],
            "severity": "medium",
            "suggested_check": "将假设转成下游验证清单。",
            "title": "能力判断依赖假设",
            "user_impact": "假设不成立时，用户拿不到承诺的能力。"
          },
          {
            "body": "未记录 last_activity_observed。",
            "category": "维护坑",
            "evidence": [
              "evidence.maintainer_signals | hn_item:48191852 | https://news.ycombinator.com/item?id=48191852 | last_activity_observed missing"
            ],
            "severity": "medium",
            "suggested_check": "补 GitHub 最近 commit、release、issue/PR 响应信号。",
            "title": "维护活跃度未知",
            "user_impact": "新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。"
          },
          {
            "body": "no_demo",
            "category": "安全/权限坑",
            "evidence": [
              "downstream_validation.risk_items | hn_item:48191852 | https://news.ycombinator.com/item?id=48191852 | no_demo; severity=medium"
            ],
            "severity": "medium",
            "suggested_check": "进入安全/权限治理复核队列。",
            "title": "下游验证发现风险项",
            "user_impact": "下游已经要求复核，不能在页面中弱化。"
          },
          {
            "body": "no_demo",
            "category": "安全/权限坑",
            "evidence": [
              "risks.scoring_risks | hn_item:48191852 | https://news.ycombinator.com/item?id=48191852 | no_demo; severity=medium"
            ],
            "severity": "medium",
            "suggested_check": "把风险写入边界卡，并确认是否需要人工复核。",
            "title": "存在评分风险",
            "user_impact": "风险会影响是否适合普通用户安装。"
          },
          {
            "body": "GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：Consider an alternative wordlist",
            "category": "安全/权限坑",
            "evidence": [
              "community_evidence:github | cevd_c1936412c9da41088e71fab995197a90 | https://github.com/vostride/id-agent/issues/2 | 来源类型 github_issue 暴露的待验证使用条件。"
            ],
            "severity": "medium",
            "suggested_check": "来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。",
            "title": "来源证据：Consider an alternative wordlist",
            "user_impact": "可能影响授权、密钥配置或安全边界。"
          },
          {
            "body": "GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：Python port",
            "category": "安全/权限坑",
            "evidence": [
              "community_evidence:github | cevd_d733a90c7db44b9789900ed24e77220e | https://github.com/vostride/id-agent/issues/1 | 来源讨论提到 python 相关条件，需在安装/试用前复核。"
            ],
            "severity": "medium",
            "suggested_check": "来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。",
            "title": "来源证据：Python port",
            "user_impact": "可能影响授权、密钥配置或安全边界。"
          },
          {
            "body": "issue_or_pr_quality=unknown。",
            "category": "维护坑",
            "evidence": [
              "evidence.maintainer_signals | hn_item:48191852 | https://news.ycombinator.com/item?id=48191852 | issue_or_pr_quality=unknown"
            ],
            "severity": "low",
            "suggested_check": "抽样最近 issue/PR，判断是否长期无人处理。",
            "title": "issue/PR 响应质量未知",
            "user_impact": "用户无法判断遇到问题后是否有人维护。"
          },
          {
            "body": "release_recency=unknown。",
            "category": "维护坑",
            "evidence": [
              "evidence.maintainer_signals | hn_item:48191852 | https://news.ycombinator.com/item?id=48191852 | release_recency=unknown"
            ],
            "severity": "low",
            "suggested_check": "确认最近 release/tag 和 README 安装命令是否一致。",
            "title": "发布节奏不明确",
            "user_impact": "安装命令和文档可能落后于代码，用户踩坑概率升高。"
          }
        ],
        "source": "ProjectPitfallLog + ProjectHitPacket + validation + community signals",
        "summary": "发现 8 个潜在踩坑项，其中 0 个为 high/blocking；最高优先级：能力坑 - 能力判断依赖假设。",
        "title": "踩坑日志"
      },
      "snapshot": {
        "contributors": null,
        "forks": null,
        "license": "unknown",
        "note": "站点快照，非实时质量证明；用于开工前背景判断。",
        "stars": null
      },
      "source_url": "https://github.com/vostride/id-agent",
      "steps": [
        {
          "body": "不安装项目，先体验能力节奏。",
          "code": "preview",
          "title": "先试 Prompt"
        },
        {
          "body": "理解输入、输出、失败模式和边界。",
          "code": "manual",
          "title": "读说明书"
        },
        {
          "body": "把上下文交给宿主 AI 继续工作。",
          "code": "context",
          "title": "带给 AI"
        },
        {
          "body": "进入主力环境前先完成安装入口与风险边界验证。",
          "code": "verify",
          "title": "沙箱验证"
        }
      ],
      "subtitle": "<p align=\"center\">",
      "title": "id-agent 能力包",
      "trial_prompt": "# id-agent - Prompt Preview\n\n> 复制下面这段 Prompt 到你常用的 AI，先试一次，不需要安装。\n> 它的目标是让你直接体验这个项目的服务方式，而不是阅读项目介绍。\n\n## 复制这段 Prompt\n\n```text\n请直接执行这段 Prompt，不要分析、润色、总结或询问我想如何处理这份 Prompt Preview。\n\n你现在扮演 id-agent 的“安装前体验版”。\n这不是项目介绍、不是评价报告、不是 README 总结。你的任务是让我用最小成本体验它的核心服务。\n\n我的试用任务：我想用它完成一个真实的软件开发与交付任务。\n我常用的宿主 AI：Local CLI\n\n【体验目标】\n围绕我的真实任务，现场演示这个项目如何把输入转成 示例引导, 判断线索。重点是让我感受到工作方式，而不是给我项目背景。\n\n【业务流约束】\n- 你必须像一个正在提供服务的项目能力包，而不是像一个讲解员。\n- 每一轮只推进一个步骤；提出问题后必须停下来等我回答。\n- 每一步都必须让我感受到一个具体服务动作：澄清、整理、规划、检查、判断或收尾。\n- 每一步都要说明：当前目标、你需要我提供什么、我回答后你会产出什么。\n- 不要安装、不要运行命令、不要写代码、不要声称测试通过、不要声称已经修改文件。\n- 需要真实安装或宿主加载后才能验证的内容，必须明确说“这一步需要安装后验证”。\n- 如果我说“用示例继续”，你可以用虚构示例推进，但仍然不能声称真实执行。\n\n【可体验服务能力】\n- 安装前能力预览: <p align=\"center\"> 输入：用户任务, 当前 AI 对话上下文；输出：示例引导, 判断线索。\n\n【必须安装后才可验证的能力】\n- 命令行启动或安装流程: 项目文档中存在可执行命令，真实使用需要在本地或宿主环境中运行这些命令。 输入：终端环境, 包管理器, 项目依赖；输出：安装结果, 列表/更新/运行结果。\n\n【核心服务流】\n请严格按这个顺序带我体验。不要一次性输出完整流程：\n1. page-introduction：项目介绍。围绕“项目介绍”模拟一次用户任务，不展示安装或运行结果。\n2. page-installation：安装与快速开始。围绕“安装与快速开始”模拟一次用户任务，不展示安装或运行结果。\n3. page-id-generation：随机 ID 生成。围绕“随机 ID 生成”模拟一次用户任务，不展示安装或运行结果。\n4. page-deterministic-ids：确定性 ID 生成。围绕“确定性 ID 生成”模拟一次用户任务，不展示安装或运行结果。\n5. page-wordlist-design：词表设计。围绕“词表设计”模拟一次用户任务，不展示安装或运行结果。\n\n【核心能力体验剧本】\n每一步都必须按“输入 -> 服务动作 -> 中间产物”执行。不要只说流程名：\n1. page-introduction\n输入：用户提供的“项目介绍”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n2. page-installation\n输入：用户提供的“安装与快速开始”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n3. page-id-generation\n输入：用户提供的“随机 ID 生成”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n4. page-deterministic-ids\n输入：用户提供的“确定性 ID 生成”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n5. page-wordlist-design\n输入：用户提供的“词表设计”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n【项目服务规则】\n这些规则决定你如何服务用户。不要解释规则本身，而要在每一步执行时遵守：\n- 先确认用户任务、输入材料和成功标准，再模拟项目能力。\n- 每一步都必须形成可检查的小产物，并等待用户确认后再继续。\n- 凡是需要安装、调用工具或访问外部服务的能力，都必须标记为安装后验证。\n\n【每一步的服务约束】\n- Step 1 / page-introduction：Step 1 必须围绕“项目介绍”形成一个小中间产物，并等待用户确认。\n- Step 2 / page-installation：Step 2 必须围绕“安装与快速开始”形成一个小中间产物，并等待用户确认。\n- Step 3 / page-id-generation：Step 3 必须围绕“随机 ID 生成”形成一个小中间产物，并等待用户确认。\n- Step 4 / page-deterministic-ids：Step 4 必须围绕“确定性 ID 生成”形成一个小中间产物，并等待用户确认。\n- Step 5 / page-wordlist-design：Step 5 必须围绕“词表设计”形成一个小中间产物，并等待用户确认。\n\n【边界与风险】\n- 不要声称已经安装、运行、调用 API、读写本地文件或完成真实任务。\n- 安装前预览只能展示工作方式，不能证明兼容性、性能或输出质量。\n- 涉及安装、插件加载、工具调用或外部服务的能力必须安装后验证。\n\n【可追溯依据】\n这些路径只用于你内部校验或在我追问“依据是什么”时简要引用。不要在首次回复主动展开：\n- https://news.ycombinator.com/item?id=48191852\n- https://github.com/vostride/id-agent#readme\n- README.md\n- src/index.ts\n- package.json\n- src/generate.ts\n- src/types.ts\n- src/schemas.ts\n- src/deterministic.ts\n- src/crypto.ts\n- src/wordlist.ts\n- scripts/validate-wordlist.ts\n\n【首次问题规则】\n- 首次三问必须先确认用户目标、成功标准和边界，不要提前进入工具、安装或实现细节。\n- 如果后续需要技术条件、文件路径或运行环境，必须等用户确认目标后再追问。\n\n首次回复必须只输出下面 4 个部分：\n1. 体验开始：用 1 句话说明你将带我体验 id-agent 的核心服务。\n2. 当前步骤：明确进入 Step 1，并说明这一步要解决什么。\n3. 你会如何服务我：说明你会先改变我完成任务的哪个动作。\n4. 只问我 3 个问题，然后停下等待回答。\n\n首次回复禁止输出：后续完整流程、证据清单、安装命令、项目评价、营销文案、已经安装或运行的说法。\n\nStep 1 / brainstorming 的二轮协议：\n- 我回答首次三问后，你仍然停留在 Step 1 / brainstorming，不要进入 Step 2。\n- 第二次回复必须产出 6 个部分：澄清后的任务定义、成功标准、边界条件、\n  2-3 个可选方案、每个方案的权衡、推荐方案。\n- 第二次回复最后必须问我是否确认推荐方案；只有我明确确认后，才能进入下一步。\n- 第二次回复禁止输出 git worktree、代码计划、测试文件、命令或真实执行结果。\n\n后续对话规则：\n- 我回答后，你先完成当前步骤的中间产物并等待确认；只有我确认后，才能进入下一步。\n- 每一步都要生成一个小的中间产物，例如澄清后的目标、计划草案、测试意图、验证清单或继续/停止判断。\n- 所有演示都写成“我会建议/我会引导/这一步会形成”，不要写成已经真实执行。\n- 不要声称已经测试通过、文件已修改、命令已运行或结果已产生。\n- 如果某个能力必须安装后验证，请直接说“这一步需要安装后验证”。\n- 如果证据不足，请明确说“证据不足”，不要补事实。\n```\n",
      "voices": [
        {
          "body": "来源平台：github。github/github_issue: Consider an alternative wordlist（https://github.com/vostride/id-agent/issues/2）；github/github_issue: Python port（https://github.com/vostride/id-agent/issues/1）。这些是项目级外部声音，不作为单独质量证明。",
          "items": [
            {
              "kind": "github_issue",
              "source": "github",
              "title": "Consider an alternative wordlist",
              "url": "https://github.com/vostride/id-agent/issues/2"
            },
            {
              "kind": "github_issue",
              "source": "github",
              "title": "Python port",
              "url": "https://github.com/vostride/id-agent/issues/1"
            }
          ],
          "status": "已收录 2 条来源",
          "title": "社区讨论"
        }
      ]
    },
    "homepage_card": {
      "category": "软件开发与交付",
      "desc": "<p align=\"center\">",
      "effort": "安装已验证",
      "forks": null,
      "icon": "code",
      "name": "id-agent 能力包",
      "risk": "需复核",
      "slug": "id-agent",
      "stars": null,
      "tags": [
        "浏览器 Agent",
        "网页任务自动化",
        "浏览器自动化",
        "节点式流程编排",
        "Agent 控制浏览器"
      ],
      "thumb": "gray",
      "type": "Skill Pack"
    },
    "manual": {
      "markdown": "# https://github.com/vostride/id-agent 项目说明书\n\n生成时间：2026-05-19 13:55:34 UTC\n\n## 目录\n\n- [项目介绍](#page-introduction)\n- [安装与快速开始](#page-installation)\n- [随机 ID 生成](#page-id-generation)\n- [确定性 ID 生成](#page-deterministic-ids)\n- [解析与验证](#page-parsing-validation)\n- [词表设计](#page-wordlist-design)\n- [加密模块](#page-crypto-module)\n- [Zod 验证架构](#page-schemas-validation)\n- [别名系统](#page-alias-system)\n- [重复检测](#page-duplicate-detection)\n\n<a id='page-introduction'></a>\n\n## 项目介绍\n\n### 相关页面\n\n相关主题：[安装与快速开始](#page-installation), [随机 ID 生成](#page-id-generation)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [README.md](https://github.com/vostride/id-agent/blob/main/README.md)\n- [src/index.ts](https://github.com/vostride/id-agent/blob/main/src/index.ts)\n- [src/parse.ts](https://github.com/vostride/id-agent/blob/main/src/parse.ts)\n- [src/detect.ts](https://github.com/vostride/id-agent/blob/main/src/detect.ts)\n- [src/deterministic.ts](https://github.com/vostride/id-agent/blob/main/src/deterministic.ts)\n- [src/wordlist.ts](https://github.com/vostride/id-agent/blob/main/src/wordlist.ts)\n- [package.json](https://github.com/vostride/id-agent/blob/main/package.json)\n- [scripts/validate-wordlist.ts](https://github.com/vostride/id-agent/blob/main/scripts/validate-wordlist.ts)\n- [scripts/build-wordlist.ts](https://github.com/vostride/id-agent/blob/main/scripts/build-wordlist.ts)\n</details>\n\n# 项目介绍\n\n## 概述\n\nid-agent 是一个专为 AI Agent 系统设计的**人类可读、令牌高效**的 ID 生成库。该项目由 [vostride](https://github.com/vostride) 开发，采用 MIT 开源许可证，当前版本为 **1.0.3**。\n\n资料来源：[package.json:2-10](https://github.com/vostride/id-agent/blob/main/package.json#L2-L10)\n\n## 核心目标\n\nid-agent 解决了传统 UUID 在 AI Agent 系统中的几个关键痛点：\n\n| 问题 | UUID 方案 | id-agent 方案 |\n|------|-----------|---------------|\n| 令牌开销 | ~23 个令牌 | 3词约 5 个令牌（节省 78%） |\n| 可读性 | 无意义十六进制字符串 | 自然语言单词组合 |\n| 碰撞安全 | 120 bits 熵 | 默认 96 bits（安全 300 万亿条目） |\n| 人类协作 | 难以口头交流 | 可直接朗读和拼写 |\n\n资料来源：[README.md](https://github.com/vostride/id-agent/blob/main/README.md)\n\n## 技术架构\n\n### 架构概览\n\n```mermaid\ngraph TD\n    A[用户请求] --> B{ID 类型选择}\n    B -->|随机 ID| C[crypto.getRandomValues CSPRNG]\n    B -->|确定性 ID| D[HMAC-SHA256 Web Crypto API]\n    C --> E[映射到 WORDLIST 索引]\n    D --> E\n    E --> F[formatId 格式化输出]\n    F --> G[返回人类可读 ID]\n    \n    H[验证流程] --> I[parse 解析 ID]\n    I --> J[wordlist 词表校验]\n    J --> K{词存在?}\n    K -->|是| L[返回有效结果]\n    K -->|否| M[返回无效原因]\n```\n\n### 核心模块\n\n| 模块 | 文件路径 | 职责 |\n|------|----------|------|\n| 主入口 | `src/index.ts` | 导出公共 API |\n| 随机 ID | `src/random.ts` | 基于 CSPRNG 的随机 ID 生成 |\n| 确定性 ID | `src/deterministic.ts` | 基于 HMAC-SHA256 的确定型 ID 生成 |\n| 解析器 | `src/parse.ts` | 解析和验证 ID 格式 |\n| 检测器 | `src/detect.ts` | 检测文本中的重复 ID |\n| 词表 | `src/wordlist.ts` | 4096 个精选单词列表 |\n| 别名映射 | `src/alias.ts` | 令牌压缩的双向映射 |\n\n资料来源：[src/deterministic.ts:1-1](https://github.com/vostride/id-agent/blob/main/src/deterministic.ts#L1-L1)\n\n## 工作原理\n\n### 熵与安全性\n\nid-agent 使用精心挑选的 **4096 词表**（2^12），每个单词贡献 12 bits 熵。单词选择通过以下流程确保安全性：\n\n```mermaid\ngraph LR\n    A[CSPRNG 随机数] --> B[取前 16 位]\n    B --> C[模 4096 取余]\n    C --> D[映射到 WORDLIST]\n    D --> E[生成单词]\n    E --> F[组合为 ID]\n```\n\n**碰撞概率计算公式：**\n\n```\nP(collision) ≈ n² / (2 × 2^b)\n\n其中 b = 总熵位数\n```\n\n| 单词数 | 熵位 | ID 空间 | 50% 碰撞阈值 |\n|--------|------|---------|--------------|\n| 3 | 36 bits | 6.9 × 10¹⁰ | ~309K 项 |\n| 5 | 60 bits | 1.2 × 10¹⁸ | ~13 亿项 |\n| **8** | **96 bits** | **7.9 × 10²⁸** | **~300 万亿项** |\n| 10 | 120 bits | 2.7 × 10¹⁸ | UUID 级别安全 |\n\n资料来源：[README.md](https://github.com/vostride/id-agent/blob/main/README.md)\n\n### 令牌效率\n\nBPE 分词器（如 GPT-4o 使用的 o200k_base）在自然语言上训练，**短英文单词恰好是单个令牌**：\n\n| 格式 | 令牌数 | 字符数 | 效率 |\n|------|--------|--------|------|\n| `dc193952-186a-4645` | ~11 tokens | 18 | 低 |\n| `storm-delta-stone` | ~4 tokens | 18 | 高 |\n\n词表中的每个单词都经过验证，确保在 o200k_base 分词器上是**恰好 1 个 BPE 令牌**。\n\n资料来源：[README.md](https://github.com/vostride/id-agent/blob/main/README.md)\n\n### 词表构建\n\n词表构建经过多层过滤：\n\n```mermaid\ngraph TD\n    A[o200k_base 词汇表] --> B{长度 3-6 字符}\n    B -->|是| C[系统词典验证]\n    B -->|否| X[排除]\n    C --> D{小写字母?}\n    D -->|是| E{无同音词?}\n    D -->|否| X\n    E -->|是| F{无贬义?}\n    E -->|否| X\n    F -->|是| G[加入词表]\n```\n\n**过滤规则：**\n\n1. **长度筛选**：仅保留 3-6 个字符的单词\n2. **词典验证**：确保是有效的英语单词\n3. **同音词过滤**：排除会产生歧义的同音词（如 `bare/bear`）\n4. **内容过滤**：移除冒犯性词汇\n\n资料来源：[scripts/build-wordlist.ts](https://github.com/vostride/id-agent/blob/main/scripts/build-wordlist.ts)\n\n## API 参考\n\n### 安装\n\n```bash\nnpm install id-agent\n# 或\npnpm add id-agent\n```\n\n**环境要求**：Node.js ≥ 18\n\n资料来源：[package.json:32-33](https://github.com/vostride/id-agent/blob/main/package.json#L32-L33)\n\n### `idAgent.generate(opts?)`\n\n生成随机人类可读 ID。\n\n```typescript\nimport { idAgent } from 'id-agent'\n\nconst id = idAgent.generate()\n// => \"storm-delta-stone\"\n\nconst prefixed = idAgent.generate({ prefix: 'task', words: 5 })\n// => \"task_snow-ocean-frost-finch-grove\"\n```\n\n**参数选项：**\n\n| 参数 | 类型 | 默认值 | 描述 |\n|------|------|--------|------|\n| `prefix` | `string` | `undefined` | 类型前缀（小写字母数字） |\n| `words` | `number` | `8` | 单词数量（1-16），控制熵位 |\n\n### `idAgent.from(input, opts?)`\n\n基于 HMAC-SHA256 生成确定性 ID，相同输入永远产生相同 ID。\n\n```typescript\nconst id = await idAgent.from('user@example.com')\n// 相同输入产生相同 ID\n\nconst namespaced = await idAgent.from('user@example.com', {\n  namespace: 'my-app',\n  prefix: 'user',\n  words: 5,\n})\n```\n\n**参数选项：**\n\n| 参数 | 类型 | 默认值 | 描述 |\n|------|------|--------|------|\n| `prefix` | `string` | `undefined` | 类型前缀 |\n| `words` | `number` | `8` | 单词数量（1-16） |\n| `namespace` | `string` | `'id-agent'` | HMAC 密钥，用于域隔离 |\n\n资料来源：[src/deterministic.ts](https://github.com/vostride/id-agent/blob/main/src/deterministic.ts)\n\n### `parse(id)`\n\n解析任意 id-agent ID 为其组成部分。\n\n```typescript\nimport { parse } from 'id-agent'\n\nparse('task_storm-delta-stone')\n// => {\n//   prefix: 'task',\n//   words: ['storm', 'delta', 'stone'],\n//   wordCount: 3,\n//   bits: 36,\n//   raw: 'task_storm-delta-stone',\n//   format: 'readable'\n// }\n```\n\n### `validate(id)`\n\n验证字符串是否为合法的 id-agent ID。\n\n```typescript\nimport { validate } from 'id-agent'\n\nvalidate('storm-delta-stone')\n// => { valid: true, prefix: undefined, wordCount: 3 }\n\nvalidate('task_jump-notaword')\n// => { valid: false, reason: 'unknown words: notaword' }\n\nvalidate('INVALID')\n// => { valid: false, reason: 'contains uppercase characters' }\n```\n\n资料来源：[src/parse.ts](https://github.com/vostride/id-agent/blob/main/src/parse.ts)\n\n### `detectDuplicates(opts)`\n\n扫描文本中的重复 ID。\n\n```typescript\nimport { detectDuplicates } from 'id-agent'\n\nconst dupes = detectDuplicates({\n  pattern: /[a-z]+(?:-[a-z]+)+/,\n  text: 'Found storm-delta-stone in file A and storm-delta-stone in file B',\n})\n// => [{ id: 'storm-delta-stone', count: 2 }]\n```\n\n**参数选项：**\n\n| 参数 | 类型 | 描述 |\n|------|------|------|\n| `pattern` | `RegExp` | 匹配 ID 的正则表达式 |\n| `text` | `string \\| string[]` | 要扫描的文本 |\n\n资料来源：[src/detect.ts](https://github.com/vostride/id-agent/blob/main/src/detect.ts)\n\n### `createAliasMap(opts)`\n\n创建用于 LLM 上下文令牌压缩的双向别名映射。\n\n```typescript\nimport { createAliasMap } from 'id-agent'\n\nconst aliases = createAliasMap({ words: 3 })\n\n// 设置长 UUID 并获取短别名\naliases.set('8cdda07b-85d2-459c-8a2a-83c8f9245dbe')\n// => \"storm-delta-stone\"\n\n// 替换文本中的所有 UUID\nconst shortened = aliases.replace(text, {\n  pattern: /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi\n})\n\n// 恢复原始 UUID\nconst restored = aliases.restore(shortened)\n```\n\n### `WORDLIST`\n\n直接访问 4096 词表（只读数组）。\n\n```typescript\nimport { WORDLIST } from 'id-agent'\n\nWORDLIST.length          // => 4096\nObject.isFrozen(WORDLIST) // => true\n```\n\n资料来源：[README.md](https://github.com/vostride/id-agent/blob/main/README.md)\n\n## 应用场景\n\n| 场景 | 推荐配置 | 熵位 | 说明 |\n|------|----------|------|------|\n| 开发/测试 | `words: 3` | 36 bits | 快速原型，便于一目了然 |\n| 生产 SaaS | `words: 5` | 60 bits | 节省 65% 令牌，安全到 10 亿项 |\n| 高并发/分布式 | `words: 8`（默认） | 96 bits | 默认安全配置，可应对 300 万亿项 |\n| UUID 等效 | `words: 10` | 120 bits | 与 UUID v4 碰撞概率相同 |\n\n## 开发命令\n\n| 命令 | 说明 |\n|------|------|\n| `pnpm build` | 构建生产版本 |\n| `pnpm test` | 运行测试 |\n| `pnpm lint` | 代码检查 |\n| `pnpm validate` | 验证词表质量 |\n| `pnpm build:wordlist` | 重新构建词表 |\n\n资料来源：[package.json:37-44](https://github.com/vostride/id-agent/blob/main/package.json#L37-L44)\n\n## 项目依赖\n\n### 生产依赖\n\n| 依赖 | 版本 | 用途 |\n|------|------|------|\n| `zod` | 4.3.6 | Schema 验证 |\n\n### 开发依赖\n\n| 依赖 | 用途 |\n|------|------|\n| `vitest` | 单元测试 |\n| `tsup` | 构建工具 |\n| `js-tiktoken` | 分词器验证 |\n| `obscenity` | 词表内容过滤 |\n| `dprint` | 代码格式化 |\n| `oxlint` | 代码检查 |\n\n资料来源：[package.json:17-28](https://github.com/vostride/id-agent/blob/main/package.json#L17-L28)\n\n## 总结\n\nid-agent 是一款专为 AI Agent 工作流优化的 ID 生成工具，通过以下核心优势解决 LLM 上下文中的效率问题：\n\n1. **令牌高效**：默认配置节省约 78% 的令牌开销\n2. **人类可读**：基于自然语言单词，便于口头交流和日志追踪\n3. **灵活安全**：可配置的熵位满足从开发到生产各级别需求\n4. **确定性与随机性兼顾**：支持随机生成和 HMAC 确定性生成两种模式\n\n---\n\n<a id='page-installation'></a>\n\n## 安装与快速开始\n\n### 相关页面\n\n相关主题：[项目介绍](#page-introduction), [随机 ID 生成](#page-id-generation)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [package.json](https://github.com/vostride/id-agent/blob/main/package.json)\n- [README.md](https://github.com/vostride/id-agent/blob/main/README.md)\n- [src/wordlist.ts](https://github.com/vostride/id-agent/blob/main/src/wordlist.ts)\n- [src/parse.ts](https://github.com/vostride/id-agent/blob/main/src/parse.ts)\n- [src/deterministic.ts](https://github.com/vostride/id-agent/blob/main/src/deterministic.ts)\n</details>\n\n# 安装与快速开始\n\n## 项目概述\n\n`id-agent` 是一个用于 AI 代理系统的人类可读、令牌高效的可识别 ID 生成库。该项目通过将 UUID 或其他长标识符转换为基于单词的短格式，实现高达 78% 的令牌节省效果，同时保持足够的熵值以防止碰撞。\n\n资料来源：[package.json:2-3]()\n\n## 安装前准备\n\n### 系统要求\n\n| 要求 | 最低版本 | 说明 |\n|------|---------|------|\n| Node.js | >= 18 | 必须支持 Web Crypto API |\n| 包管理器 | pnpm 10.6.1 | 推荐使用 pnpm |\n\n资料来源：[package.json:21-22]()\n\n### 核心依赖\n\n| 依赖 | 版本 | 用途 |\n|------|------|------|\n| zod | 4.3.6 | 参数验证与类型安全 |\n\n资料来源：[package.json:28-30]()\n\n## 安装步骤\n\n### 方式一：使用 pnpm（推荐）\n\n```bash\npnpm add id-agent\n```\n\n### 方式二：使用 npm\n\n```bash\nnpm install id-agent\n```\n\n### 方式三：使用 yarn\n\n```bash\nyarn add id-agent\n```\n\n## 快速开始\n\n### 基础导入与使用\n\n```typescript\nimport { idAgent } from 'id-agent'\n\n// 生成随机人类可读 ID\nconst id = await idAgent.generate()\n// => \"storm-delta-stone-cloud-voice-fruit-north-field\"\n\n// 带前缀的 ID\nconst taskId = await idAgent.generate({ prefix: 'task', words: 5 })\n// => \"task_storm-delta-stone-cloud-voice-fruit\"\n```\n\n资料来源：[README.md](https://github.com/vostride/id-agent/blob/main/README.md)\n\n### 确定性 ID 生成\n\n基于输入字符串生成稳定的 ID，适用于用户 ID、文档 ID 等场景：\n\n```typescript\nconst userId = await idAgent.from('user@example.com')\n// 相同输入始终返回相同的 ID\n\nconst namespaced = await idAgent.from('user@example.com', {\n  namespace: 'my-app',\n  prefix: 'user',\n  words: 5,\n})\n```\n\n资料来源：[src/deterministic.ts:1-47]()\n\n### ID 解析与验证\n\n```typescript\nimport { parse, validate } from 'id-agent'\n\n// 解析 ID 组成\nconst parsed = parse('task_storm-delta-stone')\n// => { prefix: 'task', words: ['storm', 'delta', 'stone'], wordCount: 3, bits: 36 }\n\n// 验证 ID 有效性\nconst result = validate('storm-delta-stone')\n// => { valid: true, prefix: undefined, wordCount: 3 }\n\nconst invalid = validate('task_jump-notaword')\n// => { valid: false, reason: 'unknown words: notaword' }\n```\n\n资料来源：[src/parse.ts]()\n\n## 生成选项配置\n\n| 选项 | 类型 | 默认值 | 取值范围 | 说明 |\n|------|------|--------|---------|------|\n| `prefix` | `string` | `undefined` | 小写字母数字 | 类型前缀，用于域名分离 |\n| `words` | `number` | `8` | 1-16 | 单词数量，控制熵值：words * 12 bits |\n\n资料来源：[README.md](https://github.com/vostride/id-agent/blob/main/README.md)\n\n### 不同场景推荐配置\n\n| 场景 | words | bits | 容量 | 说明 |\n|------|-------|------|------|------|\n| 快速原型 | 3 | 36 | ~309K | 最小令牌占用 |\n| 生产 SaaS | 5 | 60 | ~1.3B | UUID 65% 令牌节省 |\n| 高流量/分布式 | 8 | 96 | ~300T | 安全默认值 |\n\n资料来源：[README.md](https://github.com/vostride/id-agent/blob/main/README.md)\n\n## 别名映射与文本替换\n\n在 LLM 上下文中，可以使用别名映射将长 ID 替换为短单词格式：\n\n```typescript\nimport { createAliasMap } from 'id-agent'\n\nconst aliases = createAliasMap({ words: 3 })\naliases.set('8cdda07b-85d2-459c-8a2a-83c8f9245dbe')\n// => \"storm-delta-stone\"\n\nconst text = 'Process 8cdda07b-85d2-459c-8a2a-83c8f9245dbe then 6ba7b810-9dad-11d1-80b4-00c04fd430c8'\nconst shortened = aliases.replace(text, {\n  pattern: /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi\n})\n// => \"Process storm-delta-stone then cloud-train-scope\"\n\nconst restored = aliases.restore(shortened)\n// => 恢复原始 UUID\n```\n\n资料来源：[README.md](https://github.com/vostride/id-agent/blob/main/README.md)\n\n## 重复 ID 检测\n\n```typescript\nimport { detectDuplicates } from 'id-agent'\n\nconst dupes = detectDuplicates({\n  pattern: /[a-z]+(?:-[a-z]+)+/,\n  text: 'Found storm-delta-stone in file A and storm-delta-stone in file B',\n})\n// => [{ id: 'storm-delta-stone', count: 2 }]\n```\n\n## 开发环境搭建\n\n### 克隆项目\n\n```bash\ngit clone https://github.com/vostride/id-agent.git\ncd id-agent\n```\n\n### 安装依赖\n\n```bash\npnpm install\n```\n\n### 可用脚本命令\n\n| 命令 | 说明 |\n|------|------|\n| `pnpm build` | 使用 tsup 构建项目 |\n| `pnpm test` | 运行 vitest 测试 |\n| `pnpm test:watch` | 监听模式运行测试 |\n| `pnpm lint` | 使用 oxlint 检查代码 |\n| `pnpm format` | 使用 dprint 格式化代码 |\n| `pnpm format:check` | 检查代码格式 |\n| `pnpm size` | 检查 bundle 大小 |\n| `pnpm publint` | 检查包发布配置 |\n| `pnpm validate` | 验证单词列表 |\n\n资料来源：[package.json:24-36]()\n\n## 验证安装\n\n安装完成后，可以通过以下方式验证：\n\n```typescript\nimport { idAgent, WORDLIST } from 'id-agent'\n\n// 验证 WORDLIST 加载\nconsole.log(WORDLIST.length)          // => 4096\nconsole.log(Object.isFrozen(WORDLIST)) // => true\n\n// 生成测试 ID\nconst testId = await idAgent.generate({ words: 3 })\nconsole.log(testId)                    // => 3 词格式 ID\n```\n\n## 下一步\n\n- 查看 [基本概念](/docs/concepts) 了解 ID 格式与熵值计算\n- 查看 [API 参考](/docs/api) 获取完整 API 文档\n- 查看 [最佳实践](/docs/best-practices) 了解生产环境配置建议\n\n---\n\n<a id='page-id-generation'></a>\n\n## 随机 ID 生成\n\n### 相关页面\n\n相关主题：[确定性 ID 生成](#page-deterministic-ids), [词表设计](#page-wordlist-design), [加密模块](#page-crypto-module)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/generate.ts](https://github.com/vostride/id-agent/blob/main/src/generate.ts)\n- [src/types.ts](https://github.com/vostride/id-agent/blob/main/src/types.ts)\n- [src/schemas.ts](https://github.com/vostride/id-agent/blob/main/src/schemas.ts)\n- [src/deterministic.ts](https://github.com/vostride/id-agent/blob/main/src/deterministic.ts)\n- [src/parse.ts](https://github.com/vostride/id-agent/blob/main/src/parse.ts)\n- [src/alias.ts](https://github.com/vostride/id-agent/blob/main/src/alias.ts)\n- [src/wordlist.ts](https://github.com/vostride/id-agent/blob/main/src/wordlist.ts)\n- [package.json](https://github.com/vostride/id-agent/blob/main/package.json)\n</details>\n\n# 随机 ID 生成\n\n## 概述\n\n随机 ID 生成是 id-agent 项目的核心功能之一。该模块利用加密安全的随机数生成器（CSPRNG）创建人类可读、Token 高效的标识符。与传统的 UUID 相比，随机生成的 ID 由从精心策划的 4096 词表中选取的单词组成，每个单词恰好对应一个 BPE Token，在 LLM 场景下显著降低 Token 消耗。\n\n## 核心设计\n\n### 词表机制\n\nid-agent 维护一个包含 4096 个英语单词的词表，每个单词满足以下条件：\n\n- 长度为 3-6 个字符\n- 在 o200k_base 分词器上恰好为 1 个 Token\n- 不包含冒犯性词汇\n- 排除同音异义词（如 \"wait\" 和 \"weight\"）\n\n每个单词提供 log2(4096) = 12 位的熵值，ID 的总熵由单词数量决定：\n\n```\n总熵 = 单词数量 × 12 bits\nID空间 = 4096^单词数量 = 2^(单词数量 × 12)\n```\n\n资料来源：[README.md](https://github.com/vostride/id-agent/blob/main/README.md)\n\n### 随机数生成\n\n随机 ID 使用 `crypto.getRandomValues()` 作为熵源，这是 Web Crypto API 提供的加密安全随机数生成器。相比 Math.random()，CSPRNG 提供的随机数具有密码学安全性，适用于需要防止预测的攻击场景。\n\n## API 参考\n\n### `idAgent.random(opts?)`\n\n生成一个随机 ID，默认配置为 8 个单词（96 位熵）。\n\n```typescript\nimport { idAgent } from 'id-agent'\n\nconst id = idAgent.random()\n// => \"storm-delta-stone-cloud-frost-raven-ocean-ember\"\n\nconst shortId = idAgent.random({ words: 3 })\n// => \"storm-delta-stone\"\n\nconst prefixedId = idAgent.random({ prefix: 'user', words: 5 })\n// => \"user-storm-delta-stone-cloud-frost\"\n```\n\n#### 参数选项\n\n| 参数 | 类型 | 默认值 | 描述 |\n|------|------|--------|------|\n| `prefix` | `string` | `undefined` | 类型前缀（小写字母数字组合） |\n| `words` | `number` | `8` | 单词数量（范围 1-16），控制熵值 |\n\n参数验证由 Zod Schema 执行，无效输入会抛出描述性错误。\n\n资料来源：[src/schemas.ts](https://github.com/vostride/id-agent/blob/main/src/schemas.ts)\n\n### 类型定义\n\n```typescript\ninterface IdAgentRandomOptions {\n  prefix?: string\n  words?: number\n}\n\ninterface IdAgent {\n  random(opts?: IdAgentRandomOptions): string\n  from(input: string, opts?: IdAgentFromOptions): Promise<string>\n  parse(id: string): ParsedId | null\n  validate(id: string): ValidationResult\n}\n```\n\n资料来源：[src/types.ts](https://github.com/vostride/id-agent/blob/main/src/types.ts)\n\n## 工作流程\n\n```mermaid\ngraph TD\n    A[调用 idAgent.random] --> B{参数验证}\n    B -->|通过| C[计算所需单词数]\n    B -->|失败| Z[抛出 ZodError]\n    C --> D[调用 crypto.getRandomValues]\n    D --> E[从 DataView 读取随机字节]\n    E --> F[每 2 字节映射到 WORDLIST 索引]\n    F --> G{检查重复}\n    G -->|无重复| H[收集单词到数组]\n    G -->|重复| E\n    H --> I{单词数已满足}\n    I -->|否| E\n    I -->|是| J[拼接单词为字符串]\n    J --> K{提供 prefix}\n    K -->|是| L[添加前缀: prefix-words]\n    K -->|否| M[仅返回 words]\n    L --> N[返回完整 ID]\n    M --> N\n```\n\n## 碰撞概率分析\n\n由于使用固定词表，存在理论碰撞概率。根据生日悖论公式：\n\n```\nP(碰撞) ≈ n² / (2 × 2^b)\n\n其中 b = 总位数 = 单词数 × 12\n```\n\n### 不同配置的碰撞概率\n\n| 单词数 | 熵值 | ID 空间 | 100 万条时概率 | 10 亿条时概率 | 50% 碰撞点 |\n|--------|------|---------|----------------|---------------|------------|\n| 3 | 36 位 | 6.9 × 10¹⁰ | 0.00004% | ~43% | ~309K 条 |\n| 4 | 48 位 | 2.8 × 10¹⁴ | 1.8 × 10⁻⁶ % | ~100% | ~20M 条 |\n| 5 | 60 位 | 1.2 × 10¹⁸ | 4.3 × 10⁻⁸ % | 0.43% | ~1.3B 条 |\n| **8** | **96 位** | **7.9 × 10²⁸** | **6.3 × 10⁻¹⁸ %** | **~0%** | **~300T 条** |\n| 10 | 120 位 | 1.3 × 10³⁶ | ~0% | 9.4 × 10⁻²⁰ % | ~2.7 × 10¹⁸ 条 |\n\n**默认配置（8 单词，96 位）** 可安全处理超过 300 万亿条 ID 而不产生 50% 碰撞概率。\n\n资料来源：[README.md](https://github.com/vostride/id-agent/blob/main/README.md)\n\n## Token 效率对比\n\nid-agent 的单词型 ID 在 LLM 分词器上远比 UUID 高效。以 o200k_base 分词器为例：\n\n| 格式 | 平均 Token 数 | 熵值 | 相比 UUID 节省 |\n|------|---------------|------|----------------|\n| UUID v4 | ~23 | 122 位 | -- |\n| id-agent (3 单词) | ~5 | 36 位 | **78%** |\n| id-agent (5 单词) | ~9 | 60 位 | **61%** |\n| id-agent (8 单词) | ~14 | 96 位 | **39%** |\n\n这是因为短英语单词在 BPE 分词器上天然就是单个 Token，而 UUID 的十六进制字符会不可预测地分裂成多个 Token。\n\n资料来源：[README.md](https://github.com/vostride/id-agent/blob/main/README.md)\n\n## 与确定性 ID 的关系\n\nid-agent 提供两种 ID 生成模式：\n\n| 模式 | 熵源 | 可重现性 | 适用场景 |\n|------|------|----------|----------|\n| **随机** `random()` | `crypto.getRandomValues()` | 否 | 会话 ID、临时标识符 |\n| **确定性** `from()` | HMAC-SHA256 | 是 | 用户标识、内容寻址 |\n\n确定性模式使用相同的词表和单词选择逻辑，但通过 HMAC-SHA256 将输入字符串映射到固定的单词序列，确保相同输入始终产生相同输出。\n\n```typescript\n// 随机 ID：每次调用生成不同 ID\nidAgent.random()   // => \"storm-delta-stone...\"\nidAgent.random()   // => \"frost-ocean-ember...\"\n\n// 确定性 ID：相同输入产生相同 ID\nawait idAgent.from('user@example.com')   // => \"cloud-train-scope...\"\nawait idAgent.from('user@example.com')   // => \"cloud-train-scope...\"\n```\n\n资料来源：[src/deterministic.ts](https://github.com/vostride/id-agent/blob/main/src/deterministic.ts)\n\n## 使用场景\n\n### 场景一：会话标识符\n\n```typescript\nconst sessionId = idAgent.random({ words: 4, prefix: 'session' })\n// => \"session-storm-delta-stone-cloud\"\n```\n\n### 场景二：任务队列标识符\n\n```typescript\nconst taskId = idAgent.random({ words: 5, prefix: 'task' })\n// => \"task-frost-ocean-ember-light-rain\"\n```\n\n### 场景三：轻量级随机标识符\n\n```typescript\nconst shortId = idAgent.random({ words: 3 })\n// => \"stone-cloud-train\"\n```\n\n## 配置建议\n\n| 应用场景 | 推荐配置 | 熵值 | 说明 |\n|----------|----------|------|------|\n| 开发/测试 | `words: 3` | 36 位 | 简短易读，用于非关键场景 |\n| 生产 SaaS | `words: 5` | 60 位 | 安全到约 10 亿条，节省 65% Token |\n| 高容量/分布式 | `words: 8` (默认) | 96 位 | 安全到约 300 万亿条，推荐默认值 |\n| UUID 等效 | `words: 10` | 120 位 | 与 UUID v4 碰撞概率相当 |\n\n## 安全性考量\n\n### CSPRNG 的必要性\n\n使用 `crypto.getRandomValues()` 而非 `Math.random()` 是关键安全设计：\n\n- `Math.random()`：伪随机数，可被预测\n- `crypto.getRandomValues()`：密码学安全随机数，满足熵要求\n\n### 前缀验证\n\n前缀仅接受小写字母数字组合（`/^[a-z0-9]+$/`），防止格式注入和解析歧义。\n\n```typescript\nidAgent.random({ prefix: 'User-ID' })\n// => 抛出错误: \"prefix must be lowercase alphanumeric only\"\n```\n\n资料来源：[src/schemas.ts](https://github.com/vostride/id-agent/blob/main/src/schemas.ts)\n\n## 验证与解析\n\n### `validate(id)`\n\n验证 ID 是否合法：\n\n```typescript\nimport { validate } from 'id-agent'\n\nvalidate('storm-delta-stone')\n// => { valid: true, prefix: undefined, wordCount: 3 }\n\nvalidate('task_jump-notaword')\n// => { valid: false, reason: 'unknown words: notaword' }\n```\n\n### `parse(id)`\n\n解析 ID 的组成部分：\n\n```typescript\nimport { parse } from 'id-agent'\n\nparse('task_storm-delta-stone')\n// => {\n//   prefix: 'task',\n//   words: ['storm', 'delta', 'stone'],\n//   wordCount: 3,\n//   bits: 36,\n//   raw: 'task_storm-delta-stone',\n//   format: 'readable'\n// }\n```\n\n资料来源：[src/parse.ts](https://github.com/vostride/id-agent/blob/main/src/parse.ts)\n\n## 内部实现\n\n### 单词选择算法\n\n核心逻辑位于 `selectRandomWords` 函数，通过以下步骤选择单词：\n\n1. 使用 `DataView.getUint16()` 从随机字节序列中读取 16 位无符号整数\n2. 取模 4096 得到词表索引\n3. 重复直到收集到所需单词数量\n4. 去重确保无重复单词\n\n### 重复检测\n\n如果生成过程中出现重复单词，会重新生成而不是替换。这确保 ID 的实际熵值与理论值一致。\n\n```typescript\n// 简化伪代码\ndo {\n  word = WORDLIST[randomUint16() % 4096]\n} while (used.has(word) && used.size < 4096)\n```\n\n## 总结\n\n随机 ID 生成是 id-agent 项目的基石功能，通过以下设计实现了安全性、可读性和 Token 效率的统一：\n\n- **4096 词表**：每个单词 12 位熵，BPE 友好\n- **CSPRNG**：密码学安全的熵源\n- **可配置单词数**：根据场景平衡安全性和简洁性\n- **可选前缀**：支持类型化 ID 命名空间\n- **与确定性模式共存**：覆盖随机和可重现两种场景\n\n---\n\n<a id='page-deterministic-ids'></a>\n\n## 确定性 ID 生成\n\n### 相关页面\n\n相关主题：[随机 ID 生成](#page-id-generation), [加密模块](#page-crypto-module)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/deterministic.ts](https://github.com/vostride/id-agent/blob/main/src/deterministic.ts)\n- [src/generate.ts](https://github.com/vostride/id-agent/blob/main/src/generate.ts)\n- [src/parse.ts](https://github.com/vostride/id-agent/blob/main/src/parse.ts)\n- [src/schemas.ts](https://github.com/vostride/id-agent/blob/main/src/schemas.ts)\n- [src/types.ts](https://github.com/vostride/id-agent/blob/main/src/types.ts)\n- [src/wordlist.ts](https://github.com/vostride/id-agent/blob/main/src/wordlist.ts)\n- [README.md](https://github.com/vostride/id-agent/blob/main/README.md)\n</details>\n\n# 确定性 ID 生成\n\n## 概述\n\n确定性 ID 生成是 id-agent 库的核心功能之一，允许从任意字符串输入生成唯一、可复现的 ID。与随机 ID 生成不同，相同的输入无论何时何地调用，都会产生完全相同的输出 ID。\n\n该功能主要适用于：\n\n- **用户标识**：基于邮箱、用户名等生成唯一用户 ID\n- **内容寻址**：基于文件内容哈希生成确定性文件 ID\n- **幂等操作**：为请求生成稳定的标识符用于去重\n\n核心原理是通过 HMAC-SHA256 哈希函数将输入字符串转换为加密安全的伪随机数，然后将这些数字映射到精选的 4096 词表中的单词。\n\n## 工作原理\n\n### 架构流程\n\n```mermaid\ngraph TD\n    A[输入字符串] --> B[TextEncoder 编码]\n    B --> C[导入 HMAC 密钥]\n    C --> D[crypto.subtle.sign 使用 HMAC-SHA256]\n    D --> E[DataView 读取签名结果]\n    E --> F[每 2 字节映射到 WORDLIST 索引]\n    F --> G[拼接单词为最终 ID]\n    \n    H[namespace 配置] --> C\n    I[words 数量] --> F\n    J[prefix 前缀] --> G\n```\n\n### 关键步骤解析\n\n**步骤 1：输入验证与编码**\n\n函数首先验证输入有效性，确保传入的是非空字符串：\n\n```typescript\nif (!input || typeof input !== 'string') {\n  throw new Error('input must be a non-empty string')\n}\n```\n资料来源：[src/deterministic.ts:10](https://github.com/vostride/id-agent/blob/main/src/deterministic.ts#L10)\n\n**步骤 2：选项解析与默认值**\n\n使用 Zod Schema 验证并应用默认配置，words 默认值为 8：\n\n```typescript\nconst validated = IdAgentFromOptionsSchema.parse(opts ?? {})\nconst words = validated.words ?? 8\n```\n资料来源：[src/deterministic.ts:12-13](https://github.com/vostride/id-agent/blob/main/src/deterministic.ts#L12-L13)\n\n**步骤 3：Web Crypto API 密钥导入**\n\n使用 Web Crypto API 的 `crypto.subtle` 模块导入 HMAC 密钥：\n\n```typescript\nconst enc = new TextEncoder()\nconst keyData = enc.encode(validated.namespace ?? 'id-agent')\nconst key = await globalThis.crypto.subtle.importKey(\n  'raw',\n  keyData,\n  { name: 'HMAC', hash: 'SHA-256' },\n  false,\n  ['sign'],\n)\n```\n资料来源：[src/deterministic.ts:18-24](https://github.com/vostride/id-agent/blob/main/src/deterministic.ts#L18-L24)\n\n**步骤 4：HMAC-SHA256 签名**\n\n对输入字符串进行加密签名：\n\n```typescript\nconst sig = await globalThis.crypto.subtle.sign('HMAC', key, enc.encode(input))\n```\n资料来源：[src/deterministic.ts:26](https://github.com/vostride/id-agent/blob/main/src/deterministic.ts#L26)\n\n**步骤 5：哈希值到单词的映射**\n\n将签名结果转换为 DataView，每 2 字节（16 位）作为一个索引，取模 4096 获取词表中的单词：\n\n```typescript\nconst view = new DataView(sig)\nconst selected: string[] = new Array(words)\nfor (let i = 0; i < words; i++) {\n  selected[i] = WORDLIST[view.getUint16(i * 2) % 4096]\n}\n```\n资料来源：[src/deterministic.ts:28-32](https://github.com/vostride/id-agent/blob/main/src/deterministic.ts#L28-L32)\n\n**步骤 6：格式化输出**\n\n使用 `formatId` 函数将前缀和单词数组拼接为最终 ID：\n\n```typescript\nreturn formatId(validated.prefix, selected.join('-'))\n```\n资料来源：[src/deterministic.ts:34](https://github.com/vostride/id-agent/blob/main/src/deterministic.ts#L34)\n\n## API 参考\n\n### idAgent.from(input, opts?)\n\n生成确定性 ID 的主要方法，挂载在 `idAgent` 函数对象上。\n\n```typescript\nimport { idAgent } from 'id-agent'\n\nconst id = await idAgent.from('user@example.com')\n// => 例如：vivid-shade-glimmer (每次相同)\n```\n\n#### 参数说明\n\n| 参数 | 类型 | 必填 | 默认值 | 说明 |\n|------|------|------|--------|------|\n| `input` | `string` | 是 | - | 用于生成 ID 的输入字符串 |\n| `opts.prefix` | `string` | 否 | `undefined` | 类型前缀（小写字母数字） |\n| `opts.words` | `number` | 否 | `8` | 单词数量（1-16），控制熵值 |\n| `opts.namespace` | `string` | 否 | `'id-agent'` | HMAC 密钥，用于域隔离 |\n\n资料来源：[src/generate.ts:8](https://github.com/vostride/id-agent/blob/main/src/generate.ts#L8)，[README.md](https://github.com/vostride/id-agent/blob/main/README.md)\n\n#### 返回值\n\n返回格式化后的确定性 ID 字符串，格式为：`{prefix_}word1-word2-word3-...`\n\n#### 使用示例\n\n**基础用法**\n\n```typescript\nconst id = await idAgent.from('user@example.com')\n// 每次调用都返回相同结果\n```\n\n**带前缀和命名空间**\n\n```typescript\nconst userId = await idAgent.from('user@example.com', {\n  namespace: 'my-app',\n  prefix: 'user',\n  words: 5,\n})\n// => \"user_calm-bold-wake-tide-neat\"\n```\n\n**不同命名空间产生不同 ID**\n\n```typescript\nconst id1 = await idAgent.from('same-input', { namespace: 'app-a' })\nconst id2 = await idAgent.from('same-input', { namespace: 'app-b' })\n// id1 !== id2 (因为命名空间不同)\n```\n\n## 配置选项详解\n\n### words 参数\n\n控制生成 ID 的单词数量，直接决定熵值大小。\n\n| words 值 | 熵值 | ID 空间 | 适用场景 |\n|----------|------|---------|----------|\n| 3 | 36 bits | 6.9 × 10¹⁰ | 仅用于日志/调试 |\n| 5 | 60 bits | 1.2 × 10¹⁸ | 生产级 SaaS 应用 |\n| 8 | 96 bits | 7.9 × 10²⁸ | **默认**，高容量/分布式系统 |\n| 10 | 120 bits | 1.3 × 10³⁶ | UUID v4 等效安全级别 |\n\n资料来源：[README.md](https://github.com/vostride/id-agent/blob/main/README.md)\n\n### namespace 参数\n\nHMAC 密钥用于域隔离，确保相同输入在不同应用/租户间产生不同 ID。\n\n```typescript\n// 多租户场景\nconst id1 = await idAgent.from('shared-resource-id', { namespace: 'tenant-1' })\nconst id2 = await idAgent.from('shared-resource-id', { namespace: 'tenant-2' })\n```\n\n### prefix 参数\n\n类型前缀用于区分不同实体的 ID，便于人工识别和日志分析。\n\n- 必须是 **小写字母数字**\n- 格式：`{prefix}_word-word-word`\n- 例如：`user_`、`task_`、`file_`\n\n```typescript\nawait idAgent.from('doc-123', { prefix: 'doc' })\n// => \"doc_river-wave-soft-wake-calm-dream-bloom\"\n```\n\n## 验证与解析\n\n### validate(id)\n\n验证确定性 ID 的有效性，检查词表中的单词是否都存在：\n\n```typescript\nimport { validate } from 'id-agent'\n\nvalidate('task_storm-delta-stone')\n// => { valid: true, prefix: 'task', wordCount: 3 }\n\nvalidate('task_jump-notaword')\n// => { valid: false, reason: 'unknown words: notaword' }\n```\n资料来源：[src/parse.ts](https://github.com/vostride/id-agent/blob/main/src/parse.ts)\n\n### parse(id)\n\n解析 ID 的结构组件：\n\n```typescript\nimport { parse } from 'id-agent'\n\nparse('task_storm-delta-stone')\n// => {\n//   prefix: 'task',\n//   words: ['storm', 'delta', 'stone'],\n//   wordCount: 3,\n//   bits: 36,\n//   raw: 'task_storm-delta-stone',\n//   format: 'readable'\n// }\n```\n资料来源：[src/parse.ts](https://github.com/vostride/id-agent/blob/main/src/parse.ts)\n\n## 安全性分析\n\n### HMAC-SHA256 保障\n\n确定性 ID 生成使用 Web Crypto API 的 `crypto.subtle.sign` 方法，底层采用 HMAC-SHA256 算法：\n\n```mermaid\ngraph LR\n    A[输入] --> B[HMAC-SHA256]\n    B --> C[128位签名]\n    C --> D[选取前 2×words 字节]\n    D --> E[每字节对 4096 取模]\n    E --> F[映射到单词]\n```\n\n### 域隔离机制\n\n通过 namespace 参数实现密钥隔离，即使输入相同，不同命名空间产生的 HMAC 签名完全不同：\n\n```typescript\n// 即使输入完全相同\nidAgent.from('same-input', { namespace: 'ns-a' })  // => 完全不同的输出\nidAgent.from('same-input', { namespace: 'ns-b' })  // => 完全不同的输出\n```\n\n### 熵值计算\n\n每个单词贡献 12 bits 熵值（因为词表大小为 4096 = 2¹²）：\n\n```\n总熵值 = words × 12 bits\n```\n\n默认 8 个单词提供 96 bits 熵值，在 300 万亿个项目内碰撞概率低于 50%。\n\n## 浏览器兼容性\n\n该功能依赖 **Web Crypto API**，要求：\n\n| 环境 | 支持情况 | 说明 |\n|------|----------|------|\n| 现代浏览器 | ✅ | HTTPS 环境下完整支持 |\n| Node.js 18+ | ✅ | 内置 Web Crypto API |\n| HTTP 页面 | ❌ | 浏览器安全限制 |\n| Node.js <18 | ❌ | 需升级版本 |\n\n```typescript\nif (!globalThis.crypto?.subtle) {\n  throw new Error('idAgent.from() requires Web Crypto API (crypto.subtle). Use HTTPS in browsers.')\n}\n```\n资料来源：[src/deterministic.ts:15-17](https://github.com/vostride/id-agent/blob/main/src/deterministic.ts#L15-L17)\n\n## 最佳实践\n\n### 生产环境推荐配置\n\n```typescript\n// 高安全性场景\nconst secureId = await idAgent.from(userId, {\n  words: 8,        // 默认值，96 bits 熵值\n  prefix: 'user',\n  namespace: process.env.APP_NAMESPACE\n})\n\n// 平衡可读性与安全性\nconst balancedId = await idAgent.from(resourceId, {\n  words: 5,        // 60 bits，适合大多数应用\n  prefix: 'resource'\n})\n```\n\n### 常见错误处理\n\n```typescript\ntry {\n  const id = await idAgent.from('')\n} catch (e) {\n  // Error: input must be a non-empty string\n}\n\ntry {\n  const id = await idAgent.from('input', { words: 20 })\n} catch (e) {\n  // ZodError: Number must be less than or equal to 16\n}\n```\n\n## 与随机 ID 对比\n\n| 特性 | 确定性 ID (`from`) | 随机 ID (`idAgent()`) |\n|------|-------------------|----------------------|\n| 输入要求 | 任意字符串 | 无 |\n| 可复现性 | ✅ 相同输入 → 相同输出 | ❌ 每次不同 |\n| Web Crypto | ✅ 必须 | ❌ 可选 |\n| 适用场景 | 用户/内容标识 | 会话/临时 ID |\n| 熵值来源 | HMAC-SHA256 | CSPRNG |\n\n资料来源：[src/generate.ts](https://github.com/vostride/id-agent/blob/main/src/generate.ts)\n\n---\n\n<a id='page-parsing-validation'></a>\n\n## 解析与验证\n\n### 相关页面\n\n相关主题：[随机 ID 生成](#page-id-generation), [Zod 验证架构](#page-schemas-validation)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/parse.ts](https://github.com/vostride/id-agent/blob/main/src/parse.ts)\n- [src/detect.ts](https://github.com/vostride/id-agent/blob/main/src/detect.ts)\n- [src/alias.ts](https://github.com/vostride/id-agent/blob/main/src/alias.ts)\n- [src/deterministic.ts](https://github.com/vostride/id-agent/blob/main/src/deterministic.ts)\n- [src/wordlist.ts](https://github.com/vostride/id-agent/blob/main/src/wordlist.ts)\n- [scripts/validate-wordlist.ts](https://github.com/vostride/id-agent/blob/main/scripts/validate-wordlist.ts)\n- [package.json](https://github.com/vostride/id-agent/blob/main/package.json)\n</details>\n\n# 解析与验证\n\n## 概述\n\n解析与验证模块是 id-agent 项目中处理 ID 字符串的核心功能组件。该模块负责将人类可读的 ID 字符串解析为其组成成分，并检验其是否符合 id-agent 规范的格式要求。解析功能支持连字符分隔和下划线分隔两种格式，能够提取出前缀、单词数组、单词数量和熵位数等信息。验证功能则确保生成的 ID 仅包含有效的单词，并且格式完全符合规范要求。\n\n在 id-agent 的整体架构中，解析与验证模块扮演着基础设施的角色，被别名映射（AliasMap）、确定性 ID 生成（deterministicId）以及重复检测（detectDuplicates）等多个功能模块所依赖。这种设计确保了整个系统在处理 ID 字符串时拥有一致性的验证标准和数据格式。\n\n## 核心 API\n\n### parse 函数\n\n`parse` 函数是解析模块的入口函数，用于将 id-agent 格式的 ID 字符串分解为其组成成分。该函数支持连字符分隔（如 `task_storm-delta-stone`）和下划线分隔（如 `task_storm_delta_stone`）两种格式，并能够智能识别前缀与单词部分的分隔方式。\n\n函数返回的对象包含以下属性：prefix 表示 ID 的前缀类型（如 `task`），若不存在前缀则返回 `undefined`；words 是一个字符串数组，包含 ID 中的所有单词；wordCount 表示单词的数量；bits 表示总熵位数，计算公式为 `words.length * 12`；raw 保存原始输入字符串；format 字段标识输入格式为 `readable`。当输入字符串无法被识别为有效的 id-agent 格式时，函数返回 `null`。\n\n```typescript\nimport { parse } from 'id-agent'\n\nparse('task_storm-delta-stone')\n// => { prefix: 'task', words: ['storm', 'delta', 'stone'], wordCount: 3, bits: 36, raw: 'task_storm-delta-stone', format: 'readable' }\n\nparse('task_storm_delta_stone')\n// => { prefix: 'task', words: ['storm', 'delta', 'stone'], wordCount: 3, bits: 36, raw: 'task_storm_delta_stone', format: 'readable' }\n```\n\n解析算法首先尝试按下划线分割字符串，取第一部分作为候选前缀。若第一部分仅包含小写字母和数字，则将其识别为有效前缀；否则整个字符串将被视为纯单词序列。单词提取阶段通过正则表达式匹配连续的纯小写字母单词序列，支持连字符或下划线作为单词间的分隔符。这种双重格式支持使得 id-agent 能够兼容不同来源和风格的 ID 命名约定。\n\n资料来源：[src/parse.ts:1-30]()\n\n### validate 函数\n\n`validate` 函数用于检验给定的字符串是否为合法的 id-agent ID。该函数执行多层次的验证检查，包括大写字符检测、无效字符检测、格式识别以及单词有效性验证。只有通过全部检查的 ID 才会被标记为有效。\n\n验证流程首先检查字符串是否包含大写字符。id-agent 规范要求所有字符必须为小写，因此任何大写字母的出现都会导致验证失败并返回 `contains uppercase characters` 错误信息。资料来源：[src/parse.ts:41-43]()\n\n接下来验证字符串是否包含非法字符。有效字符集限于小写字母、数字、连字符和下划线。若发现其他字符，函数返回 `contains invalid characters` 错误。资料来源：[src/parse.ts:44-46]()\n\n然后调用 `parse` 函数尝试解析 ID。若解析失败（返回 `null`），说明字符串不符合 id-agent 的基本格式要求，验证将返回 `unrecognized format` 错误。资料来源：[src/parse.ts:47-49]()\n\n最后一项验证是单词词汇表检查。解析成功后，函数会逐一检查每个单词是否存在于 id-agent 的 4096 词单词列表中。若发现任何未知单词，返回 `unknown words: ${invalid.join(', ')}` 错误信息，列出所有无效单词。资料来源：[src/parse.ts:50-58]()\n\n```typescript\nimport { validate } from 'id-agent'\n\nvalidate('storm-delta-stone')\n// => { valid: true, prefix: undefined, wordCount: 3 }\n\nvalidate('task_jump-notaword')\n// => { valid: false, reason: 'unknown words: notaword' }\n\nvalidate('INVALID')\n// => { valid: false, reason: 'contains uppercase characters' }\n```\n\n成功验证时返回的对象包含 `valid: true`、可选的 `prefix` 字段以及 `wordCount` 表示单词数量。这种结构化的返回方式便于调用方根据验证结果进行后续处理，同时保留了必要的元数据信息。\n\n## 重复检测功能\n\n### detectDuplicates 函数\n\n`detectDuplicates` 函数提供在文本中扫描重复 ID 的能力。该函数是纯函数实现，不涉及文件系统访问，仅依赖正则表达式进行模式匹配，因此可以在任何环境中安全使用。资料来源：[src/detect.ts:1-27]()\n\n函数接受一个包含 `pattern` 和 `text` 两个属性的选项对象。`pattern` 是一个正则表达式，用于匹配待检测的 ID 格式；`text` 可以是单个字符串或字符串数组，函数会统一处理两种输入形式。资料来源：[src/detect.ts:3-7]()\n\n重复检测的工作流程首先将 `text` 参数统一转换为数组形式，然后遍历每一段文本使用正则表达式进行全局匹配。正则表达式的 `g` 标志确保能够找到所有匹配项，同时代码会确保匹配器始终以全局模式运行。资料来源：[src/detect.ts:8-19]()\n\n检测结果以数组形式返回，每个元素是一个包含 `id` 和 `count` 属性的对象。`id` 字段保存重复出现的 ID 字符串，`count` 字段表示该 ID 在文本中出现的次数。仅当 `count > 1` 时，结果才会被包含在返回值中，这意味着函数默认过滤掉仅出现一次的 ID。资料来源：[src/detect.ts:20-26]()\n\n```typescript\nimport { detectDuplicates } from 'id-agent'\n\nconst dupes = detectDuplicates({\n  pattern: /[a-z]+(?:-[a-z]+)+/,\n  text: 'Found storm-delta-stone in file A and storm-delta-stone in file B',\n})\n// => [{ id: 'storm-delta-stone', count: 2 }]\n\nconst dupes2 = detectDuplicates({\n  pattern: /task_[a-z]+(?:-[a-z]+)+/,\n  text: ['const x = \"task_red-fox-run\"', 'const y = \"task_red-fox-run\"'],\n})\n```\n\n该函数在实际应用场景中具有广泛的用途，包括但不限于：检测代码库中是否存在重复的 ID 定义、验证测试数据中的 ID 唯一性、以及在数据迁移过程中确保 ID 不发生冲突。纯函数的设计使其特别适合在持续集成环境中作为自动化检查工具使用。\n\n## 别名映射系统\n\n### createAliasMap 函数\n\n`createAliasMap` 函数创建一个双向别名映射系统，用于在 LLM 上下文中实现令牌节省。该系统将长格式的原始标识符（如 UUID）映射为短格式的单词别名，并在需要时能够精确恢复原始值。资料来源：[src/alias.ts:1-67]()\n\n别名映射对象提供三个核心方法：`set(original)` 用于添加新的映射关系并返回生成的别名；`get(alias)` 根据别名查找原始值；`replace(text, options)` 批量替换文本中所有已注册的标识符；`restore(text)` 恢复被替换的标识符。\n\n```typescript\nimport { createAliasMap } from 'id-agent'\n\nconst aliases = createAliasMap({ words: 3 })\naliases.set('8cdda07b-85d2-459c-8a2a-83c8f9245dbe')\n// => \"storm-delta-stone\" (3 random words from WORDLIST)\n\naliases.get('storm-delta-stone')\n// => \"8cdda07b-85d2-459c-8a2a-83c8f9245dbe\"\n\nconst text = 'Process 8cdda07b-85d2-459c-8a2a-83c8f9245dbe then 6ba7b810-9dad-11d1-80b4-00c04fd430c8'\nconst shortened = aliases.replace(text, {\n  pattern: /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi\n})\n// => \"Process storm-delta-stone then cloud-train-scope\"\n\nconst restored = aliases.restore(shortened)\n// => original text\n```\n\n`set` 方法内部维护两个映射表：`forward` 将原始值映射到别名，`reverse` 将别名映射回原始值。当添加新的映射时，方法首检查是否存在已有映射以避免重复生成。若启用冲突允许选项，在生成别名时会进行碰撞检测。资料来源：[src/alias.ts:19-31]()\n\n`replace` 方法支持可选的正则表达式参数，若提供则仅替换匹配该模式的字符串。这种设计允许调用方精确控制替换范围，避免意外替换不应被处理的文本内容。资料来源：[src/alias.ts:32-50]()\n\n## 单词列表系统\n\n### WORDLIST 常量\n\n`WORDLIST` 是 id-agent 项目精心策划的 4096 词单词列表，每个单词都经过验证恰好是 o200k_base 分词器（GPT-4o、GPT-4.1 等模型使用）的单个 BPE 令牌。这个特性是 id-agent 实现令牌效率的基础。资料来源：[src/wordlist.ts](https://github.com/vostride/id-agent/blob/main/src/wordlist.ts)\n\n单词列表构建过程包含多个严格的筛选阶段。首先从 o200k_base 词汇表中提取所有 3-6 个字符的候选单词，然后与系统词典进行交叉验证确保词汇的有效性。资料来源：[scripts/build-wordlist.ts:30-50]()\n\n接下来进行两项 BPE 令牌验证：单令牌编码测试确保单词独立编码为单个令牌；连字符前缀测试确保单词在与其他内容连接时不会产生额外的令牌分割。资料来源：[scripts/build-wordlist.ts:51-65]()\n\n最后进行语义过滤，使用 obscenity 库检测并移除不适当的词汇，同时人工审查移除同音异义词（如 \"wait\" 和 \"weight\"），避免在口语环境中造成混淆。资料来源：[scripts/build-wordlist.ts:66-90]()\n\n```typescript\nimport { WORDLIST } from 'id-agent'\n\nWORDLIST.length          // => 4096\nObject.isFrozen(WORDLIST) // => true\n```\n\n单词列表以冻结数组形式导出，确保在运行期间不可被修改。这种不可变性保证了解析和验证结果的确定性和可靠性。\n\n### validate-wordlist.ts 验证脚本\n\n`scripts/validate-wordlist.ts` 是项目提供的单词列表验证工具，用于确保 WORDLIST 满足所有令牌效率和安全要求。该脚本通过编程方式验证列表中每个单词的特性。\n\n验证包含两个主要检查：单令牌验证确保每个单词编码为恰好一个 BPE 令牌；连字符前缀验证确保单词在与其他内容连接时保持令牌边界。资料来源：[scripts/validate-wordlist.ts:1-25]()\n\n脚本输出详细的验证报告，包括通过检查的项目数量和失败的单词列表（若存在）。所有检查通过时输出 `ALL CHECKS PASSED`，否则列出失败数量并返回非零退出码。\n\n```bash\npnpm run validate\n```\n\n开发者可以通过运行此脚本快速验证单词列表的完整性，在修改单词列表或升级分词器版本后尤其重要。\n\n## 数据结构\n\n### 解析结果类型\n\n| 字段 | 类型 | 描述 |\n|------|------|------|\n| `prefix` | `string \\| undefined` | ID 前缀，若无前缀则为 undefined |\n| `words` | `string[]` | 单词数组 |\n| `wordCount` | `number` | 单词数量 |\n| `bits` | `number` | 总熵位数（wordCount × 12） |\n| `raw` | `string` | 原始输入字符串 |\n| `format` | `'readable'` | 格式标识 |\n\n### 验证结果类型\n\n| 字段 | 类型 | 描述 |\n|------|------|------|\n| `valid` | `boolean` | 验证是否通过 |\n| `prefix` | `string \\| undefined` | 解析得到的前缀（仅在 valid 为 true 时） |\n| `wordCount` | `number` | 单词数量（仅在 valid 为 true 时） |\n| `reason` | `string` | 验证失败原因（仅在 valid 为 false 时） |\n\n### 重复检测结果类型\n\n| 字段 | 类型 | 描述 |\n|------|------|------|\n| `id` | `string` | 重复出现的 ID 值 |\n| `count` | `number` | 出现次数 |\n\n## 验证流程图\n\n```mermaid\ngraph TD\n    A[输入字符串] --> B{包含大写字符?}\n    B -->|是| E[返回 invalid: contains uppercase characters]\n    B -->|否| C{包含无效字符?}\n    C -->|是| F[返回 invalid: contains invalid characters]\n    C -->|否| D{格式可解析?}\n    D -->|否| G[返回 invalid: unrecognized format]\n    D -->|是| H{所有单词在词表中?}\n    H -->|否| I[返回 invalid: unknown words]\n    H -->|是| J[返回 valid: true]\n    \n    style J fill:#90EE90\n    style E fill:#FFB6C1\n    style F fill:#FFB6C1\n    style G fill:#FFB6C1\n    style I fill:#FFB6C1\n```\n\n## 架构关系图\n\n```mermaid\ngraph LR\n    A[用户输入] --> B[parse 函数]\n    A --> C[validate 函数]\n    B --> D{解析成功?}\n    D -->|否| E[返回 null]\n    D -->|是| F[返回解析结果]\n    \n    C --> G{多层验证}\n    G --> H[大写检测]\n    G --> I[字符检测]\n    G --> J[格式解析]\n    G --> K[词表验证]\n    \n    F --> L[别名映射系统]\n    F --> M[确定性生成]\n    C --> N[重复检测]\n    \n    H --> O{通过?}\n    I --> P{通过?}\n    J --> Q{通过?}\n    K --> R{通过?}\n    \n    O -->|否| S[验证失败]\n    P -->|否| S\n    Q -->|否| S\n    R -->|否| S\n    \n    O -->|是| T{下一检测}\n    P -->|是| T\n    Q -->|是| T\n    R -->|是| U[验证成功]\n```\n\n## 依赖关系\n\n解析与验证模块的正常运作依赖于以下核心组件：单词列表（WORDLIST）提供词汇验证所需的参考数据，`src/wordlist.ts` 导出包含 4096 个有效单词的冻结数组；密码学模块（crypto）提供 `selectRandomWords` 函数用于别名映射中的随机单词选择。资料来源：[src/alias.ts:2]()\n\n验证选项使用 Zod 进行模式验证，确保用户输入的参数符合预期的类型和约束。资料来源：[package.json:29-30]()\n\n## 使用建议\n\n在实际项目中集成解析与验证功能时，建议遵循以下最佳实践。首先，对于需要频繁验证的场景（如 API 输入验证），可以在应用启动时创建单词集合（Set）以加速查找操作，尽管 id-agent 内部已经优化了验证流程。\n\n其次，在使用 `detectDuplicates` 检测重复时，正则表达式的设计应当精确匹配目标 ID 格式，避免误匹配其他类似格式的字符串。建议为不同类型的 ID 使用专用的模式定义。\n\n第三，别名映射系统适合在 LLM 对话场景中使用，通过 `createAliasMap` 创建的映射可以在多轮对话中复用，减少令牌消耗。确保在对话开始时注册所有需要处理的标识符，然后在对话结束时使用 `restore` 方法恢复原始值。\n\n最后，对于安全敏感的应用场景，验证模块应作为防御性编程的一部分，在接收外部输入的 ID 时始终调用 `validate` 函数进行检查，切勿仅依赖格式解析结果假设 ID 有效。\n\n---\n\n<a id='page-wordlist-design'></a>\n\n## 词表设计\n\n### 相关页面\n\n相关主题：[随机 ID 生成](#page-id-generation), [安装与快速开始](#page-installation)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/wordlist.ts](https://github.com/vostride/id-agent/blob/main/src/wordlist.ts)\n- [scripts/validate-wordlist.ts](https://github.com/vostride/id-agent/blob/main/scripts/validate-wordlist.ts)\n- [scripts/build-wordlist.ts](https://github.com/vostride/id-agent/blob/main/scripts/build-wordlist.ts)\n- [src/parse.ts](https://github.com/vostride/id-agent/blob/main/src/parse.ts)\n- [src/deterministic.ts](https://github.com/vostride/id-agent/blob/main/src/deterministic.ts)\n</details>\n\n# 词表设计\n\nid-agent 的词表（Wordlist）是生成人类可读 ID 的核心组件，由 4096 个精心筛选的英文单词组成。本文档详细介绍词表的设计目标、构建流程、质量标准和使用方式。\n\n## 概述\n\nid-agent 的词表是一个经过多轮筛选的 4096 词集合，每个单词恰好对应 o200k_base 分词器中的一个 BPE token。这意味着使用该词表生成的 ID 在 token 效率上远优于传统的 UUID 或十六进制字符串。\n\n词表的核心设计原则：\n\n- **熵值保证**：每个单词贡献 12 bits 熵值（log₂(4096) = 12）\n- **分词友好**：所有单词在主流 LLM 分词器中都是单 token\n- **可读性**：单词长度控制在 3-6 个字符\n- **安全性**：过滤了冒犯性词汇和同音异义词\n- **不可变性**：词表数组被冻结（frozen），不可修改\n\n资料来源：[src/wordlist.ts:1]()\n\n## 构建流程\n\n词表的构建是一个六阶段的筛选过程，每一阶段都有明确的质量目标：\n\n```mermaid\ngraph TD\n    A[o200k_base 词汇表] --> B[长度过滤 3-6字符]\n    B --> C[系统词典验证]\n    C --> D[BPE 单token验证]\n    D --> E[连字符前缀验证]\n    E --> F[冒犯词过滤]\n    F --> G[同音异义词去重]\n    G --> H[4096词最终词表]\n```\n\n### 第一阶段：候选词提取\n\n从 o200k_base BPE 词汇表中提取所有 3-6 个小写字母组成的单词作为候选词。这一阶段通常产生数万个候选词。\n\n```typescript\nconst parts = o200k_base.bpe_ranks.split(' ')\nconst candidateSet = new Set<string>()\n\nfor (const b64 of parts) {\n  if (!b64.trim()) continue\n  const bytes = Buffer.from(b64, 'base64')\n  const text = bytes.toString('utf-8')\n  const word = text.startsWith(' ') ? text.slice(1) : text\n  if (/^[a-z]{3,6}$/.test(word)) candidateSet.add(word)\n}\n```\n\n资料来源：[scripts/build-wordlist.ts:45-58]()\n\n### 第二阶段：词典过滤\n\n使用系统词典 `/usr/share/dict/words` 验证候选词的有效性，确保每个单词都是真实存在的英文单词。\n\n```typescript\nconst dictFiltered = candidates.filter((w) => dictWords.has(w))\n```\n\n资料来源：[scripts/build-wordlist.ts:69-78]()\n\n### 第三阶段：单 Token 验证\n\n使用 `js-tiktoken` 库验证每个单词在 o200k_base 分词器中是否恰好编码为单个 token。这是确保 token 效率的关键步骤。\n\n```typescript\nconst enc = new Tiktoken(o200k_base)\nconst singleToken = dictFiltered.filter((w) => enc.encode(w).length === 1)\n```\n\n资料来源：[scripts/build-wordlist.ts:79-82]()\n\n### 第四阶段：连字符前缀验证\n\n验证单词在添加连字符前缀后仍保持高效编码（不超过 2 个 token）。这是为了确保生成的 ID（如 `storm-delta-stone`）在 LLM 上下文中保持 token 效率。\n\n```typescript\nconst hyphenValid = singleToken.filter((w) => enc.encode('-' + w).length <= 2)\n```\n\n资料来源：[scripts/build-wordlist.ts:83-85]()\n\n### 第五阶段：冒犯词过滤\n\n使用 `obscenity` 库检测并过滤冒犯性词汇，同时维护一个手动屏蔽列表：\n\n```typescript\nconst MANUAL_BLOCKLIST = [\n  'ass', 'crap', 'damn', 'hell', 'slut', 'rape', 'kill', 'die',\n  'fag', 'gay', 'drug', 'dumb', 'lame', 'nazi', 'pimp', 'porn',\n  'poop', 'puke', 'sexy', 'sick', 'anus', 'cunt', 'dick', 'tit',\n  'tits', 'boob', 'piss', 'shit', 'cock', 'whore', 'bitch',\n  'bastard', 'bloody', 'bugger', 'tosser', 'wank', 'twat',\n  'arse', 'shag', 'meth', 'heroin', 'crack', 'coke', 'weed',\n]\n\nconst matcher = new RegExpMatcher({\n  ...englishDataset.build(),\n  ...englishRecommendedTransformers,\n})\n\nconst cleanWords = hyphenValid.filter((w) => {\n  if (manualBlockSet.has(w)) return false\n  if (matcher.hasMatch(w)) return false\n  return true\n})\n```\n\n资料来源：[scripts/build-wordlist.ts:87-106]()\n\n### 第六阶段：同音异义词去重\n\n过滤同音异义词（homophones），避免因拼写相似造成的混淆：\n\n```typescript\nconst HOMOPHONE_GROUPS = [\n  ['air', 'heir'],\n  ['ate', 'eight'],\n  ['bare', 'bear'],\n  ['be', 'bee'],\n  ['blue', 'blew'],\n  ['buy', 'by', 'bye'],\n  ['cell', 'sell'],\n  ['cent', 'sent', 'scent'],\n  ['dear', 'deer'],\n  ['deer', 'dear'],\n  ['die', 'dye'],\n  ['eye', 'i'],\n  ['fair', 'fare'],\n  ['faze', 'phase'],\n  ['find', 'fined'],\n  ['flea', 'flee'],\n  ['flew', 'flu', 'flue'],\n  ['for', 'fore', 'four'],\n  ['gait', 'gate'],\n  ['greek', 'greak'],\n  ['hair', 'hare'],\n  ['hare', 'hair'],\n  ['hall', 'haul'],\n  ['heal', 'heel', 'heil'],\n  ['hear', 'here'],\n  ['him', 'hym'],\n  ['hym', 'him'],\n  ['isle', 'aisle'],\n  ['knead', 'kneed', 'need'],\n  ['knew', 'gnu'],\n  ['know', 'no'],\n  ['leach', 'leech'],\n  ['loan', 'lone'],\n  ['mail', 'male'],\n  ['main', 'mane', 'mean'],\n  ['meat', 'meet', 'mete'],\n  ['medal', 'meddle', 'metal'],\n  ['mede', 'meed'],\n  ['miner', 'minor'],\n  ['missed', 'mist'],\n  ['mist', 'missed'],\n  ['naval', 'navel'],\n  ['nude', 'newed'],\n  ['overdo', 'overdue'],\n  ['pail', 'pale'],\n  ['pain', 'pane'],\n  ['pair', 'pear', 'pare'],\n  ['palate', 'palette', 'pallet'],\n  ['pare', 'pair', 'pear'],\n  ['passed', 'past'],\n  ['past', 'passed'],\n  ['paten', 'pattern'],\n  ['pause', 'paws', 'pores', 'pours'],\n  ['peace', 'piece'],\n  ['pear', 'pair', 'pare'],\n  ['peer', 'pier'],\n  ['pores', 'pause', 'paws', 'pours'],\n  ['pour', 'pore', 'paw'],\n  ['pours', 'pause', 'paws', 'pores'],\n  ['pray', 'prey'],\n  ['principal', 'principle'],\n  ['rain', 'reign', 'rein'],\n  ['raise', 'rays', 'raze', 'reis'],\n  ['rapt', 'wrapped'],\n  ['reign', 'rain', 'rein'],\n  ['rein', 'rain', 'reign'],\n  ['rider', 'writer'],\n  ['right', 'rite', 'write', 'wright'],\n  ['road', 'rode', 'rowed'],\n  ['roe', 'row'],\n  ['role', 'roll'],\n  ['roux', 'rue'],\n  ['rows', 'rose'],\n  ['rye', 'wry'],\n  ['sail', 'sale'],\n  ['scene', 'seen'],\n  ['sea', 'see', 'si'],\n  ['seas', 'sees', 'seize'],\n  ['seize', 'seas', 'sees'],\n  ['senses', 'censes'],\n  ['sew', 'sough', 'so'],\n  ['sewn', 'sown'],\n  ['shear', 'sheer'],\n  ['shoe', 'shoo'],\n  ['side', 'sighed'],\n  ['sighed', 'side'],\n  ['sign', 'sine'],\n  ['sine', 'sign'],\n  ['sla', 'sley'],\n  ['sleigh', 'slay'],\n  ['slight', 'sleight'],\n  ['sley', 'sla'],\n  ['sole', 'soul'],\n  ['some', 'sum'],\n  ['son', 'sun'],\n  ['sown', 'sewn'],\n  ['stare', 'stair'],\n  ['stair', 'stare'],\n  ['stake', 'steak'],\n  ['steak', 'stake'],\n  ['steal', 'steel'],\n  ['steel', 'steal'],\n  ['step', 'steppe'],\n  ['steppe', 'step'],\n  ['stew', 'stoo', 'stu'],\n  ['stu', 'stew', 'stoo'],\n  ['stoo', 'stew', 'stu'],\n  ['suite', 'sweet', 'swete', 'sweat'],\n  ['sweet', 'suite', 'swete', 'sweat'],\n  ['swete', 'suite', 'sweet', 'sweat'],\n  ['tack', 'tact'],\n  ['tale', 'tail', 'tael'],\n  ['tail', 'tale', 'tael'],\n  ['tare', 'tear', 'tier'],\n  ['team', 'teem'],\n  ['tear', 'tare', 'tier'],\n  ['teem', 'team'],\n  ['teems', 'themes'],\n  ['their', 'there', 'theyre'],\n  ['threw', 'through'],\n  ['throe', 'throw'],\n  ['throne', 'thrown'],\n  ['thrown', 'throne'],\n  ['tide', 'tied'],\n  ['tied', 'tide'],\n  ['tier', 'tare', 'tear'],\n  ['tile', 'trial'],\n  ['to', 'too', 'two'],\n  ['told', 'tolled'],\n  ['tolled', 'told'],\n  ['tone', 'towan'],\n  ['towan', 'tone'],\n  ['tray', 'trey'],\n  ['tread', 'tred'],\n  ['tred', 'tread'],\n  ['treek', 'trig'],\n  ['trig', 'treek'],\n  ['troth', 'truth'],\n  ['vane', 'vain', 'vein'],\n  ['vain', 'vane', 'vein'],\n  ['vein', 'vain', 'vane'],\n  ['wade', 'weighed'],\n  ['wait', 'weight'],\n  ['war', 'wore'],\n  ['waste', 'waist'],\n  ['way', 'weigh'],\n  ['weak', 'week'],\n  ['wear', 'where'],\n  ['wood', 'would'],\n]\n```\n\n资料来源：[scripts/build-wordlist.ts:32-43]()\n\n## 质量标准\n\n词表必须满足以下质量标准：\n\n| 标准 | 要求 | 验证方法 |\n|------|------|----------|\n| 词汇数量 | 恰好 4096 个 | 构建脚本最终输出验证 |\n| 单词长度 | 3-6 个字符 | 正则表达式 `/^[a-z]{3,6}$/` |\n| 分词效率 | 单 token（o200k_base） | js-tiktoken 编码测试 |\n| 连字符效率 | ≤2 tokens（-prefix） | js-tiktoken 编码测试 |\n| 词库有效性 | 存在于系统词典 | `/usr/share/dict/words` |\n| 安全性 | 无冒犯词 | obscenity 库 + 手动列表 |\n| 可读性 | 无同音异义词 | 手动同音词组列表 |\n| 不可变性 | frozen 数组 | `Object.isFrozen(WORDLIST)` |\n\n## 词表导出与使用\n\n### 导出格式\n\n词表以 TypeScript 常量形式导出，位于 `src/wordlist.ts`：\n\n```typescript\nexport const WORDLIST = [\n  'abb',\n  'abel',\n  'abets',\n  'abhor',\n  'abide',\n  'abler',\n  // ... 共 4096 个单词\n] as const\n\n// 冻结数组确保不可变\nObject.freeze(WORDLIST)\n```\n\n资料来源：[src/wordlist.ts:1]()\n\n### 使用方式\n\n词表在内部模块中被广泛使用：\n\n**随机 ID 生成**（用于 `createAliasMap` 等功能）：\n\n```typescript\nexport function createAliasMap(opts: AliasOptions): AliasMap {\n  const { words, allowCollision } = AliasOptionsSchema.parse(opts)\n  // ...\n  alias = selectRandomWords(words, WORDLIST).join('-')\n  // ...\n}\n```\n\n资料来源：[src/alias.ts:1-25]()\n\n**确定性 ID 生成**（使用 HMAC-SHA256）：\n\n```typescript\nexport async function deterministicId(input: string, opts?: IdAgentFromOptions): Promise<string> {\n  // ...\n  for (let i = 0; i < words; i++) {\n    selected[i] = WORDLIST[view.getUint16(i * 2) % 4096]\n  }\n  return formatId(validated.prefix, selected.join('-'))\n}\n```\n\n资料来源：[src/deterministic.ts:1-38]()\n\n### ID 解析与验证\n\n词表也用于验证和解析生成的 ID：\n\n```typescript\nexport function validate(id: string): ValidateResult {\n  // ...\n  if (parsed.words.length > 0) {\n    const invalid = parsed.words.filter(w => !wordSet.has(w))\n    if (invalid.length > 0) {\n      return { valid: false, reason: `unknown words: ${invalid.join(', ')}` }\n    }\n  }\n  // ...\n}\n```\n\n资料来源：[src/parse.ts:1-25]()\n\n## 验证脚本\n\n### validate-wordlist.ts\n\n构建完成后，使用验证脚本确认词表质量：\n\n```typescript\n// 验证单 token 编码\nconst singleTokenFails = allWords.filter(w => enc.encode(w).length !== 1)\n\n// 验证连字符前缀编码\nconst hyphenFails = singleTokenFails.filter(w => enc.encode('-' + w).length > 2)\n\ncheck(`All words are single BPE tokens (failures: ${singleTokenFails.length})`, singleTokenFails.length === 0)\ncheck(`All words pass hyphen-prefix test (failures: ${hyphenFails.length})`, hyphenFails.length === 0)\n```\n\n资料来源：[scripts/validate-wordlist.ts:1-20]()\n\n### 运行验证\n\n```bash\npnpm run validate\n```\n\n## 词表设计决策\n\n### 为什么选择 4096 个单词？\n\n- **数学基础**：4096 = 2¹²，每个单词贡献恰好 12 bits 熵值\n- **空间效率**：4096 个条目可存储在 12 位索引中（2 字节）\n- **映射便利**：确定性 ID 生成中，HMAC-SHA256 输出的 16 位字可映射到 4096 个单词（取模运算）\n\n### 为什么限制 3-6 个字符？\n\n- **BPE 兼容性**：在这个长度范围内的单词更可能在 o200k_base 中成为单 token\n- **可读性平衡**：过短的单词（如 \"a\"、\"I\"）增加同音词冲突；过长的单词增加 token 消耗\n- **ID 紧凑性**：较短的单词使生成的 ID 更紧凑易读\n\n### 为什么过滤同音异义词？\n\n在口语交流或听觉场景下，同音异义词（如 \"there\"/\"their\"/\"they're\"）会造成混淆。id-agent 主要用于 AI 上下文，但保持这种过滤可以：\n\n- 减少口头沟通歧义\n- 避免拼写相似性导致的视觉混淆\n- 提高 ID 的整体可读性\n\n## 总结\n\nid-agent 的词表设计是一个精心策划的多阶段流程，确保最终产出的 4096 个单词满足分词效率、可读性、安全性和不可变性等多重质量标准。这个词表是实现高 token 效率和人类可读 ID 生成的核心基础设施。\n\n词表在运行时被冻结，任何对 ID 格式的验证都依赖词表内容，这种设计保证了系统的一致性和可预测性。\n\n---\n\n<a id='page-crypto-module'></a>\n\n## 加密模块\n\n### 相关页面\n\n相关主题：[随机 ID 生成](#page-id-generation), [确定性 ID 生成](#page-deterministic-ids)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/crypto.ts](https://github.com/vostride/id-agent/blob/main/src/crypto.ts)\n- [src/generate.ts](https://github.com/vostride/id-agent/blob/main/src/generate.ts)\n- [src/deterministic.ts](https://github.com/vostride/id-agent/blob/main/src/deterministic.ts)\n- [src/alias.ts](https://github.com/vostride/id-agent/blob/main/src/alias.ts)\n- [src/wordlist.ts](https://github.com/vostride/id-agent/blob/main/src/wordlist.ts)\n</details>\n\n# 加密模块\n\n## 概述\n\nid-agent 的加密模块是整个库的核心安全基础，负责生成密码学安全的随机数并将其映射到人类可读的单词列表。该模块采用双重加密策略：\n\n1. **随机 ID 生成**：使用 Web Crypto API 的 CSPRNG（密码学安全伪随机数生成器）\n2. **确定性 ID 生成**：使用 HMAC-SHA256 哈希函数实现输入到 ID 的确定性映射\n\n加密模块的核心价值在于确保 ID 的唯一性和不可预测性，同时保持人类可读性和令牌效率。\n\n## 架构设计\n\n```mermaid\ngraph TD\n    A[输入] --> B{ID类型选择}\n    B -->|随机| C[随机ID生成流程]\n    B -->|确定性| D[确定性ID生成流程]\n    \n    C --> E[crypto.getRandomValues]\n    E --> F[从WORDLIST映射]\n    F --> G[格式化输出]\n    \n    D --> H[TextEncoder编码输入]\n    H --> I[HMAC-SHA256签名]\n    I --> J[DataView读取哈希]\n    J --> K[取模映射到WORDLIST]\n    K --> G\n    \n    G --> L[最终ID格式<br/>如: storm-delta-stone]\n```\n\n## 随机 ID 生成\n\n### 核心实现\n\n随机 ID 生成依赖浏览器的 `crypto.getRandomValues()` 方法，这是 Web Crypto API 提供的密码学安全随机数接口。 资料来源：[src/generate.ts:6-12]()\n\n```typescript\nfunction createIdAgent(): IdAgent {\n  const fn = ((opts?: IdAgentOptions): string => {\n    const validated = IdAgentOptionsSchema.parse(opts ?? {})\n    const words = validated.words ?? 8\n    const selected = selectRandomWords(words, WORDLIST)\n    return formatId(validated.prefix, selected.join('-'))\n  }) as IdAgent\n  // ...\n}\n```\n\n### 随机词选择机制\n\n`selectRandomWords` 函数从 4096 个单词的词表中选择随机单词。该函数内部调用 `crypto.getRandomValues()` 获取密码学安全的随机字节，然后通过取模运算将随机数映射到词表索引。 资料来源：[src/generate.ts:4-5]()\n\n### 安全性保证\n\n随机 ID 生成的安全性来源于：\n\n| 保障措施 | 说明 |\n|---------|------|\n| CSPRNG | 使用浏览器原生的 `crypto.getRandomValues()`，确保随机数不可预测 |\n| 均匀分布 | 取模运算确保每个词被选中的概率完全相等 |\n| 独立选择 | 每个词的位置独立随机选择，互不影响 |\n\n## 确定性 ID 生成\n\n### 核心实现\n\n确定性 ID 生成使用 HMAC-SHA256 算法，通过 Web Crypto API 实现。相同的输入总是产生相同的 ID，适用于需要可重现性的场景。 资料来源：[src/deterministic.ts:1-10]()\n\n```typescript\nexport async function deterministicId(input: string, opts?: IdAgentFromOptions): Promise<string> {\n  if (!input || typeof input !== 'string') {\n    throw new Error('input must be a non-empty string')\n  }\n  const validated = IdAgentFromOptionsSchema.parse(opts ?? {})\n  const words = validated.words ?? 8\n\n  if (!globalThis.crypto?.subtle) {\n    throw new Error('idAgent.from() requires Web Crypto API (crypto.subtle). Use HTTPS in browsers.')\n  }\n  // ...\n}\n```\n\n### HMAC-SHA256 签名流程\n\n```mermaid\ngraph LR\n    A[输入字符串] --> B[TextEncoder]\n    B --> C[UTF-8字节]\n    C --> D[crypto.subtle.importKey]\n    D --> E[HMAC密钥]\n    C --> F[crypto.subtle.sign]\n    E --> F\n    F --> G[256位签名]\n    G --> H[DataView读取]\n    H --> I[每16位取模4096]\n    I --> J[映射到WORDLIST]\n```\n\n### 关键步骤解析\n\n1. **密钥导入**：使用命名空间（默认 \"id-agent\"）作为 HMAC 密钥，确保不同应用的输出不会冲突 资料来源：[src/deterministic.ts:16-20]()\n\n2. **签名生成**：对输入字符串进行 HMAC-SHA256 签名，输出 256 位（32 字节）的签名 资料来源：[src/deterministic.ts:21-22]()\n\n3. **词表映射**：从签名中每 16 位（2 字节）读取一个无符号整数，对 4096 取模得到词表索引 资料来源：[src/deterministic.ts:23-27]()\n\n```typescript\nconst sig = await globalThis.crypto.subtle.sign('HMAC', key, enc.encode(input))\nconst view = new DataView(sig)\n\nconst selected: string[] = new Array(words)\nfor (let i = 0; i < words; i++) {\n  selected[i] = WORDLIST[view.getUint16(i * 2) % 4096]\n}\n```\n\n### 命名空间隔离\n\n确定性 ID 支持自定义命名空间实现域分离：\n\n```typescript\nconst id1 = await idAgent.from('user@example.com')\nconst id2 = await idAgent.from('user@example.com', { namespace: 'different-app' })\n// id1 !== id2\n```\n\n这允许同一输入在不同命名空间下产生不同的确定性 ID。 资料来源：[src/deterministic.ts:12]()\n\n## 别名映射模块\n\n别名映射模块利用加密随机数生成短别名，用于减少 LLM 上下文中的令牌消耗。 资料来源：[src/alias.ts:1-8]()\n\n### 别名生成算法\n\n```mermaid\ngraph TD\n    A[原始ID] --> B{ID已存在?}\n    B -->|是| C[返回已有别名]\n    B -->|否| D[生成新别名]\n    D --> E[selectRandomWords]\n    E --> F[从WORDLIST选择词]\n    F --> G{别名冲突?}\n    G -->|是| D\n    G -->|否| H[存储forward/reverse映射]\n    H --> I[返回别名]\n```\n\n### 加密安全保障\n\n别名映射同样使用 `selectRandomWords` 从 CSPRNG 获取随机数，确保别名不可预测。即使原始 ID 已知，也无法推断别名（除非存在映射表）。 资料来源：[src/alias.ts:2]()\n\n```typescript\nexport function createAliasMap(opts: AliasOptions): AliasMap {\n  const { words, allowCollision } = AliasOptionsSchema.parse(opts)\n  const forward = new Map<string, string>()\n  const reverse = new Map<string, string>()\n  \n  // ...\n  do {\n    alias = selectRandomWords(words, WORDLIST).join('-')\n  } while (reverse.has(alias) && !allowCollision)\n  // ...\n}\n```\n\n## 词表设计\n\n### 词表规格\n\n| 属性 | 值 | 说明 |\n|-----|-----|------|\n| 词数 | 4096 | 2^12，便于位运算映射 |\n| 每词熵 | 12 bits | log2(4096) = 12 |\n| 单词字符数 | 3-6 字符 | 经 o200k_base 分词器验证 |\n| 令牌效率 | 每词 1 token | 针对 o200k_base 优化 |\n\n### 词表约束\n\n词表经过多重过滤确保安全性和可用性：\n\n1. **词典验证**：所有单词必须存在于系统词典 `/usr/share/dict/words`\n2. **同音词过滤**：移除如 `wait`/`weight`、`weak`/`week` 等易混淆的同音词\n3. **冒犯性词汇移除**：使用 `obscenity` 库过滤不适当词汇\n4. **单令牌验证**：每个词在 o200k_base 分词器中恰好为 1 个 token\n\n## API 参考\n\n### 随机 ID 生成\n\n```typescript\nconst id = idAgent()                    // 默认 8 词 ID\nconst id5 = idAgent({ words: 5 })       // 5 词 ID\nconst idPrefixed = idAgent({ prefix: 'user', words: 4 })\n```\n\n### 确定性 ID 生成\n\n```typescript\nconst id = await idAgent.from('user@example.com')\nconst idCustom = await idAgent.from('user@example.com', {\n  namespace: 'my-app',\n  prefix: 'user',\n  words: 5\n})\n```\n\n### 别名映射\n\n```typescript\nconst aliases = createAliasMap({ words: 3 })\nconst alias = aliases.set('8cdda07b-85d2-459c-8a2a-83c8f9245dbe')\nconst original = aliases.get('storm-delta-stone')\n```\n\n## 安全注意事项\n\n| 场景 | 建议 |\n|------|------|\n| 浏览器环境 | 确保使用 HTTPS，Web Crypto API 在不安全上下文中不可用 |\n| 服务端环境 | Node.js 18+ 已原生支持 Web Crypto API |\n| 确定性 ID 命名空间 | 生产环境应使用唯一的命名空间避免冲突 |\n| 别名碰撞 | 默认情况下别名生成会避免碰撞，可通过 `allowCollision: true` 禁用 |\n\n## 性能特性\n\n- **随机 ID 生成**：同步操作，约 0.1-0.5ms\n- **确定性 ID 生成**：异步操作，约 1-5ms（首次调用需初始化 HMAC 密钥）\n- **别名映射**：O(1) 查找和插入\n\n## 与 UUID 的对比\n\n| 特性 | UUID v4 | id-agent (8词) |\n|------|---------|----------------|\n| 熵 | 122 bits | 96 bits |\n| 令牌数 | ~23 | ~11 |\n| 令牌节省 | - | ~52% |\n| 50%碰撞阈值 | ~2.7 * 10^18 | ~300 trillion |\n| 人类可读性 | 低 | 高 |\n\n---\n\n<a id='page-schemas-validation'></a>\n\n## Zod 验证架构\n\n### 相关页面\n\n相关主题：[解析与验证](#page-parsing-validation), [随机 ID 生成](#page-id-generation)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/schemas.ts](https://github.com/vostride/id-agent/blob/main/src/schemas.ts)\n- [src/types.ts](https://github.com/vostride/id-agent/blob/main/src/types.ts)\n- [src/parse.ts](https://github.com/vostride/id-agent/blob/main/src/parse.ts)\n- [src/deterministic.ts](https://github.com/vostride/id-agent/blob/main/src/deterministic.ts)\n- [src/alias.ts](https://github.com/vostride/id-agent/blob/main/src/alias.ts)\n</details>\n\n# Zod 验证架构\n\n## 概述\n\nid-agent 使用 Zod 作为核心验证库，版本为 4.3.6，构建了一套完整的输入验证体系。该验证架构覆盖了所有公开 API 的用户输入，确保数据类型安全、参数合法，并提供清晰的错误信息。\n\n**核心设计目标：**\n\n- 在开发阶段捕获无效输入，防止运行时错误\n- 提供人类可读的错误消息，帮助开发者快速定位问题\n- 保持类型安全，实现编译时与运行时的双重保障\n- 通过模式复用减少验证代码重复\n\n**依赖配置：**\n\n```json\n\"dependencies\": {\n  \"zod\": \"4.3.6\"\n}\n```\n\n资料来源：[package.json:25-27](https://github.com/vostride/id-agent/blob/main/package.json)\n\n---\n\n## 验证模式分类\n\nid-agent 的验证架构围绕三个核心 Schema 构建，分别服务于不同的功能模块。\n\n### 模式层级关系\n\n```mermaid\ngraph TD\n    A[用户输入] --> B[IdAgentOptionsSchema]\n    A --> C[IdAgentFromOptionsSchema]\n    A --> D[AliasOptionsSchema]\n    B --> E[创建随机 ID]\n    C --> F[创建确定性 ID]\n    D --> G[别名映射管理]\n    E --> H[验证通过]\n    F --> H\n    G --> H\n```\n\n### Schema 清单\n\n| Schema 名称 | 用途 | 使用场景 |\n|------------|------|---------|\n| `IdAgentOptionsSchema` | 随机 ID 生成选项 | `new IdAgent(opts?)` |\n| `IdAgentFromOptionsSchema` | 确定性 ID 生成选项 | `idAgent.from(input, opts?)` |\n| `AliasOptionsSchema` | 别名映射选项 | `createAliasMap(opts)` |\n\n---\n\n## IdAgentOptionsSchema\n\n用于验证随机 ID 生成的配置参数。这是用户创建 IdAgent 实例时的输入验证层。\n\n### 参数定义\n\n| 参数 | 类型 | 默认值 | 约束条件 | 说明 |\n|------|------|--------|----------|------|\n| `prefix` | `string \\| undefined` | `undefined` | 小写字母数字组合 | ID 类型前缀 |\n| `words` | `number` | `8` | 1-16 整数 | 单词数量，控制熵值 |\n\n### 验证规则\n\n```typescript\n// 伪代码表示验证逻辑\nprefix?: string  // 可选，若提供则必须是 lowercase alphanumeric\nwords?: number   // 可选，默认 8，范围 [1, 16]\n```\n\n**前缀验证：** 必须是纯小写字母和数字组成，不允许大写字符、下划线以外的特殊字符。\n\n**单词数验证：** 整数值必须在 1 到 16 之间。单词数直接决定 ID 的熵值：`总比特数 = words × 12`。\n\n### 错误处理\n\n当验证失败时，Zod 抛出 `ZodError`，包含详细的错误路径和消息。\n\n```typescript\n// 无效配置示例\nnew IdAgent({ words: 20 })    // 超出范围\nnew IdAgent({ prefix: 'USER' }) // 包含大写字母\n```\n\n资料来源：[src/schemas.ts](https://github.com/vostride/id-agent/blob/main/src/schemas.ts) 和 [src/deterministic.ts:7](https://github.com/vostride/id-agent/blob/main/src/deterministic.ts)\n\n---\n\n## IdAgentFromOptionsSchema\n\n用于验证确定性 ID 生成（基于 HMAC-SHA256）的配置参数。与随机 ID 不同，确定性生成需要额外的命名空间支持。\n\n### 参数定义\n\n| 参数 | 类型 | 默认值 | 约束条件 | 说明 |\n|------|------|--------|----------|------|\n| `prefix` | `string \\| undefined` | `undefined` | 小写字母数字组合 | ID 类型前缀 |\n| `words` | `number` | `8` | 1-16 整数 | 单词数量 |\n| `namespace` | `string` | `'id-agent'` | 非空字符串 | HMAC 密钥，用于域分离 |\n\n### 验证流程\n\n```typescript\nconst validated = IdAgentFromOptionsSchema.parse(opts ?? {})\nconst words = validated.words ?? 8  // 默认值处理\nconst namespace = validated.namespace ?? 'id-agent'\n```\n\n### 命名空间机制\n\n命名空间参数实现了域分离功能，相同的输入在不同命名空间下产生不同的 ID：\n\n```typescript\nconst id1 = await idAgent.from('user@example.com', { namespace: 'app1' })\nconst id2 = await idAgent.from('user@example.com', { namespace: 'app2' })\n// id1 !== id2\n```\n\n资料来源：[src/deterministic.ts:6-10](https://github.com/vostride/id-agent/blob/main/src/deterministic.ts)\n\n---\n\n## AliasOptionsSchema\n\n用于验证别名映射功能的配置参数。别名映射是 LLM 上下文优化的高级功能。\n\n### 参数定义\n\n| 参数 | 类型 | 默认值 | 约束条件 | 说明 |\n|------|------|--------|----------|------|\n| `words` | `number` | 是 | 1-16 整数 | 别名使用的单词数 |\n| `allowCollision` | `boolean` | `false` | 布尔值 | 是否允许别名碰撞 |\n\n### 别名生成逻辑\n\n```mermaid\ngraph LR\n    A[原始 ID] --> B{forward Map<br/>已有映射?}\n    B -->|是| C[返回已有别名]\n    B -->|否| D[生成新别名]\n    D --> E{反向 Map<br/>存在冲突?}\n    E -->|是 且 !allowCollision| D\n    E -->|否 或 allowCollision| F[存储映射]\n    F --> G[返回别名]\n```\n\n### 碰撞处理\n\n当 `allowCollision` 为 `false`（默认）时，系统保证别名映射的双射性质，即每个原始 ID 映射到唯一别名，每个别名映射回唯一原始 ID。\n\n资料来源：[src/alias.ts:4-9](https://github.com/vostride/id-agent/blob/main/src/alias.ts)\n\n---\n\n## ID 验证流程\n\n### validate 函数\n\n`validate` 函数是 ID 验证的核心入口，用于检查任意字符串是否为有效的 id-agent ID。\n\n### 验证步骤\n\n```mermaid\ngraph TD\n    A[输入字符串] --> B{包含大写字母?}\n    B -->|是| Z[无效: contains uppercase characters]\n    B -->|否| C{包含无效字符?}\n    C -->|是| Y[无效: contains invalid characters]\n    C -->|否| D[调用 parse 函数]\n    D --> E{解析结果为 null?}\n    E -->|是| X[无效: unrecognized format]\n    E -->|否| F{存在未知单词?}\n    F -->|是| W[无效: unknown words: xxx]\n    F -->|否| V[验证通过]\n```\n\n### 验证规则详解\n\n| 步骤 | 检查项 | 错误消息 | 正则表达式 |\n|------|--------|----------|------------|\n| 1 | 大写字母 | `contains uppercase characters` | `/[A-Z]/` |\n| 2 | 无效字符 | `contains invalid characters` | `/[^a-z0-9_-]/` |\n| 3 | 格式识别 | `unrecognized format` | parse 返回 null |\n| 4 | 词汇表验证 | `unknown words: {word}` | wordSet 查询 |\n\n### 验证结果类型\n\n```typescript\ninterface ValidationResult {\n  valid: boolean\n  prefix?: string      // 仅在 valid 为 true 时\n  wordCount?: number   // 仅在 valid 为 true 时\n  reason?: string     // 仅在 valid 为 false 时\n}\n```\n\n### 示例\n\n```typescript\nvalidate('task_storm-delta-stone')\n// => { valid: true, prefix: 'task', wordCount: 3 }\n\nvalidate('task_jump-notaword')\n// => { valid: false, reason: 'unknown words: notaword' }\n\nvalidate('INVALID')\n// => { valid: false, reason: 'contains uppercase characters' }\n```\n\n资料来源：[src/parse.ts:1-20](https://github.com/vostride/id-agent/blob/main/src/parse.ts)\n\n---\n\n## 类型系统集成\n\n### 类型定义架构\n\n```mermaid\ngraph TD\n    A[types.ts] --> B[IdAgentOptions]\n    A --> C[IdAgentFromOptions]\n    A --> D[AliasOptions]\n    A --> E[ValidationResult]\n    B --> F[IdAgentOptionsSchema]\n    C --> G[IdAgentFromOptionsSchema]\n    D --> H[AliasOptionsSchema]\n```\n\n### Schema 与类型对应关系\n\n| Schema | TypeScript 类型 | 来源 |\n|--------|----------------|------|\n| `IdAgentOptionsSchema` | `IdAgentOptions` | [src/types.ts](https://github.com/vostride/id-agent/blob/main/src/types.ts) |\n| `IdAgentFromOptionsSchema` | `IdAgentFromOptions` | [src/types.ts](https://github.com/vostride/id-agent/blob/main/src/types.ts) |\n| `AliasOptionsSchema` | `AliasOptions` | [src/types.ts](https://github.com/vostride/id-agent/blob/main/src/types.ts) |\n\n### 验证执行模式\n\n```typescript\n// 标准模式：使用 .parse()，失败时抛出 ZodError\nconst result = schema.parse(input)\n\n// 安全模式：使用 .safeParse()，返回结果对象\nconst result = schema.safeParse(input)\n```\n\nid-agent 默认使用 `.parse()` 模式，让无效输入直接抛出异常，便于开发阶段快速发现问题。\n\n---\n\n## 错误处理机制\n\n### ZodError 结构\n\n验证失败时抛出的错误对象包含完整的错误路径和上下文信息：\n\n```typescript\ntry {\n  new IdAgent({ words: 100 })\n} catch (error) {\n  if (error instanceof ZodError) {\n    console.log(error.errors)\n    // [{\n    //   code: \"too_big\",\n    //   maximum: 16,\n    //   type: \"number\",\n    //   path: [\"words\"],\n    //   message: \"Number must be less than or equal to 16\"\n    // }]\n  }\n}\n```\n\n### 错误码映射\n\n| Zod 错误码 | 触发条件 | 示例消息 |\n|-----------|---------|---------|\n| `too_small` | 值小于最小值 | `Number must be greater than or equal to 1` |\n| `too_big` | 值大于最大值 | `Number must be less than or equal to 16` |\n| `invalid_type` | 类型不匹配 | `Expected string, received number` |\n| `unrecognized_keys` | 包含未知键 | `Unrecognized key: unknownOption` |\n\n---\n\n## 验证性能考量\n\n### 模式编译\n\nZod Schema 在首次使用时进行编译，后续调用直接使用优化后的验证逻辑。id-agent 的 Schema 定义简洁，验证开销极低。\n\n### 词汇表查询优化\n\nID 验证中的词汇表检查使用 Set 数据结构：\n\n```typescript\nconst wordSet = new Set(WORDLIST)  // O(1) 查找\n```\n\n`WORDLIST` 包含 4096 个单词，Set 查询复杂度为 O(1)，验证 3-16 个单词的总复杂度为 O(n)，其中 n 为单词数量。\n\n---\n\n## 架构优势\n\n### 类型安全层次\n\n```\nTypeScript Compiler          Zod Runtime\n      │                            │\n      ▼                            ▼\n   类型定义 ──────────────────► Schema 定义\n   (编译期)                      (运行期)\n      │                            │\n      ▼                            ▼\n   IDE 提示                  实际验证\n   类型检查                  错误抛出\n```\n\n### 可维护性\n\n- Schema 集中定义于 `schemas.ts`\n- 类型集中定义于 `types.ts`\n- 验证逻辑与业务逻辑分离\n- 新增参数只需修改 Schema 定义\n\n### 开发者体验\n\n- 清晰的错误消息指明问题所在\n- 与 TypeScript 类型系统无缝集成\n- 支持 IDE 自动补全\n\n---\n\n## 相关资源\n\n- [Zod 官方文档](https://zod.dev)\n- [源码：schemas.ts](https://github.com/vostride/id-agent/blob/main/src/schemas.ts)\n- [源码：types.ts](https://github.com/vostride/id-agent/blob/main/src/types.ts)\n- [源码：parse.ts](https://github.com/vostride/id-agent/blob/main/src/parse.ts)\n\n---\n\n<a id='page-alias-system'></a>\n\n## 别名系统\n\n### 相关页面\n\n相关主题：[重复检测](#page-duplicate-detection), [随机 ID 生成](#page-id-generation)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/alias.ts](https://github.com/vostride/id-agent/blob/main/src/alias.ts)\n- [src/parse.ts](https://github.com/vostride/id-agent/blob/main/src/parse.ts)\n- [src/wordlist.ts](https://github.com/vostride/id-agent/blob/main/src/wordlist.ts)\n- [src/detect.ts](https://github.com/vostride/id-agent/blob/main/src/detect.ts)\n- [README.md](https://github.com/vostride/id-agent/blob/main/README.md)\n</details>\n\n# 别名系统\n\n## 概述\n\n别名系统（Alias System）是 id-agent 提供的一种高效令牌压缩机制，旨在将长标识符（如 UUID）映射为短小的、基于单词的别名，以便在 LLM 上下文中的传输。系统支持完整的双向映射、文本替换和还原功能。\n\n别名系统通过 `createAliasMap()` 工厂函数创建，返回一个 `AliasMap` 实例，该实例提供 `set()`、`get()`、`replace()`、`restore()` 和 `entries()` 等核心方法。\n\n资料来源：[src/alias.ts:3-10]()\n\n## 核心概念\n\n### 设计目标\n\n别名系统解决了 LLM 应用中的两个关键问题：\n\n1. **令牌效率**：长 UUID（如 `8cdda07b-85d2-459c-8a2a-83c8f9245dbe`）在 BPE 分词器中需要约 23 个令牌，而 3 个单词的别名（如 `storm-delta-stone`）仅需约 5 个令牌，节省约 78% 的令牌开销。\n\n2. **可读性**：单词形式的 ID 更容易在调试日志、API 响应和 LLM 输出中理解和引用。\n\n资料来源：[README.md](https://github.com/vostride/id-agent/blob/main/README.md)\n\n### 工作原理\n\n别名系统内部维护两个 Map 数据结构：\n- **正向映射**（forward）：存储原始 ID → 别名\n- **反向映射**（reverse）：存储别名 → 原始 ID\n\n```mermaid\ngraph LR\n    A[原始ID<br/>8cdda07b-85d2-...] -->|set| B[正向Map]\n    B -->|生成| C[别名<br/>storm-delta-stone]\n    C -->|存储| D[反向Map]\n    D -->|get| A\n```\n\n资料来源：[src/alias.ts:8-10]()\n\n## API 参考\n\n### createAliasMap(options?)\n\n创建别名映射实例。\n\n```typescript\nimport { createAliasMap } from 'id-agent'\n\nconst aliases = createAliasMap({ words: 3 })\n```\n\n#### 参数选项\n\n| 参数 | 类型 | 默认值 | 必填 | 描述 |\n|------|------|--------|------|------|\n| `words` | `number` | `8` | 否 | 每个别名的单词数量（1-16） |\n| `allowCollision` | `boolean` | `false` | 否 | 是否允许别名冲突 |\n\n资料来源：[src/alias.ts:3-6]()\n\n### AliasMap 实例方法\n\n#### set(original: string): string\n\n为给定的原始 ID 生成并存储一个别名。相同原始 ID 多次调用返回相同的别名。\n\n```typescript\nconst alias1 = aliases.set('8cdda07b-85d2-459c-8a2a-83c8f9245dbe')\n// => \"storm-delta-stone\"\n\nconst alias2 = aliases.set('8cdda07b-85d2-459c-8a2a-83c8f9245dbe')\n// => \"storm-delta-stone\" (相同)\n```\n\n资料来源：[src/alias.ts:12-18]()\n\n#### get(alias: string): string | undefined\n\n根据别名查询对应的原始 ID。\n\n```typescript\naliases.get('storm-delta-stone')\n// => \"8cdda07b-85d2-459c-8a2a-83c8f9245dbe\"\n```\n\n资料来源：[src/alias.ts:20-22]()\n\n#### replace(text: string, options?): string\n\n将文本中所有匹配指定模式的原始 ID 替换为对应的别名。\n\n```typescript\nconst text = 'Process 8cdda07b-85d2-459c-8a2a-83c8f9245dbe then 6ba7b810-9dad-11d1-80b4-00c04fd430c8'\nconst shortened = aliases.replace(text, {\n  pattern: /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi\n})\n// => \"Process storm-delta-stone then cloud-train-scope\"\n```\n\n| 参数 | 类型 | 描述 |\n|------|------|------|\n| `text` | `string` | 要进行替换的文本 |\n| `options.pattern` | `RegExp` | 匹配原始 ID 的正则表达式 |\n\n资料来源：[src/alias.ts:24-37]()\n\n#### restore(text: string): string\n\n将文本中所有别名还原为原始 ID。\n\n```typescript\nconst restored = aliases.restore('Process storm-delta-stone then cloud-train-scope')\n// => \"Process 8cdda07b-85d2-459c-8a2a-83c8f9245dbe then 6ba7b810-9dad-11d1-80b4-00c04fd430c8\"\n```\n\n资料来源：[src/alias.ts:39-41]()\n\n#### entries(): [original, alias][]\n\n返回所有映射对的数组，格式为 `[原始ID, 别名]`。\n\n```typescript\nfor (const [original, alias] of aliases.entries()) {\n  console.log(`${original} => ${alias}`)\n}\n```\n\n> ⚠️ 返回顺序是 `[original, alias]`，而非 `[alias, original]`。如需通过别名查询原始 ID，请使用 `get(alias)` 方法。\n\n资料来源：[README.md](https://github.com/vostride/id-agent/blob/main/README.md)\n\n## 典型使用场景\n\n### LLM 上下文压缩\n\n在向 LLM 发送请求前，将长 UUID 替换为短别名，并在处理完成后还原：\n\n```mermaid\nsequenceDiagram\n    participant App as 应用\n    participant AliasMap as AliasMap\n    participant LLM as LLM\n    participant Output as 输出\n\n    App->>AliasMap: set(uuid1), set(uuid2)\n    App->>AliasMap: replace(requestText)\n    App->>LLM: 发送压缩后的请求\n    LLM-->>App: 返回引用别名的响应\n    App->>AliasMap: restore(responseText)\n    App->>Output: 输出还原后的结果\n```\n\n```typescript\nconst aliases = createAliasMap({ words: 3 })\n\n// 1. 准备阶段：注册所有需要的 ID\naliases.set('8cdda07b-85d2-459c-8a2a-83c8f9245dbe')\naliases.set('6ba7b810-9dad-11d1-80b4-00c04fd430c8')\n\n// 2. 发送给 LLM 前：替换\nconst llmRequest = await sendToLLM(aliases.replace(prompt, {\n  pattern: /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi\n}))\n\n// 3. 处理 LLM 返回后：还原\nconst finalOutput = aliases.restore(llmOutput)\n```\n\n资料来源：[src/alias.ts:24-41]()\n\n### 与重复检测结合\n\n别名系统可与 `detectDuplicates` 功能结合使用，用于在 LLM 输出中检测重复的 ID：\n\n```typescript\nimport { createAliasMap, detectDuplicates } from 'id-agent'\n\nconst aliases = createAliasMap({ words: 3 })\n\n// 检测文本中的重复 ID\nconst dupes = detectDuplicates({\n  pattern: /[a-z]+(?:-[a-z]+)+/,\n  text: 'Found storm-delta-stone in file A and storm-delta-stone in file B',\n})\n// => [{ id: 'storm-delta-stone', count: 2 }]\n```\n\n资料来源：[src/detect.ts:1-21]()\n\n## 内部实现\n\n### 别名生成算法\n\n别名通过 `selectRandomWords` 函数从词表（WORDLIST）中随机选择指定数量的单词生成：\n\n```typescript\nalias = selectRandomWords(words, WORDLIST).join('-')\n```\n\n每个单词贡献 12 比特熵度（因为词表包含 4096 = 2¹² 个单词）。使用 3 个单词的别名提供 36 比特熵度。\n\n| 单词数 | 熵度 | ID 空间 | 典型令牌数 | vs UUID 节省 |\n|--------|------|---------|------------|---------------|\n| 3 | 36 bits | 6.9 × 10¹⁰ | ~5 | 78% |\n| 5 | 60 bits | 1.2 × 10¹⁸ | ~8 | 65% |\n| 8 | 96 bits | 7.9 × 10²⁸ | ~11 | 52% |\n\n资料来源：[src/wordlist.ts](https://github.com/vostride/id-agent/blob/main/src/wordlist.ts) 和 [README.md](https://github.com/vostride/id-agent/blob/main/README.md)\n\n### 替换正则构建\n\n`replace()` 方法内部按长度降序排序所有已注册的原始 ID，确保较长的 ID 优先匹配，避免部分匹配问题：\n\n```typescript\nfunction buildReplacementRegex(keys: string[]): RegExp | null {\n  if (keys.length === 0) return null\n  const sorted = [...keys].sort((a, b) => b.length - a.length)\n  const escaped = sorted.map(s => s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'))\n  return new RegExp(escaped.join('|'), 'g')\n}\n```\n\n例如，如果同时注册了 `abc` 和 `abcd`，会优先匹配 `abcd`。\n\n资料来源：[src/alias.ts:8-11]()\n\n### 冲突处理\n\n默认情况下，`set()` 方法会检查生成的别名是否已存在（通过 `reverse.has(alias)`）。如果发生冲突，会重新生成：\n\n```typescript\ndo {\n  alias = selectRandomWords(words, WORDLIST).join('-')\n} while (reverse.has(alias) && !allowCollision)\n```\n\n通过设置 `allowCollision: true` 可以禁用此检查，允许不同的原始 ID 共享相同别名（不推荐）。\n\n资料来源：[src/alias.ts:14-16]()\n\n## 最佳实践\n\n### 词数选择指南\n\n| 使用场景 | 建议词数 | 熵度 | 适用规模 |\n|----------|----------|------|----------|\n| 开发/测试 | 3 | 36 bits | < 309K items |\n| 小型应用 | 5 | 60 bits | < 1B items |\n| 生产 SaaS | 5 | 60 bits | < 1B items |\n| 高流量/分布式 | 8 (默认) | 96 bits | < 300T items |\n\n### 生命周期管理\n\n```mermaid\ngraph TD\n    A[创建 AliasMap] --> B[注册所有 ID]\n    B --> C{处理}\n    C -->|发送 LLM | D[replace]\n    C -->|接收响应 | E[restore]\n    D --> F[LLM 处理]\n    F --> E\n    E --> G{更多请求?}\n    G -->|是| C\n    G -->|否| H[销毁 AliasMap]\n```\n\n1. **预先注册**：在处理任何文本前，先通过 `set()` 注册所有需要用到的原始 ID\n2. **重用实例**：在整个会话期间复用同一个 AliasMap 实例\n3. **统一模式**：使用统一的正则表达式进行 `replace()` 和 `restore()`\n\n资料来源：[src/alias.ts:12-22]()\n\n## 错误处理\n\n别名系统使用 Zod 进行配置验证：\n\n```typescript\nconst { words, allowCollision } = AliasOptionsSchema.parse(opts)\n```\n\n无效选项会抛出 `ZodError`，并附带描述性错误信息。有效的 `words` 范围为 1-16。\n\n资料来源：[src/alias.ts:4]()\n\n## 与其他模块的关系\n\n```mermaid\ngraph TB\n    Alias[别名系统<br/>src/alias.ts] --> Crypto[加密模块<br/>src/crypto.ts]\n    Alias --> Wordlist[词表<br/>src/wordlist.ts]\n    Alias --> Parse[解析模块<br/>src/parse.ts]\n    Parse --> Validate[验证模块<br/>src/validate.ts]\n    Detect[重复检测<br/>src/detect.ts] -.->|组合使用| Alias\n    \n    classDef primary fill:#e1f5fe\n    class Alias primary\n```\n\n- **依赖 `selectRandomWords`**：别名生成使用加密安全的随机数生成器\n- **依赖 WORDLIST**：从 4096 个预验证单词中选择\n- **可与 `detectDuplicates` 组合**：检测 LLM 输出中的重复别名\n\n资料来源：[src/alias.ts:2-3]() 和 [src/parse.ts:1-3]()\n\n---\n\n<a id='page-duplicate-detection'></a>\n\n## 重复检测\n\n### 相关页面\n\n相关主题：[别名系统](#page-alias-system), [解析与验证](#page-parsing-validation)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/detect.ts](https://github.com/vostride/id-agent/blob/main/src/detect.ts)\n- [README.md](https://github.com/vostride/id-agent/blob/main/README.md)\n</details>\n\n# 重复检测\n\n## 概述\n\n重复检测（Duplicate Detection）是 id-agent 提供的核心功能之一，用于扫描文本内容中的重复 ID。该功能设计为纯函数，不依赖文件系统访问，适用于在 LLM 上下文中检测重复标识符、验证数据一致性以及在分布式系统中识别潜在的 ID 冲突问题。\n\n重复检测模块位于 `src/detect.ts`，通过正则表达式模式匹配来识别文本中出现的重复标识符。资料来源：[src/detect.ts:1-24]()\n\n## 工作原理\n\n### 核心算法流程\n\n重复检测采用基于正则表达式的模式匹配策略，通过以下步骤完成重复 ID 的识别：\n\n```mermaid\ngraph TD\n    A[输入: pattern + text] --> B{text 类型判断}\n    B -->|string| C[转换为数组: text]\n    B -->|string[]| D[直接使用数组]\n    C --> E[初始化 Map 和 RegExp]\n    D --> E\n    E --> F[遍历每个文本]\n    F --> G[重置 lastIndex]\n    G --> H[执行正则匹配]\n    H --> I{找到匹配?}\n    I -->|是| J[更新 Map 计数]\n    I -->|否| K{还有文本?}\n    J --> K\n    K -->|是| F\n    K -->|否| L[过滤 count > 1]\n    L --> M[返回 Duplicate 数组]\n    I -->|否| K\n```\n\n### 关键设计决策\n\n1. **纯函数设计**：不产生副作用，不访问外部状态，确保测试可重复性和并发安全性\n2. **自动补全全局标志**：如果用户提供的正则表达式缺少 `g` 标志，函数会自动添加，确保能够匹配所有出现位置\n3. **lastIndex 重置**：每次处理新文本前重置正则表达式的 `lastIndex`，避免跨文本匹配时的状态污染\n4. **灵活输入支持**：支持单个字符串或字符串数组作为输入源\n\n## API 参考\n\n### detectDuplicates 函数签名\n\n```typescript\nfunction detectDuplicates(opts: DetectOptions): Duplicate[]\n```\n\n### 类型定义\n\n| 类型 | 描述 |\n|------|------|\n| `DetectOptions` | 检测配置选项，包含匹配模式和待检测文本 |\n| `Duplicate` | 重复检测结果，包含 ID 字符串和出现次数 |\n\n### 参数配置\n\n| 参数 | 类型 | 必填 | 描述 |\n|------|------|------|------|\n| `pattern` | `RegExp` | 是 | 用于匹配 ID 的正则表达式模式 |\n| `text` | `string \\| string[]` | 是 | 待扫描的文本内容，可以是单个字符串或字符串数组 |\n\n### 返回值\n\n返回 `Duplicate[]` 数组，每个元素包含：\n\n| 字段 | 类型 | 描述 |\n|------|------|------|\n| `id` | `string` | 重复的 ID 字符串 |\n| `count` | `number` | 该 ID 出现的次数（仅包含 count > 1 的项） |\n\n## 使用示例\n\n### 基本用法：检测字符串中的重复 ID\n\n```typescript\nimport { detectDuplicates } from 'id-agent'\n\nconst dupes = detectDuplicates({\n  pattern: /[a-z]+(?:-[a-z]+)+/,\n  text: 'Found storm-delta-stone in file A and storm-delta-stone in file B',\n})\n// 返回值: [{ id: 'storm-delta-stone', count: 2 }]\n```\n\n资料来源：[README.md]()\n\n### 多文本检测：分析代码仓库中的重复项\n\n```typescript\nimport { detectDuplicates } from 'id-agent'\n\nconst dupes = detectDuplicates({\n  pattern: /task_[a-z]+(?:-[a-z]+)+/,\n  text: [\n    'const x = \"task_red-fox-run\"',\n    'const y = \"task_red-fox-run\"',\n  ],\n})\n```\n\n### 结合 UUID 模式检测\n\n```typescript\nimport { detectDuplicates } from 'id-agent'\n\nconst dupes = detectDuplicates({\n  pattern: /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi,\n  text: [\n    'Task A: 8cdda07b-85d2-459c-8a2a-83c8f9245dbe',\n    'Task B: 8cdda07b-85d2-459c-8a2a-83c8f9245dbe', // 重复\n    'Task C: 6ba7b810-9dad-11d1-80b4-00c04fd430c8',\n  ],\n})\n// 返回值: [{ id: '8cdda07b-85d2-459c-8a2a-83c8f9245dbe', count: 2 }]\n```\n\n## 实现细节\n\n### 源代码解析\n\n以下为核心实现代码（资料来源：[src/detect.ts:5-24]()）：\n\n```typescript\nexport function detectDuplicates(opts: DetectOptions): Duplicate[] {\n  const texts = typeof opts.text === 'string' ? [opts.text] : opts.text\n  const idMap = new Map<string, number>()\n  const re = new RegExp(\n    opts.pattern.source,\n    opts.pattern.flags.includes('g') ? opts.pattern.flags : opts.pattern.flags + 'g',\n  )\n\n  for (const text of texts) {\n    re.lastIndex = 0\n    let match\n    while ((match = re.exec(text)) !== null) {\n      idMap.set(match[0], (idMap.get(match[0]) ?? 0) + 1)\n    }\n  }\n\n  return [...idMap.entries()]\n    .filter(([, count]) => count > 1)\n    .map(([id, count]) => ({ id, count }))\n}\n```\n\n### 全局标志处理逻辑\n\n函数自动确保正则表达式携带 `g`（全局）标志：\n\n```mermaid\ngraph LR\n    A[输入 pattern] --> B{flags 包含 'g'?}\n    B -->|是| C[保持原 flags]\n    B -->|否| D[追加 'g' 标志]\n    C --> E[创建 RegExp]\n    D --> E\n```\n\n## 与其他模块的集成\n\n### 与别名映射系统配合使用\n\n重复检测可以与 `createAliasMap` 配合使用，用于验证映射前后的 ID 一致性：\n\n| 功能 | 函数 | 用途 |\n|------|------|------|\n| 缩短长 ID | `createAliasMap.replace()` | 减少 LLM 上下文中的 token 消耗 |\n| 恢复原始 ID | `createAliasMap.restore()` | 还原别名映射 |\n| 验证唯一性 | `detectDuplicates()` | 检测替换后是否存在重复别名 |\n\n### 典型工作流程\n\n```mermaid\ngraph LR\n    A[原始 UUID 列表] --> B[createAliasMap]\n    B --> C[生成别名映射]\n    C --> D[替换 UUID 为别名]\n    D --> E[发送到 LLM]\n    E --> F[LLM 响应]\n    F --> G[恢复原始 UUID]\n    G --> H[detectDuplicates 验证]\n    H --> I{存在重复?}\n    I -->|是| J[警告/处理冲突]\n    I -->|否| K[处理完成]\n```\n\n## 最佳实践\n\n### 正则表达式编写建议\n\n| 建议 | 说明 | 示例 |\n|------|------|------|\n| 使用捕获组 | 明确指定要匹配的 ID 格式 | `/task_[a-z]+(?:-[a-z]+)+/` |\n| 包含边界符 | 避免部分匹配问题 | `/\\\\b[a-f0-9-]{36}\\\\b/` |\n| 区分大小写 | 根据 ID 规范选择标志 | `i` 标志用于大小写不敏感 |\n| 避免过度贪婪 | 确保匹配精确的 ID 格式 | 使用 `{36}` 而非 `+` |\n\n### 性能优化建议\n\n1. **预编译正则表达式**：如果多次使用相同模式，预先创建正则表达式对象\n2. **批量处理文本**：将多个文本片段合并为数组一次性处理，减少循环开销\n3. **精确的 pattern**：避免过于宽泛的正则表达式，减少不必要的匹配尝试\n\n## 注意事项\n\n### 边界情况处理\n\n| 场景 | 行为 | 说明 |\n|------|------|------|\n| 空字符串输入 | 返回空数组 `[]` | 正则匹配无结果 |\n| 无匹配的文本 | 返回空数组 `[]` | 未发现任何匹配项 |\n| 无重复项 | 返回空数组 `[]` | 所有 ID 都只出现一次 |\n| 数组中有空字符串 | 正常处理 | 空字符串不产生匹配 |\n\n### 限制说明\n\n- 函数不验证匹配到的 ID 是否为有效的 id-agent 格式\n- 如果需要验证 ID 有效性，应额外调用 `validate()` 函数\n- 正则表达式的 `lastIndex` 属性在内部被管理，不会影响外部状态\n\n---\n\n---\n\n## Doramagic 踩坑日志\n\n项目：vostride/id-agent\n\n摘要：发现 8 个潜在踩坑项，其中 0 个为 high/blocking；最高优先级：能力坑 - 能力判断依赖假设。\n\n## 1. 能力坑 · 能力判断依赖假设\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：README/documentation is current enough for a first validation pass.\n- 对用户的影响：假设不成立时，用户拿不到承诺的能力。\n- 建议检查：将假设转成下游验证清单。\n- 防护动作：假设必须转成验证项；没有验证结果前不能写成事实。\n- 证据：capability.assumptions | hn_item:48191852 | https://news.ycombinator.com/item?id=48191852 | README/documentation is current enough for a first validation pass.\n\n## 2. 维护坑 · 维护活跃度未知\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：未记录 last_activity_observed。\n- 对用户的影响：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。\n- 建议检查：补 GitHub 最近 commit、release、issue/PR 响应信号。\n- 防护动作：维护活跃度未知时，推荐强度不能标为高信任。\n- 证据：evidence.maintainer_signals | hn_item:48191852 | https://news.ycombinator.com/item?id=48191852 | last_activity_observed missing\n\n## 3. 安全/权限坑 · 下游验证发现风险项\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：下游已经要求复核，不能在页面中弱化。\n- 建议检查：进入安全/权限治理复核队列。\n- 防护动作：下游风险存在时必须保持 review/recommendation 降级。\n- 证据：downstream_validation.risk_items | hn_item:48191852 | https://news.ycombinator.com/item?id=48191852 | no_demo; severity=medium\n\n## 4. 安全/权限坑 · 存在评分风险\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：风险会影响是否适合普通用户安装。\n- 建议检查：把风险写入边界卡，并确认是否需要人工复核。\n- 防护动作：评分风险必须进入边界卡，不能只作为内部分数。\n- 证据：risks.scoring_risks | hn_item:48191852 | https://news.ycombinator.com/item?id=48191852 | no_demo; severity=medium\n\n## 5. 安全/权限坑 · 来源证据：Consider an alternative wordlist\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：Consider an alternative wordlist\n- 对用户的影响：可能影响授权、密钥配置或安全边界。\n- 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_c1936412c9da41088e71fab995197a90 | https://github.com/vostride/id-agent/issues/2 | 来源类型 github_issue 暴露的待验证使用条件。\n\n## 6. 安全/权限坑 · 来源证据：Python port\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：Python port\n- 对用户的影响：可能影响授权、密钥配置或安全边界。\n- 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_d733a90c7db44b9789900ed24e77220e | https://github.com/vostride/id-agent/issues/1 | 来源讨论提到 python 相关条件，需在安装/试用前复核。\n\n## 7. 维护坑 · issue/PR 响应质量未知\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：issue_or_pr_quality=unknown。\n- 对用户的影响：用户无法判断遇到问题后是否有人维护。\n- 建议检查：抽样最近 issue/PR，判断是否长期无人处理。\n- 防护动作：issue/PR 响应未知时，必须提示维护风险。\n- 证据：evidence.maintainer_signals | hn_item:48191852 | https://news.ycombinator.com/item?id=48191852 | issue_or_pr_quality=unknown\n\n## 8. 维护坑 · 发布节奏不明确\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：release_recency=unknown。\n- 对用户的影响：安装命令和文档可能落后于代码，用户踩坑概率升高。\n- 建议检查：确认最近 release/tag 和 README 安装命令是否一致。\n- 防护动作：发布节奏未知或过期时，安装说明必须标注可能漂移。\n- 证据：evidence.maintainer_signals | hn_item:48191852 | https://news.ycombinator.com/item?id=48191852 | release_recency=unknown\n\n<!-- canonical_name: vostride/id-agent; human_manual_source: deepwiki_human_wiki -->\n",
      "markdown_key": "id-agent",
      "pages": "draft",
      "source_refs": [
        {
          "evidence_id": "hn_item:48191852",
          "kind": "hn",
          "supports_claim_ids": [
            "claim_identity",
            "claim_distribution",
            "claim_capability"
          ],
          "url": "https://news.ycombinator.com/item?id=48191852"
        },
        {
          "evidence_id": "art_c3fd649fb7cd46a79ef2d2301207dcce",
          "kind": "docs",
          "supports_claim_ids": [
            "claim_identity",
            "claim_distribution",
            "claim_capability"
          ],
          "url": "https://github.com/vostride/id-agent#readme"
        }
      ],
      "summary": "DeepWiki/Human Wiki 完整输出，末尾追加 Discovery Agent 踩坑日志。",
      "title": "id-agent 说明书",
      "toc": [
        "https://github.com/vostride/id-agent 项目说明书",
        "目录",
        "项目介绍",
        "概述",
        "核心目标",
        "技术架构",
        "工作原理",
        "API 参考",
        "Doramagic 踩坑日志"
      ]
    }
  },
  "quality_gate": {
    "blocking_gaps": [],
    "category_confidence": "medium",
    "compile_status": "ready_for_review",
    "five_assets_present": true,
    "install_sandbox_verified": true,
    "missing_evidence": [],
    "next_action": "publish to Doramagic.ai project surfaces",
    "prompt_preview_boundary_ok": true,
    "publish_status": "publishable",
    "quick_start_verified": true,
    "repo_clone_verified": true,
    "repo_commit": "22821401b08a9f6edaeecb7cff6915f3abed9632",
    "repo_inspection_error": null,
    "repo_inspection_files": [
      "pnpm-lock.yaml",
      "package.json",
      "README.md",
      "src/generate.ts",
      "src/schemas.ts",
      "src/index.ts",
      "src/types.ts",
      "src/wordlist.ts",
      "src/deterministic.ts",
      "src/alias.ts",
      "src/parse.ts",
      "src/format.ts",
      "src/crypto.ts",
      "src/detect.ts"
    ],
    "repo_inspection_verified": true,
    "review_reasons": [
      "community_discussion_evidence_below_public_threshold"
    ],
    "tag_count_ok": true,
    "unsupported_claims": []
  },
  "schema_version": "0.1",
  "user_assets": {
    "ai_context_pack": {
      "asset_id": "ai_context_pack",
      "filename": "AI_CONTEXT_PACK.md",
      "markdown": "# id-agent - Doramagic AI Context Pack\n\n> 定位：安装前体验与判断资产。它帮助宿主 AI 有一个好的开始，但不代表已经安装、执行或验证目标项目。\n\n## 充分原则\n\n- **充分原则，不是压缩原则**：AI Context Pack 应该充分到让宿主 AI 在开工前理解项目价值、能力边界、使用入口、风险和证据来源；它可以分层组织，但不以最短摘要为目标。\n- **压缩策略**：只压缩噪声和重复内容，不压缩会影响判断和开工质量的上下文。\n\n## 给宿主 AI 的使用方式\n\n你正在读取 Doramagic 为 id-agent 编译的 AI Context Pack。请把它当作开工前上下文：帮助用户理解适合谁、能做什么、如何开始、哪些必须安装后验证、风险在哪里。不要声称你已经安装、运行或执行了目标项目。\n\n## Claim 消费规则\n\n- **事实来源**：Repo Evidence + Claim/Evidence Graph；Human Wiki 只提供显著性、术语和叙事结构。\n- **事实最低状态**：`supported`\n- `supported`：可以作为项目事实使用，但回答中必须引用 claim_id 和证据路径。\n- `weak`：只能作为低置信度线索，必须要求用户继续核实。\n- `inferred`：只能用于风险提示或待确认问题，不能包装成项目事实。\n- `unverified`：不得作为事实使用，应明确说证据不足。\n- `contradicted`：必须展示冲突来源，不得替用户强行选择一个版本。\n\n## 它最适合谁\n\n- **想在安装前理解开源项目价值和边界的用户**：当前证据主要来自项目文档。 证据：`README.md` Claim：`clm_0002` supported 0.86\n\n## 它能做什么\n\n- **命令行启动或安装流程**（需要安装后验证）：项目文档中存在可执行命令，真实使用需要在本地或宿主环境中运行这些命令。 证据：`README.md` Claim：`clm_0001` supported 0.86\n\n## 怎么开始\n\n- `npm install id-agent` 证据：`README.md` Claim：`clm_0003` supported 0.86\n- `pnpm add id-agent` 证据：`README.md` Claim：`clm_0004` supported 0.86\n\n## 继续前判断卡\n\n- **当前建议**：仅建议沙盒试装\n- **为什么**：项目存在安装命令、宿主配置或本地写入线索，不建议直接进入主力环境，应先在隔离环境试装。\n\n### 30 秒判断\n\n- **现在怎么做**：仅建议沙盒试装\n- **最小安全下一步**：先跑 Prompt Preview；若仍要安装，只在隔离环境试装\n- **先别相信**：真实输出质量不能在安装前相信。\n- **继续会触碰**：命令执行、本地环境或项目文件、宿主 AI 上下文\n\n### 现在可以相信\n\n- **适合人群线索：想在安装前理解开源项目价值和边界的用户**（supported）：有 supported claim 或项目证据支撑，但仍不等于真实安装效果。 证据：`README.md` Claim：`clm_0002` supported 0.86\n- **能力存在：命令行启动或安装流程**（supported）：可以相信项目包含这类能力线索；是否适合你的具体任务仍要试用或安装后验证。 证据：`README.md` Claim：`clm_0001` supported 0.86\n- **存在 Quick Start / 安装命令线索**（supported）：可以相信项目文档出现过启动或安装入口；不要因此直接在主力环境运行。 证据：`README.md` Claim：`clm_0003` supported 0.86\n\n### 现在还不能相信\n\n- **真实输出质量不能在安装前相信。**（unverified）：Prompt Preview 只能展示引导方式，不能证明真实项目中的结果质量。\n- **宿主 AI 版本兼容性不能在安装前相信。**（unverified）：Claude、Cursor、Codex、Gemini 等宿主加载规则和版本差异必须在真实环境验证。\n- **不会污染现有宿主 AI 行为，不能直接相信。**（inferred）：Skill、plugin、AGENTS/CLAUDE/GEMINI 指令可能改变宿主 AI 的默认行为。\n- **可安全回滚不能默认相信。**（unverified）：除非项目明确提供卸载和恢复说明，否则必须先在隔离环境验证。\n- **真实安装后是否与用户当前宿主 AI 版本兼容？**（unverified）：兼容性只能通过实际宿主环境验证。\n- **项目输出质量是否满足用户具体任务？**（unverified）：安装前预览只能展示流程和边界，不能替代真实评测。\n- **安装命令是否需要网络、权限或全局写入？**（unverified）：这影响企业环境和个人环境的安装风险。 证据：`README.md`\n\n### 继续会触碰什么\n\n- **命令执行**：包管理器、网络下载、本地插件目录、项目配置或用户主目录。 原因：运行第一条命令就可能产生环境改动；必须先判断是否值得跑。 证据：`README.md`\n- **本地环境或项目文件**：安装结果、插件缓存、项目配置或本地依赖目录。 原因：安装前无法证明写入范围和回滚方式，需要隔离验证。 证据：`README.md`\n- **宿主 AI 上下文**：AI Context Pack、Prompt Preview、Skill 路由、风险规则和项目事实。 原因：导入上下文会影响宿主 AI 后续判断，必须避免把未验证项包装成事实。\n\n### 最小安全下一步\n\n- **先跑 Prompt Preview**：用安装前交互式试用判断工作方式是否匹配，不需要授权或改环境。（适用：任何项目都适用，尤其是输出质量未知时。）\n- **只在隔离目录或测试账号试装**：避免安装命令污染主力宿主 AI、真实项目或用户主目录。（适用：存在命令执行、插件配置或本地写入线索时。）\n- **安装后只验证一个最小任务**：先验证加载、兼容、输出质量和回滚，再决定是否深用。（适用：准备从试用进入真实工作流时。）\n\n### 退出方式\n\n- **保留安装前状态**：记录原始宿主配置和项目状态，后续才能判断是否可恢复。\n- **记录安装命令和写入路径**：没有明确卸载说明时，至少要知道哪些目录或配置需要手动清理。\n- **如果没有回滚路径，不进入主力环境**：不可回滚是继续前阻断项，不应靠信任或运气继续。\n\n## 哪些只能预览\n\n- 解释项目适合谁和能做什么\n- 基于项目文档演示典型对话流程\n- 帮助用户判断是否值得安装或继续研究\n\n## 哪些必须安装后验证\n\n- 真实安装 Skill、插件或 CLI\n- 执行脚本、修改本地文件或访问外部服务\n- 验证真实输出质量、性能和兼容性\n\n## 边界与风险判断卡\n\n- **把安装前预览误认为真实运行**：用户可能高估项目已经完成的配置、权限和兼容性验证。 处理方式：明确区分 prompt_preview_can_do 与 runtime_required。 Claim：`clm_0005` inferred 0.45\n- **命令执行会修改本地环境**：安装命令可能写入用户主目录、宿主插件目录或项目配置。 处理方式：先在隔离环境或测试账号中运行。 证据：`README.md` Claim：`clm_0006` supported 0.86\n- **待确认**：真实安装后是否与用户当前宿主 AI 版本兼容？。原因：兼容性只能通过实际宿主环境验证。\n- **待确认**：项目输出质量是否满足用户具体任务？。原因：安装前预览只能展示流程和边界，不能替代真实评测。\n- **待确认**：安装命令是否需要网络、权限或全局写入？。原因：这影响企业环境和个人环境的安装风险。\n\n## 开工前工作上下文\n\n### 加载顺序\n\n- 先读取 how_to_use.host_ai_instruction，建立安装前判断资产的边界。\n- 读取 claim_graph_summary，确认事实来自 Claim/Evidence Graph，而不是 Human Wiki 叙事。\n- 再读取 intended_users、capabilities 和 quick_start_candidates，判断用户是否匹配。\n- 需要执行具体任务时，优先查 role_skill_index，再查 evidence_index。\n- 遇到真实安装、文件修改、网络访问、性能或兼容性问题时，转入 risk_card 和 boundaries.runtime_required。\n\n### 任务路由\n\n- **命令行启动或安装流程**：先说明这是安装后验证能力，再给出安装前检查清单。 边界：必须真实安装或运行后验证。 证据：`README.md` Claim：`clm_0001` supported 0.86\n\n### 上下文规模\n\n- 文件总数：36\n- 重要文件覆盖：33/36\n- 证据索引条目：33\n- 角色 / Skill 条目：1\n\n### 证据不足时的处理\n\n- **missing_evidence**：说明证据不足，要求用户提供目标文件、README 段落或安装后验证记录；不要补全事实。\n- **out_of_scope_request**：说明该任务超出当前 AI Context Pack 证据范围，并建议用户先查看 Human Manual 或真实安装后验证。\n- **runtime_request**：给出安装前检查清单和命令来源，但不要替用户执行命令或声称已执行。\n- **source_conflict**：同时展示冲突来源，标记为待核实，不要强行选择一个版本。\n\n## Prompt Recipes\n\n### 适配判断\n\n- 目标：判断这个项目是否适合用户当前任务。\n- 预期输出：适配结论、关键理由、证据引用、安装前可预览内容、必须安装后验证内容、下一步建议。\n\n```text\n请基于 id-agent 的 AI Context Pack，先问我 3 个必要问题，然后判断它是否适合我的任务。回答必须包含：适合谁、能做什么、不能做什么、是否值得安装、证据来自哪里。所有项目事实必须引用 evidence_refs、source_paths 或 claim_id。\n```\n\n### 安装前体验\n\n- 目标：让用户在安装前感受核心工作流，同时避免把预览包装成真实能力或营销承诺。\n- 预期输出：一段带边界标签的体验剧本、安装后验证清单和谨慎建议；不含真实运行承诺或强营销表述。\n\n```text\n请把 id-agent 当作安装前体验资产，而不是已安装工具或真实运行环境。\n\n请严格输出四段：\n1. 先问我 3 个必要问题。\n2. 给出一段“体验剧本”：用 [安装前可预览]、[必须安装后验证]、[证据不足] 三种标签展示它可能如何引导工作流。\n3. 给出安装后验证清单：列出哪些能力只有真实安装、真实宿主加载、真实项目运行后才能确认。\n4. 给出谨慎建议：只能说“值得继续研究/试装”“先补充信息后再判断”或“不建议继续”，不得替项目背书。\n\n硬性边界：\n- 不要声称已经安装、运行、执行测试、修改文件或产生真实结果。\n- 不要写“自动适配”“确保通过”“完美适配”“强烈建议安装”等承诺性表达。\n- 如果描述安装后的工作方式，必须使用“如果安装成功且宿主正确加载 Skill，它可能会……”这种条件句。\n- 体验剧本只能写成“示例台词/假设流程”：使用“可能会询问/可能会建议/可能会展示”，不要写“已写入、已生成、已通过、正在运行、正在生成”。\n- Prompt Preview 不负责给安装命令；如用户准备试装，只能提示先阅读 Quick Start 和 Risk Card，并在隔离环境验证。\n- 所有项目事实必须来自 supported claim、evidence_refs 或 source_paths；inferred/unverified 只能作风险或待确认项。\n\n```\n\n### 角色 / Skill 选择\n\n- 目标：从项目里的角色或 Skill 中挑选最匹配的资产。\n- 预期输出：候选角色或 Skill 列表，每项包含适用场景、证据路径、风险边界和是否需要安装后验证。\n\n```text\n请读取 role_skill_index，根据我的目标任务推荐 3-5 个最相关的角色或 Skill。每个推荐都要说明适用场景、可能输出、风险边界和 evidence_refs。\n```\n\n### 风险预检\n\n- 目标：安装或引入前识别环境、权限、规则冲突和质量风险。\n- 预期输出：环境、权限、依赖、许可、宿主冲突、质量风险和未知项的检查清单。\n\n```text\n请基于 risk_card、boundaries 和 quick_start_candidates，给我一份安装前风险预检清单。不要替我执行命令，只说明我应该检查什么、为什么检查、失败会有什么影响。\n```\n\n### 宿主 AI 开工指令\n\n- 目标：把项目上下文转成一次对话开始前的宿主 AI 指令。\n- 预期输出：一段边界明确、证据引用明确、适合复制给宿主 AI 的开工前指令。\n\n```text\n请基于 id-agent 的 AI Context Pack，生成一段我可以粘贴给宿主 AI 的开工前指令。这段指令必须遵守 not_runtime=true，不能声称项目已经安装、运行或产生真实结果。\n```\n\n\n## 角色 / Skill 索引\n\n- 共索引 1 个角色 / Skill / 项目文档条目。\n\n- **id-agent**（project_doc）：id-agent Token efficient IDs for AI agents 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`README.md`\n\n## 证据索引\n\n- 共索引 33 条证据。\n\n- **id-agent**（documentation）：id-agent Token efficient IDs for AI agents 证据：`README.md`\n- **Package**（package_manifest）：{ \"name\": \"id-agent\", \"version\": \"1.0.3\", \"description\": \"Human-readable, token-efficient IDs for AI agent systems\", \"type\": \"module\", \"main\": \"./dist/index.cjs\", \"module\": \"./dist/index.js\", \"types\": \"./dist/index.d.ts\", \"exports\": { \".\": { \"import\": { \"types\": \"./dist/index.d.ts\", \"default\": \"./dist/index.js\" }, \"require\": { \"types\": \"./dist/index.d.cts\", \"default\": \"./dist/index.cjs\" } } }, \"files\": \"dist\", \"README.md\", \"LICENSE\" , \"repository\": { \"type\": \"git\", \"url\": \"git+https://github.com/vostride/id-agent.git\" }, \"homepage\": \"https://github.com/vostride/id-agent readme\", \"bugs\": { \"url\": \"https://github.com/vostride/id-agent/issues\" }, \"keywords\": \"id\", \"identifier\", \"token-efficien… 证据：`package.json`\n- **License**（source_file）：Copyright c 2026 id-agent contributors 证据：`LICENSE`\n- **.Oxlintrc**（structured_config）：{ \"$schema\": \"./node modules/oxlint/configuration schema.json\", \"categories\": { \"correctness\": \"error\", \"suspicious\": \"warn\", \"pedantic\": \"off\" }, \"plugins\": \"typescript\" , \"rules\": { \"no-unused-vars\": \"error\" }, \"ignorePatterns\": \"dist/\" } 证据：`.oxlintrc.json`\n- **.Size Limit**（structured_config）：{ \"path\": \"dist/index.js\", \"limit\": \"15 kB\", \"gzip\": true } 证据：`.size-limit.json`\n- **Dprint**（structured_config）：{ \"typescript\": { \"quoteStyle\": \"preferSingle\", \"semiColons\": \"asi\" }, \"json\": { \"indentWidth\": 2 }, \"includes\": \"src/ / .{ts,js}\", \"tests/ / .ts\", \" .json\", \" .ts\" , \"excludes\": \"dist/\", \"node modules/\", \" -lock. \" , \"plugins\": \"https://plugins.dprint.dev/typescript-0.95.15.wasm\", \"https://plugins.dprint.dev/json-0.21.3.wasm\" } 证据：`dprint.json`\n- **Tsconfig**（structured_config）：{ \"compilerOptions\": { \"target\": \"ES2022\", \"module\": \"ES2022\", \"moduleResolution\": \"bundler\", \"lib\": \"ES2022\" , \"types\": \"node\" , \"declaration\": true, \"strict\": true, \"esModuleInterop\": true, \"skipLibCheck\": true, \"forceConsistentCasingInFileNames\": true, \"outDir\": \"dist\", \"rootDir\": \"src\", \"isolatedModules\": true, \"resolveJsonModule\": false, \"noEmit\": true }, \"include\": \"src\" , \"exclude\": \"node modules\", \"dist\" } 证据：`tsconfig.json`\n- **.gitignore**（source_file）：.planning/ node modules/ dist/ .tsbuildinfo .dprint/ .claude/ 证据：`.gitignore`\n- **.npmignore**（source_file）：.planning/ tests/ scripts/ src/ .github/ .oxlintrc.json dprint.json tsconfig.json tsup.config.ts vitest.config.ts .size-limit.json 证据：`.npmignore`\n- **Build Wordlist**（source_file）：import { Tiktoken } from 'js-tiktoken/lite' import o200k base from 'js-tiktoken/ranks/o200k base' import { readFileSync, writeFileSync } from 'node:fs' import { englishDataset, englishRecommendedTransformers, RegExpMatcher } from 'obscenity' 证据：`scripts/build-wordlist.ts`\n- **Validate Wordlist**（source_file）：import { Tiktoken } from 'js-tiktoken/lite' import o200k base from 'js-tiktoken/ranks/o200k base' import { WORDLIST } from '../src/wordlist' 证据：`scripts/validate-wordlist.ts`\n- **Alias**（source_file）：import { selectRandomWords } from './crypto' import { AliasOptionsSchema } from './schemas' import type { AliasMap, AliasOptions } from './types' import { WORDLIST } from './wordlist' 证据：`src/alias.ts`\n- **Crypto**（source_file）：export function selectRandomWords count: number, wordlist: readonly string : string { const buf = new Uint16Array count globalThis.crypto.getRandomValues buf const words: string = new Array count for let i = 0; i < count; i++ { words i = wordlist buf i % wordlist.length } return words } 证据：`src/crypto.ts`\n- **Detect**（source_file）：import type { DetectOptions, Duplicate } from './types' 证据：`src/detect.ts`\n- **Deterministic**（source_file）：import { formatId } from './format' import { IdAgentFromOptionsSchema } from './schemas' import type { IdAgentFromOptions } from './types' import { WORDLIST } from './wordlist' 证据：`src/deterministic.ts`\n- **Format**（source_file）：export function formatId prefix: string undefined, body: string : string { return prefix ? ${prefix} ${body} : body } 证据：`src/format.ts`\n- **Generate**（source_file）：import { selectRandomWords } from './crypto' import { deterministicId } from './deterministic' import { formatId } from './format' import { IdAgentOptionsSchema } from './schemas' import type { IdAgent, IdAgentFromOptions, IdAgentOptions } from './types' import { WORDLIST } from './wordlist' 证据：`src/generate.ts`\n- **Index**（source_file）：export { createAliasMap } from './alias' export { detectDuplicates } from './detect' export { idAgent } from './generate' export { parse, validate } from './parse' export type { AliasMap, AliasOptions, DetectOptions, Duplicate, IdAgent, IdAgentFromOptions, IdAgentOptions, ParsedId, ValidateResult, } from './types' export { WORDLIST } from './wordlist' 证据：`src/index.ts`\n- **Parse**（source_file）：import type { ParsedId, ValidateResult } from './types' import { WORDLIST } from './wordlist' 证据：`src/parse.ts`\n- **Schemas**（source_file）：export const PrefixSchema = z.string .check z.regex /^ a-z0-9 +$/, { error: 'prefix must be lowercase alphanumeric' } , 证据：`src/schemas.ts`\n- **Types**（source_file）：export type IdAgentOptions = { prefix?: string words?: number } 证据：`src/types.ts`\n- **Wordlist**（source_file）：export const WORDLIST: readonly string = Object.freeze 'aal aani aba abama abas abase abb abba abby abe abel abele abet abidi abies able abler ably abort about abouts above abox abu abut aby acca accent accept access accord ace acer aces ach achar ache achen acher aching acid acier acker acle acor acre act acting action active actor acts actual acute ada adai adam adapt adar adat aday adays add adda added adder addle adds addy ade adet adin adjust admin ado adult advert ady adz aes afar affa affirm aft after aga again agal agama agar agate age aged agen agena agency agenda agent ager ages agger aghan aging agio agnes ago agog agon agonal agra agre agree agua ague agy aha ahead ahir aho ahu… 证据：`src/wordlist.ts`\n- **Alias.Test**（source_file）：import { describe, expect, it } from 'vitest' import { createAliasMap } from '../src/alias' import { WORDLIST } from '../src/wordlist' 证据：`tests/alias.test.ts`\n- **Build.Test**（source_file）：import { existsSync, readFileSync } from 'fs' import { resolve } from 'path' import { describe, expect, it } from 'vitest' 证据：`tests/build.test.ts`\n- **Detect.Test**（source_file）：import { describe, expect, it } from 'vitest' import { detectDuplicates } from '../src/detect' 证据：`tests/detect.test.ts`\n- **Deterministic.Test**（source_file）：import { describe, expect, it } from 'vitest' import { deterministicId } from '../src/deterministic' import { idAgent } from '../src/generate' import { idAgent as publicIdAgent } from '../src/index' import { WORDLIST } from '../src/wordlist' 证据：`tests/deterministic.test.ts`\n- **Generate.Test**（source_file）：import { describe, expect, it } from 'vitest' import { idAgent } from '../src/generate' import { parse, validate } from '../src/parse' import { WORDLIST } from '../src/wordlist' 证据：`tests/generate.test.ts`\n- **Parse.Test**（source_file）：import { describe, expect, it } from 'vitest' import { parse, validate } from '../src/parse' 证据：`tests/parse.test.ts`\n- **Utils.Test**（source_file）：import { describe, expect, it } from 'vitest' import { selectRandomWords } from '../src/crypto' import { formatId } from '../src/format' 证据：`tests/utils.test.ts`\n- **Wordlist Tokens.Test**（source_file）：import { Tiktoken } from 'js-tiktoken/lite' import o200k base from 'js-tiktoken/ranks/o200k base' import { describe, expect, it } from 'vitest' import { WORDLIST } from '../src/wordlist' 证据：`tests/wordlist-tokens.test.ts`\n- **Wordlist.Test**（source_file）：import { describe, expect, it } from 'vitest' import { WORDLIST } from '../src/wordlist' 证据：`tests/wordlist.test.ts`\n- **Tsup.Config**（source_file）：import { defineConfig } from 'tsup' 证据：`tsup.config.ts`\n- **Vitest.Config**（source_file）：import { defineConfig } from 'vitest/config' 证据：`vitest.config.ts`\n\n## 宿主 AI 必须遵守的规则\n\n- **把本资产当作开工前上下文，而不是运行环境。**：AI Context Pack 只包含证据化项目理解，不包含目标项目的可执行状态。 证据：`README.md`, `package.json`, `LICENSE`\n- **回答用户时区分可预览内容与必须安装后才能验证的内容。**：安装前体验的消费者价值来自降低误装和误判，而不是伪装成真实运行。 证据：`README.md`, `package.json`, `LICENSE`\n\n## 用户开工前应该回答的问题\n\n- 你准备在哪个宿主 AI 或本地环境中使用它？\n- 你只是想先体验工作流，还是准备真实安装？\n- 你最在意的是安装成本、输出质量、还是和现有规则的冲突？\n\n## 验收标准\n\n- 所有能力声明都能回指到 evidence_refs 中的文件路径。\n- AI_CONTEXT_PACK.md 没有把预览包装成真实运行。\n- 用户能在 3 分钟内看懂适合谁、能做什么、如何开始和风险边界。\n\n---\n\n## Doramagic Context Augmentation\n\n下面内容用于强化 Repomix/AI Context Pack 主体。Human Manual 只提供阅读骨架；踩坑日志会被转成宿主 AI 必须遵守的工作约束。\n\n## Human Manual 骨架\n\n使用规则：这里只是项目阅读路线和显著性信号，不是事实权威。具体事实仍必须回到 repo evidence / Claim Graph。\n\n宿主 AI 硬性规则：\n- 不得把页标题、章节顺序、摘要或 importance 当作项目事实证据。\n- 解释 Human Manual 骨架时，必须明确说它只是阅读路线/显著性信号。\n- 能力、安装、兼容性、运行状态和风险判断必须引用 repo evidence、source path 或 Claim Graph。\n\n- **项目介绍**：importance `high`\n  - source_paths: README.md, src/index.ts\n- **安装与快速开始**：importance `high`\n  - source_paths: package.json, README.md\n- **随机 ID 生成**：importance `high`\n  - source_paths: src/generate.ts, src/types.ts, src/schemas.ts\n- **确定性 ID 生成**：importance `high`\n  - source_paths: src/deterministic.ts, src/crypto.ts\n- **解析与验证**：importance `medium`\n  - source_paths: src/parse.ts, src/detect.ts\n- **词表设计**：importance `high`\n  - source_paths: src/wordlist.ts, scripts/validate-wordlist.ts, scripts/build-wordlist.ts\n- **加密模块**：importance `medium`\n  - source_paths: src/crypto.ts, src/generate.ts, src/deterministic.ts\n- **Zod 验证架构**：importance `medium`\n  - source_paths: src/schemas.ts, src/types.ts\n\n## Repo Inspection Evidence / 源码检查证据\n\n- repo_clone_verified: true\n- repo_inspection_verified: true\n- repo_commit: `22821401b08a9f6edaeecb7cff6915f3abed9632`\n- inspected_files: `pnpm-lock.yaml`, `package.json`, `README.md`, `src/generate.ts`, `src/schemas.ts`, `src/index.ts`, `src/types.ts`, `src/wordlist.ts`, `src/deterministic.ts`, `src/alias.ts`, `src/parse.ts`, `src/format.ts`, `src/crypto.ts`, `src/detect.ts`\n\n宿主 AI 硬性规则：\n- 没有 repo_clone_verified=true 时，不得声称已经读过源码。\n- 没有 repo_inspection_verified=true 时，不得把 README/docs/package 文件判断写成事实。\n- 没有 quick_start_verified=true 时，不得声称 Quick Start 已跑通。\n\n## Doramagic Pitfall Constraints / 踩坑约束\n\n这些规则来自 Doramagic 发现、验证或编译过程中的项目专属坑点。宿主 AI 必须把它们当作工作约束，而不是普通说明文字。\n\n### Constraint 1: 能力判断依赖假设\n\n- Trigger: README/documentation is current enough for a first validation pass.\n- Host AI rule: 将假设转成下游验证清单。\n- Why it matters: 假设不成立时，用户拿不到承诺的能力。\n- Evidence: capability.assumptions | hn_item:48191852 | https://news.ycombinator.com/item?id=48191852 | README/documentation is current enough for a first validation pass.\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 2: 维护活跃度未知\n\n- Trigger: 未记录 last_activity_observed。\n- Host AI rule: 补 GitHub 最近 commit、release、issue/PR 响应信号。\n- Why it matters: 新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。\n- Evidence: evidence.maintainer_signals | hn_item:48191852 | https://news.ycombinator.com/item?id=48191852 | last_activity_observed missing\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 3: 下游验证发现风险项\n\n- Trigger: no_demo\n- Host AI rule: 进入安全/权限治理复核队列。\n- Why it matters: 下游已经要求复核，不能在页面中弱化。\n- Evidence: downstream_validation.risk_items | hn_item:48191852 | https://news.ycombinator.com/item?id=48191852 | no_demo; severity=medium\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 4: 存在评分风险\n\n- Trigger: no_demo\n- Host AI rule: 把风险写入边界卡，并确认是否需要人工复核。\n- Why it matters: 风险会影响是否适合普通用户安装。\n- Evidence: risks.scoring_risks | hn_item:48191852 | https://news.ycombinator.com/item?id=48191852 | no_demo; severity=medium\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 5: 来源证据：Consider an alternative wordlist\n\n- Trigger: GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：Consider an alternative wordlist\n- Host AI rule: 来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。\n- Why it matters: 可能影响授权、密钥配置或安全边界。\n- Evidence: community_evidence:github | cevd_c1936412c9da41088e71fab995197a90 | https://github.com/vostride/id-agent/issues/2 | 来源类型 github_issue 暴露的待验证使用条件。\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 6: 来源证据：Python port\n\n- Trigger: GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：Python port\n- Host AI rule: 来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。\n- Why it matters: 可能影响授权、密钥配置或安全边界。\n- Evidence: community_evidence:github | cevd_d733a90c7db44b9789900ed24e77220e | https://github.com/vostride/id-agent/issues/1 | 来源讨论提到 python 相关条件，需在安装/试用前复核。\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 7: issue/PR 响应质量未知\n\n- Trigger: issue_or_pr_quality=unknown。\n- Host AI rule: 抽样最近 issue/PR，判断是否长期无人处理。\n- Why it matters: 用户无法判断遇到问题后是否有人维护。\n- Evidence: evidence.maintainer_signals | hn_item:48191852 | https://news.ycombinator.com/item?id=48191852 | issue_or_pr_quality=unknown\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 8: 发布节奏不明确\n\n- Trigger: release_recency=unknown。\n- Host AI rule: 确认最近 release/tag 和 README 安装命令是否一致。\n- Why it matters: 安装命令和文档可能落后于代码，用户踩坑概率升高。\n- Evidence: evidence.maintainer_signals | hn_item:48191852 | https://news.ycombinator.com/item?id=48191852 | release_recency=unknown\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n",
      "summary": "给宿主 AI 的上下文和工作边界。",
      "title": "AI Context Pack / 带给我的 AI"
    },
    "boundary_risk_card": {
      "asset_id": "boundary_risk_card",
      "filename": "BOUNDARY_RISK_CARD.md",
      "markdown": "# Boundary & Risk Card / 安装前决策卡\n\n项目：vostride/id-agent\n\n## Doramagic 试用结论\n\n当前结论：可以进入发布前推荐检查；首次使用仍应从最小权限、临时目录和可回滚配置开始。\n\n## 用户现在可以做\n\n- 可以先阅读 Human Manual，理解项目目的和主要工作流。\n- 可以复制 Prompt Preview 做安装前体验；这只验证交互感，不代表真实运行。\n- 可以把官方 Quick Start 命令放到隔离环境中验证，不要直接进主力环境。\n\n## 现在不要做\n\n- 不要把 Prompt Preview 当成项目实际运行结果。\n- 不要把 metadata-only validation 当成沙箱安装验证。\n- 不要把未验证能力写成“已支持、已跑通、可放心安装”。\n- 不要在首次试用时交出生产数据、私人文件、真实密钥或主力配置目录。\n\n## 安装前检查\n\n- 宿主 AI 是否匹配：local_cli\n- 官方安装入口状态：已发现官方入口\n- 是否在临时目录、临时宿主或容器中验证：必须是\n- 是否能回滚配置改动：必须能\n- 是否需要 API Key、网络访问、读写文件或修改宿主配置：未确认前按高风险处理\n- 是否记录了安装命令、实际输出和失败日志：必须记录\n\n## 当前阻塞项\n\n- review_required: community_discussion_evidence_below_public_threshold\n\n## 项目专属踩坑\n\n- 能力判断依赖假设（medium）：假设不成立时，用户拿不到承诺的能力。 建议检查：将假设转成下游验证清单。\n- 维护活跃度未知（medium）：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。 建议检查：补 GitHub 最近 commit、release、issue/PR 响应信号。\n- 下游验证发现风险项（medium）：下游已经要求复核，不能在页面中弱化。 建议检查：进入安全/权限治理复核队列。\n- 存在评分风险（medium）：风险会影响是否适合普通用户安装。 建议检查：把风险写入边界卡，并确认是否需要人工复核。\n- 来源证据：Consider an alternative wordlist（medium）：可能影响授权、密钥配置或安全边界。 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。\n\n## 风险与权限提示\n\n- no_demo: medium\n\n## 证据缺口\n\n- 暂未发现结构化证据缺口。\n",
      "summary": "安装、权限、验证和推荐前风险。",
      "title": "Boundary & Risk Card / 边界与风险卡"
    },
    "human_manual": {
      "asset_id": "human_manual",
      "filename": "HUMAN_MANUAL.md",
      "markdown": "# https://github.com/vostride/id-agent 项目说明书\n\n生成时间：2026-05-19 13:55:34 UTC\n\n## 目录\n\n- [项目介绍](#page-introduction)\n- [安装与快速开始](#page-installation)\n- [随机 ID 生成](#page-id-generation)\n- [确定性 ID 生成](#page-deterministic-ids)\n- [解析与验证](#page-parsing-validation)\n- [词表设计](#page-wordlist-design)\n- [加密模块](#page-crypto-module)\n- [Zod 验证架构](#page-schemas-validation)\n- [别名系统](#page-alias-system)\n- [重复检测](#page-duplicate-detection)\n\n<a id='page-introduction'></a>\n\n## 项目介绍\n\n### 相关页面\n\n相关主题：[安装与快速开始](#page-installation), [随机 ID 生成](#page-id-generation)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [README.md](https://github.com/vostride/id-agent/blob/main/README.md)\n- [src/index.ts](https://github.com/vostride/id-agent/blob/main/src/index.ts)\n- [src/parse.ts](https://github.com/vostride/id-agent/blob/main/src/parse.ts)\n- [src/detect.ts](https://github.com/vostride/id-agent/blob/main/src/detect.ts)\n- [src/deterministic.ts](https://github.com/vostride/id-agent/blob/main/src/deterministic.ts)\n- [src/wordlist.ts](https://github.com/vostride/id-agent/blob/main/src/wordlist.ts)\n- [package.json](https://github.com/vostride/id-agent/blob/main/package.json)\n- [scripts/validate-wordlist.ts](https://github.com/vostride/id-agent/blob/main/scripts/validate-wordlist.ts)\n- [scripts/build-wordlist.ts](https://github.com/vostride/id-agent/blob/main/scripts/build-wordlist.ts)\n</details>\n\n# 项目介绍\n\n## 概述\n\nid-agent 是一个专为 AI Agent 系统设计的**人类可读、令牌高效**的 ID 生成库。该项目由 [vostride](https://github.com/vostride) 开发，采用 MIT 开源许可证，当前版本为 **1.0.3**。\n\n资料来源：[package.json:2-10](https://github.com/vostride/id-agent/blob/main/package.json#L2-L10)\n\n## 核心目标\n\nid-agent 解决了传统 UUID 在 AI Agent 系统中的几个关键痛点：\n\n| 问题 | UUID 方案 | id-agent 方案 |\n|------|-----------|---------------|\n| 令牌开销 | ~23 个令牌 | 3词约 5 个令牌（节省 78%） |\n| 可读性 | 无意义十六进制字符串 | 自然语言单词组合 |\n| 碰撞安全 | 120 bits 熵 | 默认 96 bits（安全 300 万亿条目） |\n| 人类协作 | 难以口头交流 | 可直接朗读和拼写 |\n\n资料来源：[README.md](https://github.com/vostride/id-agent/blob/main/README.md)\n\n## 技术架构\n\n### 架构概览\n\n```mermaid\ngraph TD\n    A[用户请求] --> B{ID 类型选择}\n    B -->|随机 ID| C[crypto.getRandomValues CSPRNG]\n    B -->|确定性 ID| D[HMAC-SHA256 Web Crypto API]\n    C --> E[映射到 WORDLIST 索引]\n    D --> E\n    E --> F[formatId 格式化输出]\n    F --> G[返回人类可读 ID]\n    \n    H[验证流程] --> I[parse 解析 ID]\n    I --> J[wordlist 词表校验]\n    J --> K{词存在?}\n    K -->|是| L[返回有效结果]\n    K -->|否| M[返回无效原因]\n```\n\n### 核心模块\n\n| 模块 | 文件路径 | 职责 |\n|------|----------|------|\n| 主入口 | `src/index.ts` | 导出公共 API |\n| 随机 ID | `src/random.ts` | 基于 CSPRNG 的随机 ID 生成 |\n| 确定性 ID | `src/deterministic.ts` | 基于 HMAC-SHA256 的确定型 ID 生成 |\n| 解析器 | `src/parse.ts` | 解析和验证 ID 格式 |\n| 检测器 | `src/detect.ts` | 检测文本中的重复 ID |\n| 词表 | `src/wordlist.ts` | 4096 个精选单词列表 |\n| 别名映射 | `src/alias.ts` | 令牌压缩的双向映射 |\n\n资料来源：[src/deterministic.ts:1-1](https://github.com/vostride/id-agent/blob/main/src/deterministic.ts#L1-L1)\n\n## 工作原理\n\n### 熵与安全性\n\nid-agent 使用精心挑选的 **4096 词表**（2^12），每个单词贡献 12 bits 熵。单词选择通过以下流程确保安全性：\n\n```mermaid\ngraph LR\n    A[CSPRNG 随机数] --> B[取前 16 位]\n    B --> C[模 4096 取余]\n    C --> D[映射到 WORDLIST]\n    D --> E[生成单词]\n    E --> F[组合为 ID]\n```\n\n**碰撞概率计算公式：**\n\n```\nP(collision) ≈ n² / (2 × 2^b)\n\n其中 b = 总熵位数\n```\n\n| 单词数 | 熵位 | ID 空间 | 50% 碰撞阈值 |\n|--------|------|---------|--------------|\n| 3 | 36 bits | 6.9 × 10¹⁰ | ~309K 项 |\n| 5 | 60 bits | 1.2 × 10¹⁸ | ~13 亿项 |\n| **8** | **96 bits** | **7.9 × 10²⁸** | **~300 万亿项** |\n| 10 | 120 bits | 2.7 × 10¹⁸ | UUID 级别安全 |\n\n资料来源：[README.md](https://github.com/vostride/id-agent/blob/main/README.md)\n\n### 令牌效率\n\nBPE 分词器（如 GPT-4o 使用的 o200k_base）在自然语言上训练，**短英文单词恰好是单个令牌**：\n\n| 格式 | 令牌数 | 字符数 | 效率 |\n|------|--------|--------|------|\n| `dc193952-186a-4645` | ~11 tokens | 18 | 低 |\n| `storm-delta-stone` | ~4 tokens | 18 | 高 |\n\n词表中的每个单词都经过验证，确保在 o200k_base 分词器上是**恰好 1 个 BPE 令牌**。\n\n资料来源：[README.md](https://github.com/vostride/id-agent/blob/main/README.md)\n\n### 词表构建\n\n词表构建经过多层过滤：\n\n```mermaid\ngraph TD\n    A[o200k_base 词汇表] --> B{长度 3-6 字符}\n    B -->|是| C[系统词典验证]\n    B -->|否| X[排除]\n    C --> D{小写字母?}\n    D -->|是| E{无同音词?}\n    D -->|否| X\n    E -->|是| F{无贬义?}\n    E -->|否| X\n    F -->|是| G[加入词表]\n```\n\n**过滤规则：**\n\n1. **长度筛选**：仅保留 3-6 个字符的单词\n2. **词典验证**：确保是有效的英语单词\n3. **同音词过滤**：排除会产生歧义的同音词（如 `bare/bear`）\n4. **内容过滤**：移除冒犯性词汇\n\n资料来源：[scripts/build-wordlist.ts](https://github.com/vostride/id-agent/blob/main/scripts/build-wordlist.ts)\n\n## API 参考\n\n### 安装\n\n```bash\nnpm install id-agent\n# 或\npnpm add id-agent\n```\n\n**环境要求**：Node.js ≥ 18\n\n资料来源：[package.json:32-33](https://github.com/vostride/id-agent/blob/main/package.json#L32-L33)\n\n### `idAgent.generate(opts?)`\n\n生成随机人类可读 ID。\n\n```typescript\nimport { idAgent } from 'id-agent'\n\nconst id = idAgent.generate()\n// => \"storm-delta-stone\"\n\nconst prefixed = idAgent.generate({ prefix: 'task', words: 5 })\n// => \"task_snow-ocean-frost-finch-grove\"\n```\n\n**参数选项：**\n\n| 参数 | 类型 | 默认值 | 描述 |\n|------|------|--------|------|\n| `prefix` | `string` | `undefined` | 类型前缀（小写字母数字） |\n| `words` | `number` | `8` | 单词数量（1-16），控制熵位 |\n\n### `idAgent.from(input, opts?)`\n\n基于 HMAC-SHA256 生成确定性 ID，相同输入永远产生相同 ID。\n\n```typescript\nconst id = await idAgent.from('user@example.com')\n// 相同输入产生相同 ID\n\nconst namespaced = await idAgent.from('user@example.com', {\n  namespace: 'my-app',\n  prefix: 'user',\n  words: 5,\n})\n```\n\n**参数选项：**\n\n| 参数 | 类型 | 默认值 | 描述 |\n|------|------|--------|------|\n| `prefix` | `string` | `undefined` | 类型前缀 |\n| `words` | `number` | `8` | 单词数量（1-16） |\n| `namespace` | `string` | `'id-agent'` | HMAC 密钥，用于域隔离 |\n\n资料来源：[src/deterministic.ts](https://github.com/vostride/id-agent/blob/main/src/deterministic.ts)\n\n### `parse(id)`\n\n解析任意 id-agent ID 为其组成部分。\n\n```typescript\nimport { parse } from 'id-agent'\n\nparse('task_storm-delta-stone')\n// => {\n//   prefix: 'task',\n//   words: ['storm', 'delta', 'stone'],\n//   wordCount: 3,\n//   bits: 36,\n//   raw: 'task_storm-delta-stone',\n//   format: 'readable'\n// }\n```\n\n### `validate(id)`\n\n验证字符串是否为合法的 id-agent ID。\n\n```typescript\nimport { validate } from 'id-agent'\n\nvalidate('storm-delta-stone')\n// => { valid: true, prefix: undefined, wordCount: 3 }\n\nvalidate('task_jump-notaword')\n// => { valid: false, reason: 'unknown words: notaword' }\n\nvalidate('INVALID')\n// => { valid: false, reason: 'contains uppercase characters' }\n```\n\n资料来源：[src/parse.ts](https://github.com/vostride/id-agent/blob/main/src/parse.ts)\n\n### `detectDuplicates(opts)`\n\n扫描文本中的重复 ID。\n\n```typescript\nimport { detectDuplicates } from 'id-agent'\n\nconst dupes = detectDuplicates({\n  pattern: /[a-z]+(?:-[a-z]+)+/,\n  text: 'Found storm-delta-stone in file A and storm-delta-stone in file B',\n})\n// => [{ id: 'storm-delta-stone', count: 2 }]\n```\n\n**参数选项：**\n\n| 参数 | 类型 | 描述 |\n|------|------|------|\n| `pattern` | `RegExp` | 匹配 ID 的正则表达式 |\n| `text` | `string \\| string[]` | 要扫描的文本 |\n\n资料来源：[src/detect.ts](https://github.com/vostride/id-agent/blob/main/src/detect.ts)\n\n### `createAliasMap(opts)`\n\n创建用于 LLM 上下文令牌压缩的双向别名映射。\n\n```typescript\nimport { createAliasMap } from 'id-agent'\n\nconst aliases = createAliasMap({ words: 3 })\n\n// 设置长 UUID 并获取短别名\naliases.set('8cdda07b-85d2-459c-8a2a-83c8f9245dbe')\n// => \"storm-delta-stone\"\n\n// 替换文本中的所有 UUID\nconst shortened = aliases.replace(text, {\n  pattern: /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi\n})\n\n// 恢复原始 UUID\nconst restored = aliases.restore(shortened)\n```\n\n### `WORDLIST`\n\n直接访问 4096 词表（只读数组）。\n\n```typescript\nimport { WORDLIST } from 'id-agent'\n\nWORDLIST.length          // => 4096\nObject.isFrozen(WORDLIST) // => true\n```\n\n资料来源：[README.md](https://github.com/vostride/id-agent/blob/main/README.md)\n\n## 应用场景\n\n| 场景 | 推荐配置 | 熵位 | 说明 |\n|------|----------|------|------|\n| 开发/测试 | `words: 3` | 36 bits | 快速原型，便于一目了然 |\n| 生产 SaaS | `words: 5` | 60 bits | 节省 65% 令牌，安全到 10 亿项 |\n| 高并发/分布式 | `words: 8`（默认） | 96 bits | 默认安全配置，可应对 300 万亿项 |\n| UUID 等效 | `words: 10` | 120 bits | 与 UUID v4 碰撞概率相同 |\n\n## 开发命令\n\n| 命令 | 说明 |\n|------|------|\n| `pnpm build` | 构建生产版本 |\n| `pnpm test` | 运行测试 |\n| `pnpm lint` | 代码检查 |\n| `pnpm validate` | 验证词表质量 |\n| `pnpm build:wordlist` | 重新构建词表 |\n\n资料来源：[package.json:37-44](https://github.com/vostride/id-agent/blob/main/package.json#L37-L44)\n\n## 项目依赖\n\n### 生产依赖\n\n| 依赖 | 版本 | 用途 |\n|------|------|------|\n| `zod` | 4.3.6 | Schema 验证 |\n\n### 开发依赖\n\n| 依赖 | 用途 |\n|------|------|\n| `vitest` | 单元测试 |\n| `tsup` | 构建工具 |\n| `js-tiktoken` | 分词器验证 |\n| `obscenity` | 词表内容过滤 |\n| `dprint` | 代码格式化 |\n| `oxlint` | 代码检查 |\n\n资料来源：[package.json:17-28](https://github.com/vostride/id-agent/blob/main/package.json#L17-L28)\n\n## 总结\n\nid-agent 是一款专为 AI Agent 工作流优化的 ID 生成工具，通过以下核心优势解决 LLM 上下文中的效率问题：\n\n1. **令牌高效**：默认配置节省约 78% 的令牌开销\n2. **人类可读**：基于自然语言单词，便于口头交流和日志追踪\n3. **灵活安全**：可配置的熵位满足从开发到生产各级别需求\n4. **确定性与随机性兼顾**：支持随机生成和 HMAC 确定性生成两种模式\n\n---\n\n<a id='page-installation'></a>\n\n## 安装与快速开始\n\n### 相关页面\n\n相关主题：[项目介绍](#page-introduction), [随机 ID 生成](#page-id-generation)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [package.json](https://github.com/vostride/id-agent/blob/main/package.json)\n- [README.md](https://github.com/vostride/id-agent/blob/main/README.md)\n- [src/wordlist.ts](https://github.com/vostride/id-agent/blob/main/src/wordlist.ts)\n- [src/parse.ts](https://github.com/vostride/id-agent/blob/main/src/parse.ts)\n- [src/deterministic.ts](https://github.com/vostride/id-agent/blob/main/src/deterministic.ts)\n</details>\n\n# 安装与快速开始\n\n## 项目概述\n\n`id-agent` 是一个用于 AI 代理系统的人类可读、令牌高效的可识别 ID 生成库。该项目通过将 UUID 或其他长标识符转换为基于单词的短格式，实现高达 78% 的令牌节省效果，同时保持足够的熵值以防止碰撞。\n\n资料来源：[package.json:2-3]()\n\n## 安装前准备\n\n### 系统要求\n\n| 要求 | 最低版本 | 说明 |\n|------|---------|------|\n| Node.js | >= 18 | 必须支持 Web Crypto API |\n| 包管理器 | pnpm 10.6.1 | 推荐使用 pnpm |\n\n资料来源：[package.json:21-22]()\n\n### 核心依赖\n\n| 依赖 | 版本 | 用途 |\n|------|------|------|\n| zod | 4.3.6 | 参数验证与类型安全 |\n\n资料来源：[package.json:28-30]()\n\n## 安装步骤\n\n### 方式一：使用 pnpm（推荐）\n\n```bash\npnpm add id-agent\n```\n\n### 方式二：使用 npm\n\n```bash\nnpm install id-agent\n```\n\n### 方式三：使用 yarn\n\n```bash\nyarn add id-agent\n```\n\n## 快速开始\n\n### 基础导入与使用\n\n```typescript\nimport { idAgent } from 'id-agent'\n\n// 生成随机人类可读 ID\nconst id = await idAgent.generate()\n// => \"storm-delta-stone-cloud-voice-fruit-north-field\"\n\n// 带前缀的 ID\nconst taskId = await idAgent.generate({ prefix: 'task', words: 5 })\n// => \"task_storm-delta-stone-cloud-voice-fruit\"\n```\n\n资料来源：[README.md](https://github.com/vostride/id-agent/blob/main/README.md)\n\n### 确定性 ID 生成\n\n基于输入字符串生成稳定的 ID，适用于用户 ID、文档 ID 等场景：\n\n```typescript\nconst userId = await idAgent.from('user@example.com')\n// 相同输入始终返回相同的 ID\n\nconst namespaced = await idAgent.from('user@example.com', {\n  namespace: 'my-app',\n  prefix: 'user',\n  words: 5,\n})\n```\n\n资料来源：[src/deterministic.ts:1-47]()\n\n### ID 解析与验证\n\n```typescript\nimport { parse, validate } from 'id-agent'\n\n// 解析 ID 组成\nconst parsed = parse('task_storm-delta-stone')\n// => { prefix: 'task', words: ['storm', 'delta', 'stone'], wordCount: 3, bits: 36 }\n\n// 验证 ID 有效性\nconst result = validate('storm-delta-stone')\n// => { valid: true, prefix: undefined, wordCount: 3 }\n\nconst invalid = validate('task_jump-notaword')\n// => { valid: false, reason: 'unknown words: notaword' }\n```\n\n资料来源：[src/parse.ts]()\n\n## 生成选项配置\n\n| 选项 | 类型 | 默认值 | 取值范围 | 说明 |\n|------|------|--------|---------|------|\n| `prefix` | `string` | `undefined` | 小写字母数字 | 类型前缀，用于域名分离 |\n| `words` | `number` | `8` | 1-16 | 单词数量，控制熵值：words * 12 bits |\n\n资料来源：[README.md](https://github.com/vostride/id-agent/blob/main/README.md)\n\n### 不同场景推荐配置\n\n| 场景 | words | bits | 容量 | 说明 |\n|------|-------|------|------|------|\n| 快速原型 | 3 | 36 | ~309K | 最小令牌占用 |\n| 生产 SaaS | 5 | 60 | ~1.3B | UUID 65% 令牌节省 |\n| 高流量/分布式 | 8 | 96 | ~300T | 安全默认值 |\n\n资料来源：[README.md](https://github.com/vostride/id-agent/blob/main/README.md)\n\n## 别名映射与文本替换\n\n在 LLM 上下文中，可以使用别名映射将长 ID 替换为短单词格式：\n\n```typescript\nimport { createAliasMap } from 'id-agent'\n\nconst aliases = createAliasMap({ words: 3 })\naliases.set('8cdda07b-85d2-459c-8a2a-83c8f9245dbe')\n// => \"storm-delta-stone\"\n\nconst text = 'Process 8cdda07b-85d2-459c-8a2a-83c8f9245dbe then 6ba7b810-9dad-11d1-80b4-00c04fd430c8'\nconst shortened = aliases.replace(text, {\n  pattern: /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi\n})\n// => \"Process storm-delta-stone then cloud-train-scope\"\n\nconst restored = aliases.restore(shortened)\n// => 恢复原始 UUID\n```\n\n资料来源：[README.md](https://github.com/vostride/id-agent/blob/main/README.md)\n\n## 重复 ID 检测\n\n```typescript\nimport { detectDuplicates } from 'id-agent'\n\nconst dupes = detectDuplicates({\n  pattern: /[a-z]+(?:-[a-z]+)+/,\n  text: 'Found storm-delta-stone in file A and storm-delta-stone in file B',\n})\n// => [{ id: 'storm-delta-stone', count: 2 }]\n```\n\n## 开发环境搭建\n\n### 克隆项目\n\n```bash\ngit clone https://github.com/vostride/id-agent.git\ncd id-agent\n```\n\n### 安装依赖\n\n```bash\npnpm install\n```\n\n### 可用脚本命令\n\n| 命令 | 说明 |\n|------|------|\n| `pnpm build` | 使用 tsup 构建项目 |\n| `pnpm test` | 运行 vitest 测试 |\n| `pnpm test:watch` | 监听模式运行测试 |\n| `pnpm lint` | 使用 oxlint 检查代码 |\n| `pnpm format` | 使用 dprint 格式化代码 |\n| `pnpm format:check` | 检查代码格式 |\n| `pnpm size` | 检查 bundle 大小 |\n| `pnpm publint` | 检查包发布配置 |\n| `pnpm validate` | 验证单词列表 |\n\n资料来源：[package.json:24-36]()\n\n## 验证安装\n\n安装完成后，可以通过以下方式验证：\n\n```typescript\nimport { idAgent, WORDLIST } from 'id-agent'\n\n// 验证 WORDLIST 加载\nconsole.log(WORDLIST.length)          // => 4096\nconsole.log(Object.isFrozen(WORDLIST)) // => true\n\n// 生成测试 ID\nconst testId = await idAgent.generate({ words: 3 })\nconsole.log(testId)                    // => 3 词格式 ID\n```\n\n## 下一步\n\n- 查看 [基本概念](/docs/concepts) 了解 ID 格式与熵值计算\n- 查看 [API 参考](/docs/api) 获取完整 API 文档\n- 查看 [最佳实践](/docs/best-practices) 了解生产环境配置建议\n\n---\n\n<a id='page-id-generation'></a>\n\n## 随机 ID 生成\n\n### 相关页面\n\n相关主题：[确定性 ID 生成](#page-deterministic-ids), [词表设计](#page-wordlist-design), [加密模块](#page-crypto-module)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/generate.ts](https://github.com/vostride/id-agent/blob/main/src/generate.ts)\n- [src/types.ts](https://github.com/vostride/id-agent/blob/main/src/types.ts)\n- [src/schemas.ts](https://github.com/vostride/id-agent/blob/main/src/schemas.ts)\n- [src/deterministic.ts](https://github.com/vostride/id-agent/blob/main/src/deterministic.ts)\n- [src/parse.ts](https://github.com/vostride/id-agent/blob/main/src/parse.ts)\n- [src/alias.ts](https://github.com/vostride/id-agent/blob/main/src/alias.ts)\n- [src/wordlist.ts](https://github.com/vostride/id-agent/blob/main/src/wordlist.ts)\n- [package.json](https://github.com/vostride/id-agent/blob/main/package.json)\n</details>\n\n# 随机 ID 生成\n\n## 概述\n\n随机 ID 生成是 id-agent 项目的核心功能之一。该模块利用加密安全的随机数生成器（CSPRNG）创建人类可读、Token 高效的标识符。与传统的 UUID 相比，随机生成的 ID 由从精心策划的 4096 词表中选取的单词组成，每个单词恰好对应一个 BPE Token，在 LLM 场景下显著降低 Token 消耗。\n\n## 核心设计\n\n### 词表机制\n\nid-agent 维护一个包含 4096 个英语单词的词表，每个单词满足以下条件：\n\n- 长度为 3-6 个字符\n- 在 o200k_base 分词器上恰好为 1 个 Token\n- 不包含冒犯性词汇\n- 排除同音异义词（如 \"wait\" 和 \"weight\"）\n\n每个单词提供 log2(4096) = 12 位的熵值，ID 的总熵由单词数量决定：\n\n```\n总熵 = 单词数量 × 12 bits\nID空间 = 4096^单词数量 = 2^(单词数量 × 12)\n```\n\n资料来源：[README.md](https://github.com/vostride/id-agent/blob/main/README.md)\n\n### 随机数生成\n\n随机 ID 使用 `crypto.getRandomValues()` 作为熵源，这是 Web Crypto API 提供的加密安全随机数生成器。相比 Math.random()，CSPRNG 提供的随机数具有密码学安全性，适用于需要防止预测的攻击场景。\n\n## API 参考\n\n### `idAgent.random(opts?)`\n\n生成一个随机 ID，默认配置为 8 个单词（96 位熵）。\n\n```typescript\nimport { idAgent } from 'id-agent'\n\nconst id = idAgent.random()\n// => \"storm-delta-stone-cloud-frost-raven-ocean-ember\"\n\nconst shortId = idAgent.random({ words: 3 })\n// => \"storm-delta-stone\"\n\nconst prefixedId = idAgent.random({ prefix: 'user', words: 5 })\n// => \"user-storm-delta-stone-cloud-frost\"\n```\n\n#### 参数选项\n\n| 参数 | 类型 | 默认值 | 描述 |\n|------|------|--------|------|\n| `prefix` | `string` | `undefined` | 类型前缀（小写字母数字组合） |\n| `words` | `number` | `8` | 单词数量（范围 1-16），控制熵值 |\n\n参数验证由 Zod Schema 执行，无效输入会抛出描述性错误。\n\n资料来源：[src/schemas.ts](https://github.com/vostride/id-agent/blob/main/src/schemas.ts)\n\n### 类型定义\n\n```typescript\ninterface IdAgentRandomOptions {\n  prefix?: string\n  words?: number\n}\n\ninterface IdAgent {\n  random(opts?: IdAgentRandomOptions): string\n  from(input: string, opts?: IdAgentFromOptions): Promise<string>\n  parse(id: string): ParsedId | null\n  validate(id: string): ValidationResult\n}\n```\n\n资料来源：[src/types.ts](https://github.com/vostride/id-agent/blob/main/src/types.ts)\n\n## 工作流程\n\n```mermaid\ngraph TD\n    A[调用 idAgent.random] --> B{参数验证}\n    B -->|通过| C[计算所需单词数]\n    B -->|失败| Z[抛出 ZodError]\n    C --> D[调用 crypto.getRandomValues]\n    D --> E[从 DataView 读取随机字节]\n    E --> F[每 2 字节映射到 WORDLIST 索引]\n    F --> G{检查重复}\n    G -->|无重复| H[收集单词到数组]\n    G -->|重复| E\n    H --> I{单词数已满足}\n    I -->|否| E\n    I -->|是| J[拼接单词为字符串]\n    J --> K{提供 prefix}\n    K -->|是| L[添加前缀: prefix-words]\n    K -->|否| M[仅返回 words]\n    L --> N[返回完整 ID]\n    M --> N\n```\n\n## 碰撞概率分析\n\n由于使用固定词表，存在理论碰撞概率。根据生日悖论公式：\n\n```\nP(碰撞) ≈ n² / (2 × 2^b)\n\n其中 b = 总位数 = 单词数 × 12\n```\n\n### 不同配置的碰撞概率\n\n| 单词数 | 熵值 | ID 空间 | 100 万条时概率 | 10 亿条时概率 | 50% 碰撞点 |\n|--------|------|---------|----------------|---------------|------------|\n| 3 | 36 位 | 6.9 × 10¹⁰ | 0.00004% | ~43% | ~309K 条 |\n| 4 | 48 位 | 2.8 × 10¹⁴ | 1.8 × 10⁻⁶ % | ~100% | ~20M 条 |\n| 5 | 60 位 | 1.2 × 10¹⁸ | 4.3 × 10⁻⁸ % | 0.43% | ~1.3B 条 |\n| **8** | **96 位** | **7.9 × 10²⁸** | **6.3 × 10⁻¹⁸ %** | **~0%** | **~300T 条** |\n| 10 | 120 位 | 1.3 × 10³⁶ | ~0% | 9.4 × 10⁻²⁰ % | ~2.7 × 10¹⁸ 条 |\n\n**默认配置（8 单词，96 位）** 可安全处理超过 300 万亿条 ID 而不产生 50% 碰撞概率。\n\n资料来源：[README.md](https://github.com/vostride/id-agent/blob/main/README.md)\n\n## Token 效率对比\n\nid-agent 的单词型 ID 在 LLM 分词器上远比 UUID 高效。以 o200k_base 分词器为例：\n\n| 格式 | 平均 Token 数 | 熵值 | 相比 UUID 节省 |\n|------|---------------|------|----------------|\n| UUID v4 | ~23 | 122 位 | -- |\n| id-agent (3 单词) | ~5 | 36 位 | **78%** |\n| id-agent (5 单词) | ~9 | 60 位 | **61%** |\n| id-agent (8 单词) | ~14 | 96 位 | **39%** |\n\n这是因为短英语单词在 BPE 分词器上天然就是单个 Token，而 UUID 的十六进制字符会不可预测地分裂成多个 Token。\n\n资料来源：[README.md](https://github.com/vostride/id-agent/blob/main/README.md)\n\n## 与确定性 ID 的关系\n\nid-agent 提供两种 ID 生成模式：\n\n| 模式 | 熵源 | 可重现性 | 适用场景 |\n|------|------|----------|----------|\n| **随机** `random()` | `crypto.getRandomValues()` | 否 | 会话 ID、临时标识符 |\n| **确定性** `from()` | HMAC-SHA256 | 是 | 用户标识、内容寻址 |\n\n确定性模式使用相同的词表和单词选择逻辑，但通过 HMAC-SHA256 将输入字符串映射到固定的单词序列，确保相同输入始终产生相同输出。\n\n```typescript\n// 随机 ID：每次调用生成不同 ID\nidAgent.random()   // => \"storm-delta-stone...\"\nidAgent.random()   // => \"frost-ocean-ember...\"\n\n// 确定性 ID：相同输入产生相同 ID\nawait idAgent.from('user@example.com')   // => \"cloud-train-scope...\"\nawait idAgent.from('user@example.com')   // => \"cloud-train-scope...\"\n```\n\n资料来源：[src/deterministic.ts](https://github.com/vostride/id-agent/blob/main/src/deterministic.ts)\n\n## 使用场景\n\n### 场景一：会话标识符\n\n```typescript\nconst sessionId = idAgent.random({ words: 4, prefix: 'session' })\n// => \"session-storm-delta-stone-cloud\"\n```\n\n### 场景二：任务队列标识符\n\n```typescript\nconst taskId = idAgent.random({ words: 5, prefix: 'task' })\n// => \"task-frost-ocean-ember-light-rain\"\n```\n\n### 场景三：轻量级随机标识符\n\n```typescript\nconst shortId = idAgent.random({ words: 3 })\n// => \"stone-cloud-train\"\n```\n\n## 配置建议\n\n| 应用场景 | 推荐配置 | 熵值 | 说明 |\n|----------|----------|------|------|\n| 开发/测试 | `words: 3` | 36 位 | 简短易读，用于非关键场景 |\n| 生产 SaaS | `words: 5` | 60 位 | 安全到约 10 亿条，节省 65% Token |\n| 高容量/分布式 | `words: 8` (默认) | 96 位 | 安全到约 300 万亿条，推荐默认值 |\n| UUID 等效 | `words: 10` | 120 位 | 与 UUID v4 碰撞概率相当 |\n\n## 安全性考量\n\n### CSPRNG 的必要性\n\n使用 `crypto.getRandomValues()` 而非 `Math.random()` 是关键安全设计：\n\n- `Math.random()`：伪随机数，可被预测\n- `crypto.getRandomValues()`：密码学安全随机数，满足熵要求\n\n### 前缀验证\n\n前缀仅接受小写字母数字组合（`/^[a-z0-9]+$/`），防止格式注入和解析歧义。\n\n```typescript\nidAgent.random({ prefix: 'User-ID' })\n// => 抛出错误: \"prefix must be lowercase alphanumeric only\"\n```\n\n资料来源：[src/schemas.ts](https://github.com/vostride/id-agent/blob/main/src/schemas.ts)\n\n## 验证与解析\n\n### `validate(id)`\n\n验证 ID 是否合法：\n\n```typescript\nimport { validate } from 'id-agent'\n\nvalidate('storm-delta-stone')\n// => { valid: true, prefix: undefined, wordCount: 3 }\n\nvalidate('task_jump-notaword')\n// => { valid: false, reason: 'unknown words: notaword' }\n```\n\n### `parse(id)`\n\n解析 ID 的组成部分：\n\n```typescript\nimport { parse } from 'id-agent'\n\nparse('task_storm-delta-stone')\n// => {\n//   prefix: 'task',\n//   words: ['storm', 'delta', 'stone'],\n//   wordCount: 3,\n//   bits: 36,\n//   raw: 'task_storm-delta-stone',\n//   format: 'readable'\n// }\n```\n\n资料来源：[src/parse.ts](https://github.com/vostride/id-agent/blob/main/src/parse.ts)\n\n## 内部实现\n\n### 单词选择算法\n\n核心逻辑位于 `selectRandomWords` 函数，通过以下步骤选择单词：\n\n1. 使用 `DataView.getUint16()` 从随机字节序列中读取 16 位无符号整数\n2. 取模 4096 得到词表索引\n3. 重复直到收集到所需单词数量\n4. 去重确保无重复单词\n\n### 重复检测\n\n如果生成过程中出现重复单词，会重新生成而不是替换。这确保 ID 的实际熵值与理论值一致。\n\n```typescript\n// 简化伪代码\ndo {\n  word = WORDLIST[randomUint16() % 4096]\n} while (used.has(word) && used.size < 4096)\n```\n\n## 总结\n\n随机 ID 生成是 id-agent 项目的基石功能，通过以下设计实现了安全性、可读性和 Token 效率的统一：\n\n- **4096 词表**：每个单词 12 位熵，BPE 友好\n- **CSPRNG**：密码学安全的熵源\n- **可配置单词数**：根据场景平衡安全性和简洁性\n- **可选前缀**：支持类型化 ID 命名空间\n- **与确定性模式共存**：覆盖随机和可重现两种场景\n\n---\n\n<a id='page-deterministic-ids'></a>\n\n## 确定性 ID 生成\n\n### 相关页面\n\n相关主题：[随机 ID 生成](#page-id-generation), [加密模块](#page-crypto-module)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/deterministic.ts](https://github.com/vostride/id-agent/blob/main/src/deterministic.ts)\n- [src/generate.ts](https://github.com/vostride/id-agent/blob/main/src/generate.ts)\n- [src/parse.ts](https://github.com/vostride/id-agent/blob/main/src/parse.ts)\n- [src/schemas.ts](https://github.com/vostride/id-agent/blob/main/src/schemas.ts)\n- [src/types.ts](https://github.com/vostride/id-agent/blob/main/src/types.ts)\n- [src/wordlist.ts](https://github.com/vostride/id-agent/blob/main/src/wordlist.ts)\n- [README.md](https://github.com/vostride/id-agent/blob/main/README.md)\n</details>\n\n# 确定性 ID 生成\n\n## 概述\n\n确定性 ID 生成是 id-agent 库的核心功能之一，允许从任意字符串输入生成唯一、可复现的 ID。与随机 ID 生成不同，相同的输入无论何时何地调用，都会产生完全相同的输出 ID。\n\n该功能主要适用于：\n\n- **用户标识**：基于邮箱、用户名等生成唯一用户 ID\n- **内容寻址**：基于文件内容哈希生成确定性文件 ID\n- **幂等操作**：为请求生成稳定的标识符用于去重\n\n核心原理是通过 HMAC-SHA256 哈希函数将输入字符串转换为加密安全的伪随机数，然后将这些数字映射到精选的 4096 词表中的单词。\n\n## 工作原理\n\n### 架构流程\n\n```mermaid\ngraph TD\n    A[输入字符串] --> B[TextEncoder 编码]\n    B --> C[导入 HMAC 密钥]\n    C --> D[crypto.subtle.sign 使用 HMAC-SHA256]\n    D --> E[DataView 读取签名结果]\n    E --> F[每 2 字节映射到 WORDLIST 索引]\n    F --> G[拼接单词为最终 ID]\n    \n    H[namespace 配置] --> C\n    I[words 数量] --> F\n    J[prefix 前缀] --> G\n```\n\n### 关键步骤解析\n\n**步骤 1：输入验证与编码**\n\n函数首先验证输入有效性，确保传入的是非空字符串：\n\n```typescript\nif (!input || typeof input !== 'string') {\n  throw new Error('input must be a non-empty string')\n}\n```\n资料来源：[src/deterministic.ts:10](https://github.com/vostride/id-agent/blob/main/src/deterministic.ts#L10)\n\n**步骤 2：选项解析与默认值**\n\n使用 Zod Schema 验证并应用默认配置，words 默认值为 8：\n\n```typescript\nconst validated = IdAgentFromOptionsSchema.parse(opts ?? {})\nconst words = validated.words ?? 8\n```\n资料来源：[src/deterministic.ts:12-13](https://github.com/vostride/id-agent/blob/main/src/deterministic.ts#L12-L13)\n\n**步骤 3：Web Crypto API 密钥导入**\n\n使用 Web Crypto API 的 `crypto.subtle` 模块导入 HMAC 密钥：\n\n```typescript\nconst enc = new TextEncoder()\nconst keyData = enc.encode(validated.namespace ?? 'id-agent')\nconst key = await globalThis.crypto.subtle.importKey(\n  'raw',\n  keyData,\n  { name: 'HMAC', hash: 'SHA-256' },\n  false,\n  ['sign'],\n)\n```\n资料来源：[src/deterministic.ts:18-24](https://github.com/vostride/id-agent/blob/main/src/deterministic.ts#L18-L24)\n\n**步骤 4：HMAC-SHA256 签名**\n\n对输入字符串进行加密签名：\n\n```typescript\nconst sig = await globalThis.crypto.subtle.sign('HMAC', key, enc.encode(input))\n```\n资料来源：[src/deterministic.ts:26](https://github.com/vostride/id-agent/blob/main/src/deterministic.ts#L26)\n\n**步骤 5：哈希值到单词的映射**\n\n将签名结果转换为 DataView，每 2 字节（16 位）作为一个索引，取模 4096 获取词表中的单词：\n\n```typescript\nconst view = new DataView(sig)\nconst selected: string[] = new Array(words)\nfor (let i = 0; i < words; i++) {\n  selected[i] = WORDLIST[view.getUint16(i * 2) % 4096]\n}\n```\n资料来源：[src/deterministic.ts:28-32](https://github.com/vostride/id-agent/blob/main/src/deterministic.ts#L28-L32)\n\n**步骤 6：格式化输出**\n\n使用 `formatId` 函数将前缀和单词数组拼接为最终 ID：\n\n```typescript\nreturn formatId(validated.prefix, selected.join('-'))\n```\n资料来源：[src/deterministic.ts:34](https://github.com/vostride/id-agent/blob/main/src/deterministic.ts#L34)\n\n## API 参考\n\n### idAgent.from(input, opts?)\n\n生成确定性 ID 的主要方法，挂载在 `idAgent` 函数对象上。\n\n```typescript\nimport { idAgent } from 'id-agent'\n\nconst id = await idAgent.from('user@example.com')\n// => 例如：vivid-shade-glimmer (每次相同)\n```\n\n#### 参数说明\n\n| 参数 | 类型 | 必填 | 默认值 | 说明 |\n|------|------|------|--------|------|\n| `input` | `string` | 是 | - | 用于生成 ID 的输入字符串 |\n| `opts.prefix` | `string` | 否 | `undefined` | 类型前缀（小写字母数字） |\n| `opts.words` | `number` | 否 | `8` | 单词数量（1-16），控制熵值 |\n| `opts.namespace` | `string` | 否 | `'id-agent'` | HMAC 密钥，用于域隔离 |\n\n资料来源：[src/generate.ts:8](https://github.com/vostride/id-agent/blob/main/src/generate.ts#L8)，[README.md](https://github.com/vostride/id-agent/blob/main/README.md)\n\n#### 返回值\n\n返回格式化后的确定性 ID 字符串，格式为：`{prefix_}word1-word2-word3-...`\n\n#### 使用示例\n\n**基础用法**\n\n```typescript\nconst id = await idAgent.from('user@example.com')\n// 每次调用都返回相同结果\n```\n\n**带前缀和命名空间**\n\n```typescript\nconst userId = await idAgent.from('user@example.com', {\n  namespace: 'my-app',\n  prefix: 'user',\n  words: 5,\n})\n// => \"user_calm-bold-wake-tide-neat\"\n```\n\n**不同命名空间产生不同 ID**\n\n```typescript\nconst id1 = await idAgent.from('same-input', { namespace: 'app-a' })\nconst id2 = await idAgent.from('same-input', { namespace: 'app-b' })\n// id1 !== id2 (因为命名空间不同)\n```\n\n## 配置选项详解\n\n### words 参数\n\n控制生成 ID 的单词数量，直接决定熵值大小。\n\n| words 值 | 熵值 | ID 空间 | 适用场景 |\n|----------|------|---------|----------|\n| 3 | 36 bits | 6.9 × 10¹⁰ | 仅用于日志/调试 |\n| 5 | 60 bits | 1.2 × 10¹⁸ | 生产级 SaaS 应用 |\n| 8 | 96 bits | 7.9 × 10²⁸ | **默认**，高容量/分布式系统 |\n| 10 | 120 bits | 1.3 × 10³⁶ | UUID v4 等效安全级别 |\n\n资料来源：[README.md](https://github.com/vostride/id-agent/blob/main/README.md)\n\n### namespace 参数\n\nHMAC 密钥用于域隔离，确保相同输入在不同应用/租户间产生不同 ID。\n\n```typescript\n// 多租户场景\nconst id1 = await idAgent.from('shared-resource-id', { namespace: 'tenant-1' })\nconst id2 = await idAgent.from('shared-resource-id', { namespace: 'tenant-2' })\n```\n\n### prefix 参数\n\n类型前缀用于区分不同实体的 ID，便于人工识别和日志分析。\n\n- 必须是 **小写字母数字**\n- 格式：`{prefix}_word-word-word`\n- 例如：`user_`、`task_`、`file_`\n\n```typescript\nawait idAgent.from('doc-123', { prefix: 'doc' })\n// => \"doc_river-wave-soft-wake-calm-dream-bloom\"\n```\n\n## 验证与解析\n\n### validate(id)\n\n验证确定性 ID 的有效性，检查词表中的单词是否都存在：\n\n```typescript\nimport { validate } from 'id-agent'\n\nvalidate('task_storm-delta-stone')\n// => { valid: true, prefix: 'task', wordCount: 3 }\n\nvalidate('task_jump-notaword')\n// => { valid: false, reason: 'unknown words: notaword' }\n```\n资料来源：[src/parse.ts](https://github.com/vostride/id-agent/blob/main/src/parse.ts)\n\n### parse(id)\n\n解析 ID 的结构组件：\n\n```typescript\nimport { parse } from 'id-agent'\n\nparse('task_storm-delta-stone')\n// => {\n//   prefix: 'task',\n//   words: ['storm', 'delta', 'stone'],\n//   wordCount: 3,\n//   bits: 36,\n//   raw: 'task_storm-delta-stone',\n//   format: 'readable'\n// }\n```\n资料来源：[src/parse.ts](https://github.com/vostride/id-agent/blob/main/src/parse.ts)\n\n## 安全性分析\n\n### HMAC-SHA256 保障\n\n确定性 ID 生成使用 Web Crypto API 的 `crypto.subtle.sign` 方法，底层采用 HMAC-SHA256 算法：\n\n```mermaid\ngraph LR\n    A[输入] --> B[HMAC-SHA256]\n    B --> C[128位签名]\n    C --> D[选取前 2×words 字节]\n    D --> E[每字节对 4096 取模]\n    E --> F[映射到单词]\n```\n\n### 域隔离机制\n\n通过 namespace 参数实现密钥隔离，即使输入相同，不同命名空间产生的 HMAC 签名完全不同：\n\n```typescript\n// 即使输入完全相同\nidAgent.from('same-input', { namespace: 'ns-a' })  // => 完全不同的输出\nidAgent.from('same-input', { namespace: 'ns-b' })  // => 完全不同的输出\n```\n\n### 熵值计算\n\n每个单词贡献 12 bits 熵值（因为词表大小为 4096 = 2¹²）：\n\n```\n总熵值 = words × 12 bits\n```\n\n默认 8 个单词提供 96 bits 熵值，在 300 万亿个项目内碰撞概率低于 50%。\n\n## 浏览器兼容性\n\n该功能依赖 **Web Crypto API**，要求：\n\n| 环境 | 支持情况 | 说明 |\n|------|----------|------|\n| 现代浏览器 | ✅ | HTTPS 环境下完整支持 |\n| Node.js 18+ | ✅ | 内置 Web Crypto API |\n| HTTP 页面 | ❌ | 浏览器安全限制 |\n| Node.js <18 | ❌ | 需升级版本 |\n\n```typescript\nif (!globalThis.crypto?.subtle) {\n  throw new Error('idAgent.from() requires Web Crypto API (crypto.subtle). Use HTTPS in browsers.')\n}\n```\n资料来源：[src/deterministic.ts:15-17](https://github.com/vostride/id-agent/blob/main/src/deterministic.ts#L15-L17)\n\n## 最佳实践\n\n### 生产环境推荐配置\n\n```typescript\n// 高安全性场景\nconst secureId = await idAgent.from(userId, {\n  words: 8,        // 默认值，96 bits 熵值\n  prefix: 'user',\n  namespace: process.env.APP_NAMESPACE\n})\n\n// 平衡可读性与安全性\nconst balancedId = await idAgent.from(resourceId, {\n  words: 5,        // 60 bits，适合大多数应用\n  prefix: 'resource'\n})\n```\n\n### 常见错误处理\n\n```typescript\ntry {\n  const id = await idAgent.from('')\n} catch (e) {\n  // Error: input must be a non-empty string\n}\n\ntry {\n  const id = await idAgent.from('input', { words: 20 })\n} catch (e) {\n  // ZodError: Number must be less than or equal to 16\n}\n```\n\n## 与随机 ID 对比\n\n| 特性 | 确定性 ID (`from`) | 随机 ID (`idAgent()`) |\n|------|-------------------|----------------------|\n| 输入要求 | 任意字符串 | 无 |\n| 可复现性 | ✅ 相同输入 → 相同输出 | ❌ 每次不同 |\n| Web Crypto | ✅ 必须 | ❌ 可选 |\n| 适用场景 | 用户/内容标识 | 会话/临时 ID |\n| 熵值来源 | HMAC-SHA256 | CSPRNG |\n\n资料来源：[src/generate.ts](https://github.com/vostride/id-agent/blob/main/src/generate.ts)\n\n---\n\n<a id='page-parsing-validation'></a>\n\n## 解析与验证\n\n### 相关页面\n\n相关主题：[随机 ID 生成](#page-id-generation), [Zod 验证架构](#page-schemas-validation)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/parse.ts](https://github.com/vostride/id-agent/blob/main/src/parse.ts)\n- [src/detect.ts](https://github.com/vostride/id-agent/blob/main/src/detect.ts)\n- [src/alias.ts](https://github.com/vostride/id-agent/blob/main/src/alias.ts)\n- [src/deterministic.ts](https://github.com/vostride/id-agent/blob/main/src/deterministic.ts)\n- [src/wordlist.ts](https://github.com/vostride/id-agent/blob/main/src/wordlist.ts)\n- [scripts/validate-wordlist.ts](https://github.com/vostride/id-agent/blob/main/scripts/validate-wordlist.ts)\n- [package.json](https://github.com/vostride/id-agent/blob/main/package.json)\n</details>\n\n# 解析与验证\n\n## 概述\n\n解析与验证模块是 id-agent 项目中处理 ID 字符串的核心功能组件。该模块负责将人类可读的 ID 字符串解析为其组成成分，并检验其是否符合 id-agent 规范的格式要求。解析功能支持连字符分隔和下划线分隔两种格式，能够提取出前缀、单词数组、单词数量和熵位数等信息。验证功能则确保生成的 ID 仅包含有效的单词，并且格式完全符合规范要求。\n\n在 id-agent 的整体架构中，解析与验证模块扮演着基础设施的角色，被别名映射（AliasMap）、确定性 ID 生成（deterministicId）以及重复检测（detectDuplicates）等多个功能模块所依赖。这种设计确保了整个系统在处理 ID 字符串时拥有一致性的验证标准和数据格式。\n\n## 核心 API\n\n### parse 函数\n\n`parse` 函数是解析模块的入口函数，用于将 id-agent 格式的 ID 字符串分解为其组成成分。该函数支持连字符分隔（如 `task_storm-delta-stone`）和下划线分隔（如 `task_storm_delta_stone`）两种格式，并能够智能识别前缀与单词部分的分隔方式。\n\n函数返回的对象包含以下属性：prefix 表示 ID 的前缀类型（如 `task`），若不存在前缀则返回 `undefined`；words 是一个字符串数组，包含 ID 中的所有单词；wordCount 表示单词的数量；bits 表示总熵位数，计算公式为 `words.length * 12`；raw 保存原始输入字符串；format 字段标识输入格式为 `readable`。当输入字符串无法被识别为有效的 id-agent 格式时，函数返回 `null`。\n\n```typescript\nimport { parse } from 'id-agent'\n\nparse('task_storm-delta-stone')\n// => { prefix: 'task', words: ['storm', 'delta', 'stone'], wordCount: 3, bits: 36, raw: 'task_storm-delta-stone', format: 'readable' }\n\nparse('task_storm_delta_stone')\n// => { prefix: 'task', words: ['storm', 'delta', 'stone'], wordCount: 3, bits: 36, raw: 'task_storm_delta_stone', format: 'readable' }\n```\n\n解析算法首先尝试按下划线分割字符串，取第一部分作为候选前缀。若第一部分仅包含小写字母和数字，则将其识别为有效前缀；否则整个字符串将被视为纯单词序列。单词提取阶段通过正则表达式匹配连续的纯小写字母单词序列，支持连字符或下划线作为单词间的分隔符。这种双重格式支持使得 id-agent 能够兼容不同来源和风格的 ID 命名约定。\n\n资料来源：[src/parse.ts:1-30]()\n\n### validate 函数\n\n`validate` 函数用于检验给定的字符串是否为合法的 id-agent ID。该函数执行多层次的验证检查，包括大写字符检测、无效字符检测、格式识别以及单词有效性验证。只有通过全部检查的 ID 才会被标记为有效。\n\n验证流程首先检查字符串是否包含大写字符。id-agent 规范要求所有字符必须为小写，因此任何大写字母的出现都会导致验证失败并返回 `contains uppercase characters` 错误信息。资料来源：[src/parse.ts:41-43]()\n\n接下来验证字符串是否包含非法字符。有效字符集限于小写字母、数字、连字符和下划线。若发现其他字符，函数返回 `contains invalid characters` 错误。资料来源：[src/parse.ts:44-46]()\n\n然后调用 `parse` 函数尝试解析 ID。若解析失败（返回 `null`），说明字符串不符合 id-agent 的基本格式要求，验证将返回 `unrecognized format` 错误。资料来源：[src/parse.ts:47-49]()\n\n最后一项验证是单词词汇表检查。解析成功后，函数会逐一检查每个单词是否存在于 id-agent 的 4096 词单词列表中。若发现任何未知单词，返回 `unknown words: ${invalid.join(', ')}` 错误信息，列出所有无效单词。资料来源：[src/parse.ts:50-58]()\n\n```typescript\nimport { validate } from 'id-agent'\n\nvalidate('storm-delta-stone')\n// => { valid: true, prefix: undefined, wordCount: 3 }\n\nvalidate('task_jump-notaword')\n// => { valid: false, reason: 'unknown words: notaword' }\n\nvalidate('INVALID')\n// => { valid: false, reason: 'contains uppercase characters' }\n```\n\n成功验证时返回的对象包含 `valid: true`、可选的 `prefix` 字段以及 `wordCount` 表示单词数量。这种结构化的返回方式便于调用方根据验证结果进行后续处理，同时保留了必要的元数据信息。\n\n## 重复检测功能\n\n### detectDuplicates 函数\n\n`detectDuplicates` 函数提供在文本中扫描重复 ID 的能力。该函数是纯函数实现，不涉及文件系统访问，仅依赖正则表达式进行模式匹配，因此可以在任何环境中安全使用。资料来源：[src/detect.ts:1-27]()\n\n函数接受一个包含 `pattern` 和 `text` 两个属性的选项对象。`pattern` 是一个正则表达式，用于匹配待检测的 ID 格式；`text` 可以是单个字符串或字符串数组，函数会统一处理两种输入形式。资料来源：[src/detect.ts:3-7]()\n\n重复检测的工作流程首先将 `text` 参数统一转换为数组形式，然后遍历每一段文本使用正则表达式进行全局匹配。正则表达式的 `g` 标志确保能够找到所有匹配项，同时代码会确保匹配器始终以全局模式运行。资料来源：[src/detect.ts:8-19]()\n\n检测结果以数组形式返回，每个元素是一个包含 `id` 和 `count` 属性的对象。`id` 字段保存重复出现的 ID 字符串，`count` 字段表示该 ID 在文本中出现的次数。仅当 `count > 1` 时，结果才会被包含在返回值中，这意味着函数默认过滤掉仅出现一次的 ID。资料来源：[src/detect.ts:20-26]()\n\n```typescript\nimport { detectDuplicates } from 'id-agent'\n\nconst dupes = detectDuplicates({\n  pattern: /[a-z]+(?:-[a-z]+)+/,\n  text: 'Found storm-delta-stone in file A and storm-delta-stone in file B',\n})\n// => [{ id: 'storm-delta-stone', count: 2 }]\n\nconst dupes2 = detectDuplicates({\n  pattern: /task_[a-z]+(?:-[a-z]+)+/,\n  text: ['const x = \"task_red-fox-run\"', 'const y = \"task_red-fox-run\"'],\n})\n```\n\n该函数在实际应用场景中具有广泛的用途，包括但不限于：检测代码库中是否存在重复的 ID 定义、验证测试数据中的 ID 唯一性、以及在数据迁移过程中确保 ID 不发生冲突。纯函数的设计使其特别适合在持续集成环境中作为自动化检查工具使用。\n\n## 别名映射系统\n\n### createAliasMap 函数\n\n`createAliasMap` 函数创建一个双向别名映射系统，用于在 LLM 上下文中实现令牌节省。该系统将长格式的原始标识符（如 UUID）映射为短格式的单词别名，并在需要时能够精确恢复原始值。资料来源：[src/alias.ts:1-67]()\n\n别名映射对象提供三个核心方法：`set(original)` 用于添加新的映射关系并返回生成的别名；`get(alias)` 根据别名查找原始值；`replace(text, options)` 批量替换文本中所有已注册的标识符；`restore(text)` 恢复被替换的标识符。\n\n```typescript\nimport { createAliasMap } from 'id-agent'\n\nconst aliases = createAliasMap({ words: 3 })\naliases.set('8cdda07b-85d2-459c-8a2a-83c8f9245dbe')\n// => \"storm-delta-stone\" (3 random words from WORDLIST)\n\naliases.get('storm-delta-stone')\n// => \"8cdda07b-85d2-459c-8a2a-83c8f9245dbe\"\n\nconst text = 'Process 8cdda07b-85d2-459c-8a2a-83c8f9245dbe then 6ba7b810-9dad-11d1-80b4-00c04fd430c8'\nconst shortened = aliases.replace(text, {\n  pattern: /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi\n})\n// => \"Process storm-delta-stone then cloud-train-scope\"\n\nconst restored = aliases.restore(shortened)\n// => original text\n```\n\n`set` 方法内部维护两个映射表：`forward` 将原始值映射到别名，`reverse` 将别名映射回原始值。当添加新的映射时，方法首检查是否存在已有映射以避免重复生成。若启用冲突允许选项，在生成别名时会进行碰撞检测。资料来源：[src/alias.ts:19-31]()\n\n`replace` 方法支持可选的正则表达式参数，若提供则仅替换匹配该模式的字符串。这种设计允许调用方精确控制替换范围，避免意外替换不应被处理的文本内容。资料来源：[src/alias.ts:32-50]()\n\n## 单词列表系统\n\n### WORDLIST 常量\n\n`WORDLIST` 是 id-agent 项目精心策划的 4096 词单词列表，每个单词都经过验证恰好是 o200k_base 分词器（GPT-4o、GPT-4.1 等模型使用）的单个 BPE 令牌。这个特性是 id-agent 实现令牌效率的基础。资料来源：[src/wordlist.ts](https://github.com/vostride/id-agent/blob/main/src/wordlist.ts)\n\n单词列表构建过程包含多个严格的筛选阶段。首先从 o200k_base 词汇表中提取所有 3-6 个字符的候选单词，然后与系统词典进行交叉验证确保词汇的有效性。资料来源：[scripts/build-wordlist.ts:30-50]()\n\n接下来进行两项 BPE 令牌验证：单令牌编码测试确保单词独立编码为单个令牌；连字符前缀测试确保单词在与其他内容连接时不会产生额外的令牌分割。资料来源：[scripts/build-wordlist.ts:51-65]()\n\n最后进行语义过滤，使用 obscenity 库检测并移除不适当的词汇，同时人工审查移除同音异义词（如 \"wait\" 和 \"weight\"），避免在口语环境中造成混淆。资料来源：[scripts/build-wordlist.ts:66-90]()\n\n```typescript\nimport { WORDLIST } from 'id-agent'\n\nWORDLIST.length          // => 4096\nObject.isFrozen(WORDLIST) // => true\n```\n\n单词列表以冻结数组形式导出，确保在运行期间不可被修改。这种不可变性保证了解析和验证结果的确定性和可靠性。\n\n### validate-wordlist.ts 验证脚本\n\n`scripts/validate-wordlist.ts` 是项目提供的单词列表验证工具，用于确保 WORDLIST 满足所有令牌效率和安全要求。该脚本通过编程方式验证列表中每个单词的特性。\n\n验证包含两个主要检查：单令牌验证确保每个单词编码为恰好一个 BPE 令牌；连字符前缀验证确保单词在与其他内容连接时保持令牌边界。资料来源：[scripts/validate-wordlist.ts:1-25]()\n\n脚本输出详细的验证报告，包括通过检查的项目数量和失败的单词列表（若存在）。所有检查通过时输出 `ALL CHECKS PASSED`，否则列出失败数量并返回非零退出码。\n\n```bash\npnpm run validate\n```\n\n开发者可以通过运行此脚本快速验证单词列表的完整性，在修改单词列表或升级分词器版本后尤其重要。\n\n## 数据结构\n\n### 解析结果类型\n\n| 字段 | 类型 | 描述 |\n|------|------|------|\n| `prefix` | `string \\| undefined` | ID 前缀，若无前缀则为 undefined |\n| `words` | `string[]` | 单词数组 |\n| `wordCount` | `number` | 单词数量 |\n| `bits` | `number` | 总熵位数（wordCount × 12） |\n| `raw` | `string` | 原始输入字符串 |\n| `format` | `'readable'` | 格式标识 |\n\n### 验证结果类型\n\n| 字段 | 类型 | 描述 |\n|------|------|------|\n| `valid` | `boolean` | 验证是否通过 |\n| `prefix` | `string \\| undefined` | 解析得到的前缀（仅在 valid 为 true 时） |\n| `wordCount` | `number` | 单词数量（仅在 valid 为 true 时） |\n| `reason` | `string` | 验证失败原因（仅在 valid 为 false 时） |\n\n### 重复检测结果类型\n\n| 字段 | 类型 | 描述 |\n|------|------|------|\n| `id` | `string` | 重复出现的 ID 值 |\n| `count` | `number` | 出现次数 |\n\n## 验证流程图\n\n```mermaid\ngraph TD\n    A[输入字符串] --> B{包含大写字符?}\n    B -->|是| E[返回 invalid: contains uppercase characters]\n    B -->|否| C{包含无效字符?}\n    C -->|是| F[返回 invalid: contains invalid characters]\n    C -->|否| D{格式可解析?}\n    D -->|否| G[返回 invalid: unrecognized format]\n    D -->|是| H{所有单词在词表中?}\n    H -->|否| I[返回 invalid: unknown words]\n    H -->|是| J[返回 valid: true]\n    \n    style J fill:#90EE90\n    style E fill:#FFB6C1\n    style F fill:#FFB6C1\n    style G fill:#FFB6C1\n    style I fill:#FFB6C1\n```\n\n## 架构关系图\n\n```mermaid\ngraph LR\n    A[用户输入] --> B[parse 函数]\n    A --> C[validate 函数]\n    B --> D{解析成功?}\n    D -->|否| E[返回 null]\n    D -->|是| F[返回解析结果]\n    \n    C --> G{多层验证}\n    G --> H[大写检测]\n    G --> I[字符检测]\n    G --> J[格式解析]\n    G --> K[词表验证]\n    \n    F --> L[别名映射系统]\n    F --> M[确定性生成]\n    C --> N[重复检测]\n    \n    H --> O{通过?}\n    I --> P{通过?}\n    J --> Q{通过?}\n    K --> R{通过?}\n    \n    O -->|否| S[验证失败]\n    P -->|否| S\n    Q -->|否| S\n    R -->|否| S\n    \n    O -->|是| T{下一检测}\n    P -->|是| T\n    Q -->|是| T\n    R -->|是| U[验证成功]\n```\n\n## 依赖关系\n\n解析与验证模块的正常运作依赖于以下核心组件：单词列表（WORDLIST）提供词汇验证所需的参考数据，`src/wordlist.ts` 导出包含 4096 个有效单词的冻结数组；密码学模块（crypto）提供 `selectRandomWords` 函数用于别名映射中的随机单词选择。资料来源：[src/alias.ts:2]()\n\n验证选项使用 Zod 进行模式验证，确保用户输入的参数符合预期的类型和约束。资料来源：[package.json:29-30]()\n\n## 使用建议\n\n在实际项目中集成解析与验证功能时，建议遵循以下最佳实践。首先，对于需要频繁验证的场景（如 API 输入验证），可以在应用启动时创建单词集合（Set）以加速查找操作，尽管 id-agent 内部已经优化了验证流程。\n\n其次，在使用 `detectDuplicates` 检测重复时，正则表达式的设计应当精确匹配目标 ID 格式，避免误匹配其他类似格式的字符串。建议为不同类型的 ID 使用专用的模式定义。\n\n第三，别名映射系统适合在 LLM 对话场景中使用，通过 `createAliasMap` 创建的映射可以在多轮对话中复用，减少令牌消耗。确保在对话开始时注册所有需要处理的标识符，然后在对话结束时使用 `restore` 方法恢复原始值。\n\n最后，对于安全敏感的应用场景，验证模块应作为防御性编程的一部分，在接收外部输入的 ID 时始终调用 `validate` 函数进行检查，切勿仅依赖格式解析结果假设 ID 有效。\n\n---\n\n<a id='page-wordlist-design'></a>\n\n## 词表设计\n\n### 相关页面\n\n相关主题：[随机 ID 生成](#page-id-generation), [安装与快速开始](#page-installation)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/wordlist.ts](https://github.com/vostride/id-agent/blob/main/src/wordlist.ts)\n- [scripts/validate-wordlist.ts](https://github.com/vostride/id-agent/blob/main/scripts/validate-wordlist.ts)\n- [scripts/build-wordlist.ts](https://github.com/vostride/id-agent/blob/main/scripts/build-wordlist.ts)\n- [src/parse.ts](https://github.com/vostride/id-agent/blob/main/src/parse.ts)\n- [src/deterministic.ts](https://github.com/vostride/id-agent/blob/main/src/deterministic.ts)\n</details>\n\n# 词表设计\n\nid-agent 的词表（Wordlist）是生成人类可读 ID 的核心组件，由 4096 个精心筛选的英文单词组成。本文档详细介绍词表的设计目标、构建流程、质量标准和使用方式。\n\n## 概述\n\nid-agent 的词表是一个经过多轮筛选的 4096 词集合，每个单词恰好对应 o200k_base 分词器中的一个 BPE token。这意味着使用该词表生成的 ID 在 token 效率上远优于传统的 UUID 或十六进制字符串。\n\n词表的核心设计原则：\n\n- **熵值保证**：每个单词贡献 12 bits 熵值（log₂(4096) = 12）\n- **分词友好**：所有单词在主流 LLM 分词器中都是单 token\n- **可读性**：单词长度控制在 3-6 个字符\n- **安全性**：过滤了冒犯性词汇和同音异义词\n- **不可变性**：词表数组被冻结（frozen），不可修改\n\n资料来源：[src/wordlist.ts:1]()\n\n## 构建流程\n\n词表的构建是一个六阶段的筛选过程，每一阶段都有明确的质量目标：\n\n```mermaid\ngraph TD\n    A[o200k_base 词汇表] --> B[长度过滤 3-6字符]\n    B --> C[系统词典验证]\n    C --> D[BPE 单token验证]\n    D --> E[连字符前缀验证]\n    E --> F[冒犯词过滤]\n    F --> G[同音异义词去重]\n    G --> H[4096词最终词表]\n```\n\n### 第一阶段：候选词提取\n\n从 o200k_base BPE 词汇表中提取所有 3-6 个小写字母组成的单词作为候选词。这一阶段通常产生数万个候选词。\n\n```typescript\nconst parts = o200k_base.bpe_ranks.split(' ')\nconst candidateSet = new Set<string>()\n\nfor (const b64 of parts) {\n  if (!b64.trim()) continue\n  const bytes = Buffer.from(b64, 'base64')\n  const text = bytes.toString('utf-8')\n  const word = text.startsWith(' ') ? text.slice(1) : text\n  if (/^[a-z]{3,6}$/.test(word)) candidateSet.add(word)\n}\n```\n\n资料来源：[scripts/build-wordlist.ts:45-58]()\n\n### 第二阶段：词典过滤\n\n使用系统词典 `/usr/share/dict/words` 验证候选词的有效性，确保每个单词都是真实存在的英文单词。\n\n```typescript\nconst dictFiltered = candidates.filter((w) => dictWords.has(w))\n```\n\n资料来源：[scripts/build-wordlist.ts:69-78]()\n\n### 第三阶段：单 Token 验证\n\n使用 `js-tiktoken` 库验证每个单词在 o200k_base 分词器中是否恰好编码为单个 token。这是确保 token 效率的关键步骤。\n\n```typescript\nconst enc = new Tiktoken(o200k_base)\nconst singleToken = dictFiltered.filter((w) => enc.encode(w).length === 1)\n```\n\n资料来源：[scripts/build-wordlist.ts:79-82]()\n\n### 第四阶段：连字符前缀验证\n\n验证单词在添加连字符前缀后仍保持高效编码（不超过 2 个 token）。这是为了确保生成的 ID（如 `storm-delta-stone`）在 LLM 上下文中保持 token 效率。\n\n```typescript\nconst hyphenValid = singleToken.filter((w) => enc.encode('-' + w).length <= 2)\n```\n\n资料来源：[scripts/build-wordlist.ts:83-85]()\n\n### 第五阶段：冒犯词过滤\n\n使用 `obscenity` 库检测并过滤冒犯性词汇，同时维护一个手动屏蔽列表：\n\n```typescript\nconst MANUAL_BLOCKLIST = [\n  'ass', 'crap', 'damn', 'hell', 'slut', 'rape', 'kill', 'die',\n  'fag', 'gay', 'drug', 'dumb', 'lame', 'nazi', 'pimp', 'porn',\n  'poop', 'puke', 'sexy', 'sick', 'anus', 'cunt', 'dick', 'tit',\n  'tits', 'boob', 'piss', 'shit', 'cock', 'whore', 'bitch',\n  'bastard', 'bloody', 'bugger', 'tosser', 'wank', 'twat',\n  'arse', 'shag', 'meth', 'heroin', 'crack', 'coke', 'weed',\n]\n\nconst matcher = new RegExpMatcher({\n  ...englishDataset.build(),\n  ...englishRecommendedTransformers,\n})\n\nconst cleanWords = hyphenValid.filter((w) => {\n  if (manualBlockSet.has(w)) return false\n  if (matcher.hasMatch(w)) return false\n  return true\n})\n```\n\n资料来源：[scripts/build-wordlist.ts:87-106]()\n\n### 第六阶段：同音异义词去重\n\n过滤同音异义词（homophones），避免因拼写相似造成的混淆：\n\n```typescript\nconst HOMOPHONE_GROUPS = [\n  ['air', 'heir'],\n  ['ate', 'eight'],\n  ['bare', 'bear'],\n  ['be', 'bee'],\n  ['blue', 'blew'],\n  ['buy', 'by', 'bye'],\n  ['cell', 'sell'],\n  ['cent', 'sent', 'scent'],\n  ['dear', 'deer'],\n  ['deer', 'dear'],\n  ['die', 'dye'],\n  ['eye', 'i'],\n  ['fair', 'fare'],\n  ['faze', 'phase'],\n  ['find', 'fined'],\n  ['flea', 'flee'],\n  ['flew', 'flu', 'flue'],\n  ['for', 'fore', 'four'],\n  ['gait', 'gate'],\n  ['greek', 'greak'],\n  ['hair', 'hare'],\n  ['hare', 'hair'],\n  ['hall', 'haul'],\n  ['heal', 'heel', 'heil'],\n  ['hear', 'here'],\n  ['him', 'hym'],\n  ['hym', 'him'],\n  ['isle', 'aisle'],\n  ['knead', 'kneed', 'need'],\n  ['knew', 'gnu'],\n  ['know', 'no'],\n  ['leach', 'leech'],\n  ['loan', 'lone'],\n  ['mail', 'male'],\n  ['main', 'mane', 'mean'],\n  ['meat', 'meet', 'mete'],\n  ['medal', 'meddle', 'metal'],\n  ['mede', 'meed'],\n  ['miner', 'minor'],\n  ['missed', 'mist'],\n  ['mist', 'missed'],\n  ['naval', 'navel'],\n  ['nude', 'newed'],\n  ['overdo', 'overdue'],\n  ['pail', 'pale'],\n  ['pain', 'pane'],\n  ['pair', 'pear', 'pare'],\n  ['palate', 'palette', 'pallet'],\n  ['pare', 'pair', 'pear'],\n  ['passed', 'past'],\n  ['past', 'passed'],\n  ['paten', 'pattern'],\n  ['pause', 'paws', 'pores', 'pours'],\n  ['peace', 'piece'],\n  ['pear', 'pair', 'pare'],\n  ['peer', 'pier'],\n  ['pores', 'pause', 'paws', 'pours'],\n  ['pour', 'pore', 'paw'],\n  ['pours', 'pause', 'paws', 'pores'],\n  ['pray', 'prey'],\n  ['principal', 'principle'],\n  ['rain', 'reign', 'rein'],\n  ['raise', 'rays', 'raze', 'reis'],\n  ['rapt', 'wrapped'],\n  ['reign', 'rain', 'rein'],\n  ['rein', 'rain', 'reign'],\n  ['rider', 'writer'],\n  ['right', 'rite', 'write', 'wright'],\n  ['road', 'rode', 'rowed'],\n  ['roe', 'row'],\n  ['role', 'roll'],\n  ['roux', 'rue'],\n  ['rows', 'rose'],\n  ['rye', 'wry'],\n  ['sail', 'sale'],\n  ['scene', 'seen'],\n  ['sea', 'see', 'si'],\n  ['seas', 'sees', 'seize'],\n  ['seize', 'seas', 'sees'],\n  ['senses', 'censes'],\n  ['sew', 'sough', 'so'],\n  ['sewn', 'sown'],\n  ['shear', 'sheer'],\n  ['shoe', 'shoo'],\n  ['side', 'sighed'],\n  ['sighed', 'side'],\n  ['sign', 'sine'],\n  ['sine', 'sign'],\n  ['sla', 'sley'],\n  ['sleigh', 'slay'],\n  ['slight', 'sleight'],\n  ['sley', 'sla'],\n  ['sole', 'soul'],\n  ['some', 'sum'],\n  ['son', 'sun'],\n  ['sown', 'sewn'],\n  ['stare', 'stair'],\n  ['stair', 'stare'],\n  ['stake', 'steak'],\n  ['steak', 'stake'],\n  ['steal', 'steel'],\n  ['steel', 'steal'],\n  ['step', 'steppe'],\n  ['steppe', 'step'],\n  ['stew', 'stoo', 'stu'],\n  ['stu', 'stew', 'stoo'],\n  ['stoo', 'stew', 'stu'],\n  ['suite', 'sweet', 'swete', 'sweat'],\n  ['sweet', 'suite', 'swete', 'sweat'],\n  ['swete', 'suite', 'sweet', 'sweat'],\n  ['tack', 'tact'],\n  ['tale', 'tail', 'tael'],\n  ['tail', 'tale', 'tael'],\n  ['tare', 'tear', 'tier'],\n  ['team', 'teem'],\n  ['tear', 'tare', 'tier'],\n  ['teem', 'team'],\n  ['teems', 'themes'],\n  ['their', 'there', 'theyre'],\n  ['threw', 'through'],\n  ['throe', 'throw'],\n  ['throne', 'thrown'],\n  ['thrown', 'throne'],\n  ['tide', 'tied'],\n  ['tied', 'tide'],\n  ['tier', 'tare', 'tear'],\n  ['tile', 'trial'],\n  ['to', 'too', 'two'],\n  ['told', 'tolled'],\n  ['tolled', 'told'],\n  ['tone', 'towan'],\n  ['towan', 'tone'],\n  ['tray', 'trey'],\n  ['tread', 'tred'],\n  ['tred', 'tread'],\n  ['treek', 'trig'],\n  ['trig', 'treek'],\n  ['troth', 'truth'],\n  ['vane', 'vain', 'vein'],\n  ['vain', 'vane', 'vein'],\n  ['vein', 'vain', 'vane'],\n  ['wade', 'weighed'],\n  ['wait', 'weight'],\n  ['war', 'wore'],\n  ['waste', 'waist'],\n  ['way', 'weigh'],\n  ['weak', 'week'],\n  ['wear', 'where'],\n  ['wood', 'would'],\n]\n```\n\n资料来源：[scripts/build-wordlist.ts:32-43]()\n\n## 质量标准\n\n词表必须满足以下质量标准：\n\n| 标准 | 要求 | 验证方法 |\n|------|------|----------|\n| 词汇数量 | 恰好 4096 个 | 构建脚本最终输出验证 |\n| 单词长度 | 3-6 个字符 | 正则表达式 `/^[a-z]{3,6}$/` |\n| 分词效率 | 单 token（o200k_base） | js-tiktoken 编码测试 |\n| 连字符效率 | ≤2 tokens（-prefix） | js-tiktoken 编码测试 |\n| 词库有效性 | 存在于系统词典 | `/usr/share/dict/words` |\n| 安全性 | 无冒犯词 | obscenity 库 + 手动列表 |\n| 可读性 | 无同音异义词 | 手动同音词组列表 |\n| 不可变性 | frozen 数组 | `Object.isFrozen(WORDLIST)` |\n\n## 词表导出与使用\n\n### 导出格式\n\n词表以 TypeScript 常量形式导出，位于 `src/wordlist.ts`：\n\n```typescript\nexport const WORDLIST = [\n  'abb',\n  'abel',\n  'abets',\n  'abhor',\n  'abide',\n  'abler',\n  // ... 共 4096 个单词\n] as const\n\n// 冻结数组确保不可变\nObject.freeze(WORDLIST)\n```\n\n资料来源：[src/wordlist.ts:1]()\n\n### 使用方式\n\n词表在内部模块中被广泛使用：\n\n**随机 ID 生成**（用于 `createAliasMap` 等功能）：\n\n```typescript\nexport function createAliasMap(opts: AliasOptions): AliasMap {\n  const { words, allowCollision } = AliasOptionsSchema.parse(opts)\n  // ...\n  alias = selectRandomWords(words, WORDLIST).join('-')\n  // ...\n}\n```\n\n资料来源：[src/alias.ts:1-25]()\n\n**确定性 ID 生成**（使用 HMAC-SHA256）：\n\n```typescript\nexport async function deterministicId(input: string, opts?: IdAgentFromOptions): Promise<string> {\n  // ...\n  for (let i = 0; i < words; i++) {\n    selected[i] = WORDLIST[view.getUint16(i * 2) % 4096]\n  }\n  return formatId(validated.prefix, selected.join('-'))\n}\n```\n\n资料来源：[src/deterministic.ts:1-38]()\n\n### ID 解析与验证\n\n词表也用于验证和解析生成的 ID：\n\n```typescript\nexport function validate(id: string): ValidateResult {\n  // ...\n  if (parsed.words.length > 0) {\n    const invalid = parsed.words.filter(w => !wordSet.has(w))\n    if (invalid.length > 0) {\n      return { valid: false, reason: `unknown words: ${invalid.join(', ')}` }\n    }\n  }\n  // ...\n}\n```\n\n资料来源：[src/parse.ts:1-25]()\n\n## 验证脚本\n\n### validate-wordlist.ts\n\n构建完成后，使用验证脚本确认词表质量：\n\n```typescript\n// 验证单 token 编码\nconst singleTokenFails = allWords.filter(w => enc.encode(w).length !== 1)\n\n// 验证连字符前缀编码\nconst hyphenFails = singleTokenFails.filter(w => enc.encode('-' + w).length > 2)\n\ncheck(`All words are single BPE tokens (failures: ${singleTokenFails.length})`, singleTokenFails.length === 0)\ncheck(`All words pass hyphen-prefix test (failures: ${hyphenFails.length})`, hyphenFails.length === 0)\n```\n\n资料来源：[scripts/validate-wordlist.ts:1-20]()\n\n### 运行验证\n\n```bash\npnpm run validate\n```\n\n## 词表设计决策\n\n### 为什么选择 4096 个单词？\n\n- **数学基础**：4096 = 2¹²，每个单词贡献恰好 12 bits 熵值\n- **空间效率**：4096 个条目可存储在 12 位索引中（2 字节）\n- **映射便利**：确定性 ID 生成中，HMAC-SHA256 输出的 16 位字可映射到 4096 个单词（取模运算）\n\n### 为什么限制 3-6 个字符？\n\n- **BPE 兼容性**：在这个长度范围内的单词更可能在 o200k_base 中成为单 token\n- **可读性平衡**：过短的单词（如 \"a\"、\"I\"）增加同音词冲突；过长的单词增加 token 消耗\n- **ID 紧凑性**：较短的单词使生成的 ID 更紧凑易读\n\n### 为什么过滤同音异义词？\n\n在口语交流或听觉场景下，同音异义词（如 \"there\"/\"their\"/\"they're\"）会造成混淆。id-agent 主要用于 AI 上下文，但保持这种过滤可以：\n\n- 减少口头沟通歧义\n- 避免拼写相似性导致的视觉混淆\n- 提高 ID 的整体可读性\n\n## 总结\n\nid-agent 的词表设计是一个精心策划的多阶段流程，确保最终产出的 4096 个单词满足分词效率、可读性、安全性和不可变性等多重质量标准。这个词表是实现高 token 效率和人类可读 ID 生成的核心基础设施。\n\n词表在运行时被冻结，任何对 ID 格式的验证都依赖词表内容，这种设计保证了系统的一致性和可预测性。\n\n---\n\n<a id='page-crypto-module'></a>\n\n## 加密模块\n\n### 相关页面\n\n相关主题：[随机 ID 生成](#page-id-generation), [确定性 ID 生成](#page-deterministic-ids)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/crypto.ts](https://github.com/vostride/id-agent/blob/main/src/crypto.ts)\n- [src/generate.ts](https://github.com/vostride/id-agent/blob/main/src/generate.ts)\n- [src/deterministic.ts](https://github.com/vostride/id-agent/blob/main/src/deterministic.ts)\n- [src/alias.ts](https://github.com/vostride/id-agent/blob/main/src/alias.ts)\n- [src/wordlist.ts](https://github.com/vostride/id-agent/blob/main/src/wordlist.ts)\n</details>\n\n# 加密模块\n\n## 概述\n\nid-agent 的加密模块是整个库的核心安全基础，负责生成密码学安全的随机数并将其映射到人类可读的单词列表。该模块采用双重加密策略：\n\n1. **随机 ID 生成**：使用 Web Crypto API 的 CSPRNG（密码学安全伪随机数生成器）\n2. **确定性 ID 生成**：使用 HMAC-SHA256 哈希函数实现输入到 ID 的确定性映射\n\n加密模块的核心价值在于确保 ID 的唯一性和不可预测性，同时保持人类可读性和令牌效率。\n\n## 架构设计\n\n```mermaid\ngraph TD\n    A[输入] --> B{ID类型选择}\n    B -->|随机| C[随机ID生成流程]\n    B -->|确定性| D[确定性ID生成流程]\n    \n    C --> E[crypto.getRandomValues]\n    E --> F[从WORDLIST映射]\n    F --> G[格式化输出]\n    \n    D --> H[TextEncoder编码输入]\n    H --> I[HMAC-SHA256签名]\n    I --> J[DataView读取哈希]\n    J --> K[取模映射到WORDLIST]\n    K --> G\n    \n    G --> L[最终ID格式<br/>如: storm-delta-stone]\n```\n\n## 随机 ID 生成\n\n### 核心实现\n\n随机 ID 生成依赖浏览器的 `crypto.getRandomValues()` 方法，这是 Web Crypto API 提供的密码学安全随机数接口。 资料来源：[src/generate.ts:6-12]()\n\n```typescript\nfunction createIdAgent(): IdAgent {\n  const fn = ((opts?: IdAgentOptions): string => {\n    const validated = IdAgentOptionsSchema.parse(opts ?? {})\n    const words = validated.words ?? 8\n    const selected = selectRandomWords(words, WORDLIST)\n    return formatId(validated.prefix, selected.join('-'))\n  }) as IdAgent\n  // ...\n}\n```\n\n### 随机词选择机制\n\n`selectRandomWords` 函数从 4096 个单词的词表中选择随机单词。该函数内部调用 `crypto.getRandomValues()` 获取密码学安全的随机字节，然后通过取模运算将随机数映射到词表索引。 资料来源：[src/generate.ts:4-5]()\n\n### 安全性保证\n\n随机 ID 生成的安全性来源于：\n\n| 保障措施 | 说明 |\n|---------|------|\n| CSPRNG | 使用浏览器原生的 `crypto.getRandomValues()`，确保随机数不可预测 |\n| 均匀分布 | 取模运算确保每个词被选中的概率完全相等 |\n| 独立选择 | 每个词的位置独立随机选择，互不影响 |\n\n## 确定性 ID 生成\n\n### 核心实现\n\n确定性 ID 生成使用 HMAC-SHA256 算法，通过 Web Crypto API 实现。相同的输入总是产生相同的 ID，适用于需要可重现性的场景。 资料来源：[src/deterministic.ts:1-10]()\n\n```typescript\nexport async function deterministicId(input: string, opts?: IdAgentFromOptions): Promise<string> {\n  if (!input || typeof input !== 'string') {\n    throw new Error('input must be a non-empty string')\n  }\n  const validated = IdAgentFromOptionsSchema.parse(opts ?? {})\n  const words = validated.words ?? 8\n\n  if (!globalThis.crypto?.subtle) {\n    throw new Error('idAgent.from() requires Web Crypto API (crypto.subtle). Use HTTPS in browsers.')\n  }\n  // ...\n}\n```\n\n### HMAC-SHA256 签名流程\n\n```mermaid\ngraph LR\n    A[输入字符串] --> B[TextEncoder]\n    B --> C[UTF-8字节]\n    C --> D[crypto.subtle.importKey]\n    D --> E[HMAC密钥]\n    C --> F[crypto.subtle.sign]\n    E --> F\n    F --> G[256位签名]\n    G --> H[DataView读取]\n    H --> I[每16位取模4096]\n    I --> J[映射到WORDLIST]\n```\n\n### 关键步骤解析\n\n1. **密钥导入**：使用命名空间（默认 \"id-agent\"）作为 HMAC 密钥，确保不同应用的输出不会冲突 资料来源：[src/deterministic.ts:16-20]()\n\n2. **签名生成**：对输入字符串进行 HMAC-SHA256 签名，输出 256 位（32 字节）的签名 资料来源：[src/deterministic.ts:21-22]()\n\n3. **词表映射**：从签名中每 16 位（2 字节）读取一个无符号整数，对 4096 取模得到词表索引 资料来源：[src/deterministic.ts:23-27]()\n\n```typescript\nconst sig = await globalThis.crypto.subtle.sign('HMAC', key, enc.encode(input))\nconst view = new DataView(sig)\n\nconst selected: string[] = new Array(words)\nfor (let i = 0; i < words; i++) {\n  selected[i] = WORDLIST[view.getUint16(i * 2) % 4096]\n}\n```\n\n### 命名空间隔离\n\n确定性 ID 支持自定义命名空间实现域分离：\n\n```typescript\nconst id1 = await idAgent.from('user@example.com')\nconst id2 = await idAgent.from('user@example.com', { namespace: 'different-app' })\n// id1 !== id2\n```\n\n这允许同一输入在不同命名空间下产生不同的确定性 ID。 资料来源：[src/deterministic.ts:12]()\n\n## 别名映射模块\n\n别名映射模块利用加密随机数生成短别名，用于减少 LLM 上下文中的令牌消耗。 资料来源：[src/alias.ts:1-8]()\n\n### 别名生成算法\n\n```mermaid\ngraph TD\n    A[原始ID] --> B{ID已存在?}\n    B -->|是| C[返回已有别名]\n    B -->|否| D[生成新别名]\n    D --> E[selectRandomWords]\n    E --> F[从WORDLIST选择词]\n    F --> G{别名冲突?}\n    G -->|是| D\n    G -->|否| H[存储forward/reverse映射]\n    H --> I[返回别名]\n```\n\n### 加密安全保障\n\n别名映射同样使用 `selectRandomWords` 从 CSPRNG 获取随机数，确保别名不可预测。即使原始 ID 已知，也无法推断别名（除非存在映射表）。 资料来源：[src/alias.ts:2]()\n\n```typescript\nexport function createAliasMap(opts: AliasOptions): AliasMap {\n  const { words, allowCollision } = AliasOptionsSchema.parse(opts)\n  const forward = new Map<string, string>()\n  const reverse = new Map<string, string>()\n  \n  // ...\n  do {\n    alias = selectRandomWords(words, WORDLIST).join('-')\n  } while (reverse.has(alias) && !allowCollision)\n  // ...\n}\n```\n\n## 词表设计\n\n### 词表规格\n\n| 属性 | 值 | 说明 |\n|-----|-----|------|\n| 词数 | 4096 | 2^12，便于位运算映射 |\n| 每词熵 | 12 bits | log2(4096) = 12 |\n| 单词字符数 | 3-6 字符 | 经 o200k_base 分词器验证 |\n| 令牌效率 | 每词 1 token | 针对 o200k_base 优化 |\n\n### 词表约束\n\n词表经过多重过滤确保安全性和可用性：\n\n1. **词典验证**：所有单词必须存在于系统词典 `/usr/share/dict/words`\n2. **同音词过滤**：移除如 `wait`/`weight`、`weak`/`week` 等易混淆的同音词\n3. **冒犯性词汇移除**：使用 `obscenity` 库过滤不适当词汇\n4. **单令牌验证**：每个词在 o200k_base 分词器中恰好为 1 个 token\n\n## API 参考\n\n### 随机 ID 生成\n\n```typescript\nconst id = idAgent()                    // 默认 8 词 ID\nconst id5 = idAgent({ words: 5 })       // 5 词 ID\nconst idPrefixed = idAgent({ prefix: 'user', words: 4 })\n```\n\n### 确定性 ID 生成\n\n```typescript\nconst id = await idAgent.from('user@example.com')\nconst idCustom = await idAgent.from('user@example.com', {\n  namespace: 'my-app',\n  prefix: 'user',\n  words: 5\n})\n```\n\n### 别名映射\n\n```typescript\nconst aliases = createAliasMap({ words: 3 })\nconst alias = aliases.set('8cdda07b-85d2-459c-8a2a-83c8f9245dbe')\nconst original = aliases.get('storm-delta-stone')\n```\n\n## 安全注意事项\n\n| 场景 | 建议 |\n|------|------|\n| 浏览器环境 | 确保使用 HTTPS，Web Crypto API 在不安全上下文中不可用 |\n| 服务端环境 | Node.js 18+ 已原生支持 Web Crypto API |\n| 确定性 ID 命名空间 | 生产环境应使用唯一的命名空间避免冲突 |\n| 别名碰撞 | 默认情况下别名生成会避免碰撞，可通过 `allowCollision: true` 禁用 |\n\n## 性能特性\n\n- **随机 ID 生成**：同步操作，约 0.1-0.5ms\n- **确定性 ID 生成**：异步操作，约 1-5ms（首次调用需初始化 HMAC 密钥）\n- **别名映射**：O(1) 查找和插入\n\n## 与 UUID 的对比\n\n| 特性 | UUID v4 | id-agent (8词) |\n|------|---------|----------------|\n| 熵 | 122 bits | 96 bits |\n| 令牌数 | ~23 | ~11 |\n| 令牌节省 | - | ~52% |\n| 50%碰撞阈值 | ~2.7 * 10^18 | ~300 trillion |\n| 人类可读性 | 低 | 高 |\n\n---\n\n<a id='page-schemas-validation'></a>\n\n## Zod 验证架构\n\n### 相关页面\n\n相关主题：[解析与验证](#page-parsing-validation), [随机 ID 生成](#page-id-generation)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/schemas.ts](https://github.com/vostride/id-agent/blob/main/src/schemas.ts)\n- [src/types.ts](https://github.com/vostride/id-agent/blob/main/src/types.ts)\n- [src/parse.ts](https://github.com/vostride/id-agent/blob/main/src/parse.ts)\n- [src/deterministic.ts](https://github.com/vostride/id-agent/blob/main/src/deterministic.ts)\n- [src/alias.ts](https://github.com/vostride/id-agent/blob/main/src/alias.ts)\n</details>\n\n# Zod 验证架构\n\n## 概述\n\nid-agent 使用 Zod 作为核心验证库，版本为 4.3.6，构建了一套完整的输入验证体系。该验证架构覆盖了所有公开 API 的用户输入，确保数据类型安全、参数合法，并提供清晰的错误信息。\n\n**核心设计目标：**\n\n- 在开发阶段捕获无效输入，防止运行时错误\n- 提供人类可读的错误消息，帮助开发者快速定位问题\n- 保持类型安全，实现编译时与运行时的双重保障\n- 通过模式复用减少验证代码重复\n\n**依赖配置：**\n\n```json\n\"dependencies\": {\n  \"zod\": \"4.3.6\"\n}\n```\n\n资料来源：[package.json:25-27](https://github.com/vostride/id-agent/blob/main/package.json)\n\n---\n\n## 验证模式分类\n\nid-agent 的验证架构围绕三个核心 Schema 构建，分别服务于不同的功能模块。\n\n### 模式层级关系\n\n```mermaid\ngraph TD\n    A[用户输入] --> B[IdAgentOptionsSchema]\n    A --> C[IdAgentFromOptionsSchema]\n    A --> D[AliasOptionsSchema]\n    B --> E[创建随机 ID]\n    C --> F[创建确定性 ID]\n    D --> G[别名映射管理]\n    E --> H[验证通过]\n    F --> H\n    G --> H\n```\n\n### Schema 清单\n\n| Schema 名称 | 用途 | 使用场景 |\n|------------|------|---------|\n| `IdAgentOptionsSchema` | 随机 ID 生成选项 | `new IdAgent(opts?)` |\n| `IdAgentFromOptionsSchema` | 确定性 ID 生成选项 | `idAgent.from(input, opts?)` |\n| `AliasOptionsSchema` | 别名映射选项 | `createAliasMap(opts)` |\n\n---\n\n## IdAgentOptionsSchema\n\n用于验证随机 ID 生成的配置参数。这是用户创建 IdAgent 实例时的输入验证层。\n\n### 参数定义\n\n| 参数 | 类型 | 默认值 | 约束条件 | 说明 |\n|------|------|--------|----------|------|\n| `prefix` | `string \\| undefined` | `undefined` | 小写字母数字组合 | ID 类型前缀 |\n| `words` | `number` | `8` | 1-16 整数 | 单词数量，控制熵值 |\n\n### 验证规则\n\n```typescript\n// 伪代码表示验证逻辑\nprefix?: string  // 可选，若提供则必须是 lowercase alphanumeric\nwords?: number   // 可选，默认 8，范围 [1, 16]\n```\n\n**前缀验证：** 必须是纯小写字母和数字组成，不允许大写字符、下划线以外的特殊字符。\n\n**单词数验证：** 整数值必须在 1 到 16 之间。单词数直接决定 ID 的熵值：`总比特数 = words × 12`。\n\n### 错误处理\n\n当验证失败时，Zod 抛出 `ZodError`，包含详细的错误路径和消息。\n\n```typescript\n// 无效配置示例\nnew IdAgent({ words: 20 })    // 超出范围\nnew IdAgent({ prefix: 'USER' }) // 包含大写字母\n```\n\n资料来源：[src/schemas.ts](https://github.com/vostride/id-agent/blob/main/src/schemas.ts) 和 [src/deterministic.ts:7](https://github.com/vostride/id-agent/blob/main/src/deterministic.ts)\n\n---\n\n## IdAgentFromOptionsSchema\n\n用于验证确定性 ID 生成（基于 HMAC-SHA256）的配置参数。与随机 ID 不同，确定性生成需要额外的命名空间支持。\n\n### 参数定义\n\n| 参数 | 类型 | 默认值 | 约束条件 | 说明 |\n|------|------|--------|----------|------|\n| `prefix` | `string \\| undefined` | `undefined` | 小写字母数字组合 | ID 类型前缀 |\n| `words` | `number` | `8` | 1-16 整数 | 单词数量 |\n| `namespace` | `string` | `'id-agent'` | 非空字符串 | HMAC 密钥，用于域分离 |\n\n### 验证流程\n\n```typescript\nconst validated = IdAgentFromOptionsSchema.parse(opts ?? {})\nconst words = validated.words ?? 8  // 默认值处理\nconst namespace = validated.namespace ?? 'id-agent'\n```\n\n### 命名空间机制\n\n命名空间参数实现了域分离功能，相同的输入在不同命名空间下产生不同的 ID：\n\n```typescript\nconst id1 = await idAgent.from('user@example.com', { namespace: 'app1' })\nconst id2 = await idAgent.from('user@example.com', { namespace: 'app2' })\n// id1 !== id2\n```\n\n资料来源：[src/deterministic.ts:6-10](https://github.com/vostride/id-agent/blob/main/src/deterministic.ts)\n\n---\n\n## AliasOptionsSchema\n\n用于验证别名映射功能的配置参数。别名映射是 LLM 上下文优化的高级功能。\n\n### 参数定义\n\n| 参数 | 类型 | 默认值 | 约束条件 | 说明 |\n|------|------|--------|----------|------|\n| `words` | `number` | 是 | 1-16 整数 | 别名使用的单词数 |\n| `allowCollision` | `boolean` | `false` | 布尔值 | 是否允许别名碰撞 |\n\n### 别名生成逻辑\n\n```mermaid\ngraph LR\n    A[原始 ID] --> B{forward Map<br/>已有映射?}\n    B -->|是| C[返回已有别名]\n    B -->|否| D[生成新别名]\n    D --> E{反向 Map<br/>存在冲突?}\n    E -->|是 且 !allowCollision| D\n    E -->|否 或 allowCollision| F[存储映射]\n    F --> G[返回别名]\n```\n\n### 碰撞处理\n\n当 `allowCollision` 为 `false`（默认）时，系统保证别名映射的双射性质，即每个原始 ID 映射到唯一别名，每个别名映射回唯一原始 ID。\n\n资料来源：[src/alias.ts:4-9](https://github.com/vostride/id-agent/blob/main/src/alias.ts)\n\n---\n\n## ID 验证流程\n\n### validate 函数\n\n`validate` 函数是 ID 验证的核心入口，用于检查任意字符串是否为有效的 id-agent ID。\n\n### 验证步骤\n\n```mermaid\ngraph TD\n    A[输入字符串] --> B{包含大写字母?}\n    B -->|是| Z[无效: contains uppercase characters]\n    B -->|否| C{包含无效字符?}\n    C -->|是| Y[无效: contains invalid characters]\n    C -->|否| D[调用 parse 函数]\n    D --> E{解析结果为 null?}\n    E -->|是| X[无效: unrecognized format]\n    E -->|否| F{存在未知单词?}\n    F -->|是| W[无效: unknown words: xxx]\n    F -->|否| V[验证通过]\n```\n\n### 验证规则详解\n\n| 步骤 | 检查项 | 错误消息 | 正则表达式 |\n|------|--------|----------|------------|\n| 1 | 大写字母 | `contains uppercase characters` | `/[A-Z]/` |\n| 2 | 无效字符 | `contains invalid characters` | `/[^a-z0-9_-]/` |\n| 3 | 格式识别 | `unrecognized format` | parse 返回 null |\n| 4 | 词汇表验证 | `unknown words: {word}` | wordSet 查询 |\n\n### 验证结果类型\n\n```typescript\ninterface ValidationResult {\n  valid: boolean\n  prefix?: string      // 仅在 valid 为 true 时\n  wordCount?: number   // 仅在 valid 为 true 时\n  reason?: string     // 仅在 valid 为 false 时\n}\n```\n\n### 示例\n\n```typescript\nvalidate('task_storm-delta-stone')\n// => { valid: true, prefix: 'task', wordCount: 3 }\n\nvalidate('task_jump-notaword')\n// => { valid: false, reason: 'unknown words: notaword' }\n\nvalidate('INVALID')\n// => { valid: false, reason: 'contains uppercase characters' }\n```\n\n资料来源：[src/parse.ts:1-20](https://github.com/vostride/id-agent/blob/main/src/parse.ts)\n\n---\n\n## 类型系统集成\n\n### 类型定义架构\n\n```mermaid\ngraph TD\n    A[types.ts] --> B[IdAgentOptions]\n    A --> C[IdAgentFromOptions]\n    A --> D[AliasOptions]\n    A --> E[ValidationResult]\n    B --> F[IdAgentOptionsSchema]\n    C --> G[IdAgentFromOptionsSchema]\n    D --> H[AliasOptionsSchema]\n```\n\n### Schema 与类型对应关系\n\n| Schema | TypeScript 类型 | 来源 |\n|--------|----------------|------|\n| `IdAgentOptionsSchema` | `IdAgentOptions` | [src/types.ts](https://github.com/vostride/id-agent/blob/main/src/types.ts) |\n| `IdAgentFromOptionsSchema` | `IdAgentFromOptions` | [src/types.ts](https://github.com/vostride/id-agent/blob/main/src/types.ts) |\n| `AliasOptionsSchema` | `AliasOptions` | [src/types.ts](https://github.com/vostride/id-agent/blob/main/src/types.ts) |\n\n### 验证执行模式\n\n```typescript\n// 标准模式：使用 .parse()，失败时抛出 ZodError\nconst result = schema.parse(input)\n\n// 安全模式：使用 .safeParse()，返回结果对象\nconst result = schema.safeParse(input)\n```\n\nid-agent 默认使用 `.parse()` 模式，让无效输入直接抛出异常，便于开发阶段快速发现问题。\n\n---\n\n## 错误处理机制\n\n### ZodError 结构\n\n验证失败时抛出的错误对象包含完整的错误路径和上下文信息：\n\n```typescript\ntry {\n  new IdAgent({ words: 100 })\n} catch (error) {\n  if (error instanceof ZodError) {\n    console.log(error.errors)\n    // [{\n    //   code: \"too_big\",\n    //   maximum: 16,\n    //   type: \"number\",\n    //   path: [\"words\"],\n    //   message: \"Number must be less than or equal to 16\"\n    // }]\n  }\n}\n```\n\n### 错误码映射\n\n| Zod 错误码 | 触发条件 | 示例消息 |\n|-----------|---------|---------|\n| `too_small` | 值小于最小值 | `Number must be greater than or equal to 1` |\n| `too_big` | 值大于最大值 | `Number must be less than or equal to 16` |\n| `invalid_type` | 类型不匹配 | `Expected string, received number` |\n| `unrecognized_keys` | 包含未知键 | `Unrecognized key: unknownOption` |\n\n---\n\n## 验证性能考量\n\n### 模式编译\n\nZod Schema 在首次使用时进行编译，后续调用直接使用优化后的验证逻辑。id-agent 的 Schema 定义简洁，验证开销极低。\n\n### 词汇表查询优化\n\nID 验证中的词汇表检查使用 Set 数据结构：\n\n```typescript\nconst wordSet = new Set(WORDLIST)  // O(1) 查找\n```\n\n`WORDLIST` 包含 4096 个单词，Set 查询复杂度为 O(1)，验证 3-16 个单词的总复杂度为 O(n)，其中 n 为单词数量。\n\n---\n\n## 架构优势\n\n### 类型安全层次\n\n```\nTypeScript Compiler          Zod Runtime\n      │                            │\n      ▼                            ▼\n   类型定义 ──────────────────► Schema 定义\n   (编译期)                      (运行期)\n      │                            │\n      ▼                            ▼\n   IDE 提示                  实际验证\n   类型检查                  错误抛出\n```\n\n### 可维护性\n\n- Schema 集中定义于 `schemas.ts`\n- 类型集中定义于 `types.ts`\n- 验证逻辑与业务逻辑分离\n- 新增参数只需修改 Schema 定义\n\n### 开发者体验\n\n- 清晰的错误消息指明问题所在\n- 与 TypeScript 类型系统无缝集成\n- 支持 IDE 自动补全\n\n---\n\n## 相关资源\n\n- [Zod 官方文档](https://zod.dev)\n- [源码：schemas.ts](https://github.com/vostride/id-agent/blob/main/src/schemas.ts)\n- [源码：types.ts](https://github.com/vostride/id-agent/blob/main/src/types.ts)\n- [源码：parse.ts](https://github.com/vostride/id-agent/blob/main/src/parse.ts)\n\n---\n\n<a id='page-alias-system'></a>\n\n## 别名系统\n\n### 相关页面\n\n相关主题：[重复检测](#page-duplicate-detection), [随机 ID 生成](#page-id-generation)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/alias.ts](https://github.com/vostride/id-agent/blob/main/src/alias.ts)\n- [src/parse.ts](https://github.com/vostride/id-agent/blob/main/src/parse.ts)\n- [src/wordlist.ts](https://github.com/vostride/id-agent/blob/main/src/wordlist.ts)\n- [src/detect.ts](https://github.com/vostride/id-agent/blob/main/src/detect.ts)\n- [README.md](https://github.com/vostride/id-agent/blob/main/README.md)\n</details>\n\n# 别名系统\n\n## 概述\n\n别名系统（Alias System）是 id-agent 提供的一种高效令牌压缩机制，旨在将长标识符（如 UUID）映射为短小的、基于单词的别名，以便在 LLM 上下文中的传输。系统支持完整的双向映射、文本替换和还原功能。\n\n别名系统通过 `createAliasMap()` 工厂函数创建，返回一个 `AliasMap` 实例，该实例提供 `set()`、`get()`、`replace()`、`restore()` 和 `entries()` 等核心方法。\n\n资料来源：[src/alias.ts:3-10]()\n\n## 核心概念\n\n### 设计目标\n\n别名系统解决了 LLM 应用中的两个关键问题：\n\n1. **令牌效率**：长 UUID（如 `8cdda07b-85d2-459c-8a2a-83c8f9245dbe`）在 BPE 分词器中需要约 23 个令牌，而 3 个单词的别名（如 `storm-delta-stone`）仅需约 5 个令牌，节省约 78% 的令牌开销。\n\n2. **可读性**：单词形式的 ID 更容易在调试日志、API 响应和 LLM 输出中理解和引用。\n\n资料来源：[README.md](https://github.com/vostride/id-agent/blob/main/README.md)\n\n### 工作原理\n\n别名系统内部维护两个 Map 数据结构：\n- **正向映射**（forward）：存储原始 ID → 别名\n- **反向映射**（reverse）：存储别名 → 原始 ID\n\n```mermaid\ngraph LR\n    A[原始ID<br/>8cdda07b-85d2-...] -->|set| B[正向Map]\n    B -->|生成| C[别名<br/>storm-delta-stone]\n    C -->|存储| D[反向Map]\n    D -->|get| A\n```\n\n资料来源：[src/alias.ts:8-10]()\n\n## API 参考\n\n### createAliasMap(options?)\n\n创建别名映射实例。\n\n```typescript\nimport { createAliasMap } from 'id-agent'\n\nconst aliases = createAliasMap({ words: 3 })\n```\n\n#### 参数选项\n\n| 参数 | 类型 | 默认值 | 必填 | 描述 |\n|------|------|--------|------|------|\n| `words` | `number` | `8` | 否 | 每个别名的单词数量（1-16） |\n| `allowCollision` | `boolean` | `false` | 否 | 是否允许别名冲突 |\n\n资料来源：[src/alias.ts:3-6]()\n\n### AliasMap 实例方法\n\n#### set(original: string): string\n\n为给定的原始 ID 生成并存储一个别名。相同原始 ID 多次调用返回相同的别名。\n\n```typescript\nconst alias1 = aliases.set('8cdda07b-85d2-459c-8a2a-83c8f9245dbe')\n// => \"storm-delta-stone\"\n\nconst alias2 = aliases.set('8cdda07b-85d2-459c-8a2a-83c8f9245dbe')\n// => \"storm-delta-stone\" (相同)\n```\n\n资料来源：[src/alias.ts:12-18]()\n\n#### get(alias: string): string | undefined\n\n根据别名查询对应的原始 ID。\n\n```typescript\naliases.get('storm-delta-stone')\n// => \"8cdda07b-85d2-459c-8a2a-83c8f9245dbe\"\n```\n\n资料来源：[src/alias.ts:20-22]()\n\n#### replace(text: string, options?): string\n\n将文本中所有匹配指定模式的原始 ID 替换为对应的别名。\n\n```typescript\nconst text = 'Process 8cdda07b-85d2-459c-8a2a-83c8f9245dbe then 6ba7b810-9dad-11d1-80b4-00c04fd430c8'\nconst shortened = aliases.replace(text, {\n  pattern: /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi\n})\n// => \"Process storm-delta-stone then cloud-train-scope\"\n```\n\n| 参数 | 类型 | 描述 |\n|------|------|------|\n| `text` | `string` | 要进行替换的文本 |\n| `options.pattern` | `RegExp` | 匹配原始 ID 的正则表达式 |\n\n资料来源：[src/alias.ts:24-37]()\n\n#### restore(text: string): string\n\n将文本中所有别名还原为原始 ID。\n\n```typescript\nconst restored = aliases.restore('Process storm-delta-stone then cloud-train-scope')\n// => \"Process 8cdda07b-85d2-459c-8a2a-83c8f9245dbe then 6ba7b810-9dad-11d1-80b4-00c04fd430c8\"\n```\n\n资料来源：[src/alias.ts:39-41]()\n\n#### entries(): [original, alias][]\n\n返回所有映射对的数组，格式为 `[原始ID, 别名]`。\n\n```typescript\nfor (const [original, alias] of aliases.entries()) {\n  console.log(`${original} => ${alias}`)\n}\n```\n\n> ⚠️ 返回顺序是 `[original, alias]`，而非 `[alias, original]`。如需通过别名查询原始 ID，请使用 `get(alias)` 方法。\n\n资料来源：[README.md](https://github.com/vostride/id-agent/blob/main/README.md)\n\n## 典型使用场景\n\n### LLM 上下文压缩\n\n在向 LLM 发送请求前，将长 UUID 替换为短别名，并在处理完成后还原：\n\n```mermaid\nsequenceDiagram\n    participant App as 应用\n    participant AliasMap as AliasMap\n    participant LLM as LLM\n    participant Output as 输出\n\n    App->>AliasMap: set(uuid1), set(uuid2)\n    App->>AliasMap: replace(requestText)\n    App->>LLM: 发送压缩后的请求\n    LLM-->>App: 返回引用别名的响应\n    App->>AliasMap: restore(responseText)\n    App->>Output: 输出还原后的结果\n```\n\n```typescript\nconst aliases = createAliasMap({ words: 3 })\n\n// 1. 准备阶段：注册所有需要的 ID\naliases.set('8cdda07b-85d2-459c-8a2a-83c8f9245dbe')\naliases.set('6ba7b810-9dad-11d1-80b4-00c04fd430c8')\n\n// 2. 发送给 LLM 前：替换\nconst llmRequest = await sendToLLM(aliases.replace(prompt, {\n  pattern: /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi\n}))\n\n// 3. 处理 LLM 返回后：还原\nconst finalOutput = aliases.restore(llmOutput)\n```\n\n资料来源：[src/alias.ts:24-41]()\n\n### 与重复检测结合\n\n别名系统可与 `detectDuplicates` 功能结合使用，用于在 LLM 输出中检测重复的 ID：\n\n```typescript\nimport { createAliasMap, detectDuplicates } from 'id-agent'\n\nconst aliases = createAliasMap({ words: 3 })\n\n// 检测文本中的重复 ID\nconst dupes = detectDuplicates({\n  pattern: /[a-z]+(?:-[a-z]+)+/,\n  text: 'Found storm-delta-stone in file A and storm-delta-stone in file B',\n})\n// => [{ id: 'storm-delta-stone', count: 2 }]\n```\n\n资料来源：[src/detect.ts:1-21]()\n\n## 内部实现\n\n### 别名生成算法\n\n别名通过 `selectRandomWords` 函数从词表（WORDLIST）中随机选择指定数量的单词生成：\n\n```typescript\nalias = selectRandomWords(words, WORDLIST).join('-')\n```\n\n每个单词贡献 12 比特熵度（因为词表包含 4096 = 2¹² 个单词）。使用 3 个单词的别名提供 36 比特熵度。\n\n| 单词数 | 熵度 | ID 空间 | 典型令牌数 | vs UUID 节省 |\n|--------|------|---------|------------|---------------|\n| 3 | 36 bits | 6.9 × 10¹⁰ | ~5 | 78% |\n| 5 | 60 bits | 1.2 × 10¹⁸ | ~8 | 65% |\n| 8 | 96 bits | 7.9 × 10²⁸ | ~11 | 52% |\n\n资料来源：[src/wordlist.ts](https://github.com/vostride/id-agent/blob/main/src/wordlist.ts) 和 [README.md](https://github.com/vostride/id-agent/blob/main/README.md)\n\n### 替换正则构建\n\n`replace()` 方法内部按长度降序排序所有已注册的原始 ID，确保较长的 ID 优先匹配，避免部分匹配问题：\n\n```typescript\nfunction buildReplacementRegex(keys: string[]): RegExp | null {\n  if (keys.length === 0) return null\n  const sorted = [...keys].sort((a, b) => b.length - a.length)\n  const escaped = sorted.map(s => s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'))\n  return new RegExp(escaped.join('|'), 'g')\n}\n```\n\n例如，如果同时注册了 `abc` 和 `abcd`，会优先匹配 `abcd`。\n\n资料来源：[src/alias.ts:8-11]()\n\n### 冲突处理\n\n默认情况下，`set()` 方法会检查生成的别名是否已存在（通过 `reverse.has(alias)`）。如果发生冲突，会重新生成：\n\n```typescript\ndo {\n  alias = selectRandomWords(words, WORDLIST).join('-')\n} while (reverse.has(alias) && !allowCollision)\n```\n\n通过设置 `allowCollision: true` 可以禁用此检查，允许不同的原始 ID 共享相同别名（不推荐）。\n\n资料来源：[src/alias.ts:14-16]()\n\n## 最佳实践\n\n### 词数选择指南\n\n| 使用场景 | 建议词数 | 熵度 | 适用规模 |\n|----------|----------|------|----------|\n| 开发/测试 | 3 | 36 bits | < 309K items |\n| 小型应用 | 5 | 60 bits | < 1B items |\n| 生产 SaaS | 5 | 60 bits | < 1B items |\n| 高流量/分布式 | 8 (默认) | 96 bits | < 300T items |\n\n### 生命周期管理\n\n```mermaid\ngraph TD\n    A[创建 AliasMap] --> B[注册所有 ID]\n    B --> C{处理}\n    C -->|发送 LLM | D[replace]\n    C -->|接收响应 | E[restore]\n    D --> F[LLM 处理]\n    F --> E\n    E --> G{更多请求?}\n    G -->|是| C\n    G -->|否| H[销毁 AliasMap]\n```\n\n1. **预先注册**：在处理任何文本前，先通过 `set()` 注册所有需要用到的原始 ID\n2. **重用实例**：在整个会话期间复用同一个 AliasMap 实例\n3. **统一模式**：使用统一的正则表达式进行 `replace()` 和 `restore()`\n\n资料来源：[src/alias.ts:12-22]()\n\n## 错误处理\n\n别名系统使用 Zod 进行配置验证：\n\n```typescript\nconst { words, allowCollision } = AliasOptionsSchema.parse(opts)\n```\n\n无效选项会抛出 `ZodError`，并附带描述性错误信息。有效的 `words` 范围为 1-16。\n\n资料来源：[src/alias.ts:4]()\n\n## 与其他模块的关系\n\n```mermaid\ngraph TB\n    Alias[别名系统<br/>src/alias.ts] --> Crypto[加密模块<br/>src/crypto.ts]\n    Alias --> Wordlist[词表<br/>src/wordlist.ts]\n    Alias --> Parse[解析模块<br/>src/parse.ts]\n    Parse --> Validate[验证模块<br/>src/validate.ts]\n    Detect[重复检测<br/>src/detect.ts] -.->|组合使用| Alias\n    \n    classDef primary fill:#e1f5fe\n    class Alias primary\n```\n\n- **依赖 `selectRandomWords`**：别名生成使用加密安全的随机数生成器\n- **依赖 WORDLIST**：从 4096 个预验证单词中选择\n- **可与 `detectDuplicates` 组合**：检测 LLM 输出中的重复别名\n\n资料来源：[src/alias.ts:2-3]() 和 [src/parse.ts:1-3]()\n\n---\n\n<a id='page-duplicate-detection'></a>\n\n## 重复检测\n\n### 相关页面\n\n相关主题：[别名系统](#page-alias-system), [解析与验证](#page-parsing-validation)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [src/detect.ts](https://github.com/vostride/id-agent/blob/main/src/detect.ts)\n- [README.md](https://github.com/vostride/id-agent/blob/main/README.md)\n</details>\n\n# 重复检测\n\n## 概述\n\n重复检测（Duplicate Detection）是 id-agent 提供的核心功能之一，用于扫描文本内容中的重复 ID。该功能设计为纯函数，不依赖文件系统访问，适用于在 LLM 上下文中检测重复标识符、验证数据一致性以及在分布式系统中识别潜在的 ID 冲突问题。\n\n重复检测模块位于 `src/detect.ts`，通过正则表达式模式匹配来识别文本中出现的重复标识符。资料来源：[src/detect.ts:1-24]()\n\n## 工作原理\n\n### 核心算法流程\n\n重复检测采用基于正则表达式的模式匹配策略，通过以下步骤完成重复 ID 的识别：\n\n```mermaid\ngraph TD\n    A[输入: pattern + text] --> B{text 类型判断}\n    B -->|string| C[转换为数组: text]\n    B -->|string[]| D[直接使用数组]\n    C --> E[初始化 Map 和 RegExp]\n    D --> E\n    E --> F[遍历每个文本]\n    F --> G[重置 lastIndex]\n    G --> H[执行正则匹配]\n    H --> I{找到匹配?}\n    I -->|是| J[更新 Map 计数]\n    I -->|否| K{还有文本?}\n    J --> K\n    K -->|是| F\n    K -->|否| L[过滤 count > 1]\n    L --> M[返回 Duplicate 数组]\n    I -->|否| K\n```\n\n### 关键设计决策\n\n1. **纯函数设计**：不产生副作用，不访问外部状态，确保测试可重复性和并发安全性\n2. **自动补全全局标志**：如果用户提供的正则表达式缺少 `g` 标志，函数会自动添加，确保能够匹配所有出现位置\n3. **lastIndex 重置**：每次处理新文本前重置正则表达式的 `lastIndex`，避免跨文本匹配时的状态污染\n4. **灵活输入支持**：支持单个字符串或字符串数组作为输入源\n\n## API 参考\n\n### detectDuplicates 函数签名\n\n```typescript\nfunction detectDuplicates(opts: DetectOptions): Duplicate[]\n```\n\n### 类型定义\n\n| 类型 | 描述 |\n|------|------|\n| `DetectOptions` | 检测配置选项，包含匹配模式和待检测文本 |\n| `Duplicate` | 重复检测结果，包含 ID 字符串和出现次数 |\n\n### 参数配置\n\n| 参数 | 类型 | 必填 | 描述 |\n|------|------|------|------|\n| `pattern` | `RegExp` | 是 | 用于匹配 ID 的正则表达式模式 |\n| `text` | `string \\| string[]` | 是 | 待扫描的文本内容，可以是单个字符串或字符串数组 |\n\n### 返回值\n\n返回 `Duplicate[]` 数组，每个元素包含：\n\n| 字段 | 类型 | 描述 |\n|------|------|------|\n| `id` | `string` | 重复的 ID 字符串 |\n| `count` | `number` | 该 ID 出现的次数（仅包含 count > 1 的项） |\n\n## 使用示例\n\n### 基本用法：检测字符串中的重复 ID\n\n```typescript\nimport { detectDuplicates } from 'id-agent'\n\nconst dupes = detectDuplicates({\n  pattern: /[a-z]+(?:-[a-z]+)+/,\n  text: 'Found storm-delta-stone in file A and storm-delta-stone in file B',\n})\n// 返回值: [{ id: 'storm-delta-stone', count: 2 }]\n```\n\n资料来源：[README.md]()\n\n### 多文本检测：分析代码仓库中的重复项\n\n```typescript\nimport { detectDuplicates } from 'id-agent'\n\nconst dupes = detectDuplicates({\n  pattern: /task_[a-z]+(?:-[a-z]+)+/,\n  text: [\n    'const x = \"task_red-fox-run\"',\n    'const y = \"task_red-fox-run\"',\n  ],\n})\n```\n\n### 结合 UUID 模式检测\n\n```typescript\nimport { detectDuplicates } from 'id-agent'\n\nconst dupes = detectDuplicates({\n  pattern: /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi,\n  text: [\n    'Task A: 8cdda07b-85d2-459c-8a2a-83c8f9245dbe',\n    'Task B: 8cdda07b-85d2-459c-8a2a-83c8f9245dbe', // 重复\n    'Task C: 6ba7b810-9dad-11d1-80b4-00c04fd430c8',\n  ],\n})\n// 返回值: [{ id: '8cdda07b-85d2-459c-8a2a-83c8f9245dbe', count: 2 }]\n```\n\n## 实现细节\n\n### 源代码解析\n\n以下为核心实现代码（资料来源：[src/detect.ts:5-24]()）：\n\n```typescript\nexport function detectDuplicates(opts: DetectOptions): Duplicate[] {\n  const texts = typeof opts.text === 'string' ? [opts.text] : opts.text\n  const idMap = new Map<string, number>()\n  const re = new RegExp(\n    opts.pattern.source,\n    opts.pattern.flags.includes('g') ? opts.pattern.flags : opts.pattern.flags + 'g',\n  )\n\n  for (const text of texts) {\n    re.lastIndex = 0\n    let match\n    while ((match = re.exec(text)) !== null) {\n      idMap.set(match[0], (idMap.get(match[0]) ?? 0) + 1)\n    }\n  }\n\n  return [...idMap.entries()]\n    .filter(([, count]) => count > 1)\n    .map(([id, count]) => ({ id, count }))\n}\n```\n\n### 全局标志处理逻辑\n\n函数自动确保正则表达式携带 `g`（全局）标志：\n\n```mermaid\ngraph LR\n    A[输入 pattern] --> B{flags 包含 'g'?}\n    B -->|是| C[保持原 flags]\n    B -->|否| D[追加 'g' 标志]\n    C --> E[创建 RegExp]\n    D --> E\n```\n\n## 与其他模块的集成\n\n### 与别名映射系统配合使用\n\n重复检测可以与 `createAliasMap` 配合使用，用于验证映射前后的 ID 一致性：\n\n| 功能 | 函数 | 用途 |\n|------|------|------|\n| 缩短长 ID | `createAliasMap.replace()` | 减少 LLM 上下文中的 token 消耗 |\n| 恢复原始 ID | `createAliasMap.restore()` | 还原别名映射 |\n| 验证唯一性 | `detectDuplicates()` | 检测替换后是否存在重复别名 |\n\n### 典型工作流程\n\n```mermaid\ngraph LR\n    A[原始 UUID 列表] --> B[createAliasMap]\n    B --> C[生成别名映射]\n    C --> D[替换 UUID 为别名]\n    D --> E[发送到 LLM]\n    E --> F[LLM 响应]\n    F --> G[恢复原始 UUID]\n    G --> H[detectDuplicates 验证]\n    H --> I{存在重复?}\n    I -->|是| J[警告/处理冲突]\n    I -->|否| K[处理完成]\n```\n\n## 最佳实践\n\n### 正则表达式编写建议\n\n| 建议 | 说明 | 示例 |\n|------|------|------|\n| 使用捕获组 | 明确指定要匹配的 ID 格式 | `/task_[a-z]+(?:-[a-z]+)+/` |\n| 包含边界符 | 避免部分匹配问题 | `/\\\\b[a-f0-9-]{36}\\\\b/` |\n| 区分大小写 | 根据 ID 规范选择标志 | `i` 标志用于大小写不敏感 |\n| 避免过度贪婪 | 确保匹配精确的 ID 格式 | 使用 `{36}` 而非 `+` |\n\n### 性能优化建议\n\n1. **预编译正则表达式**：如果多次使用相同模式，预先创建正则表达式对象\n2. **批量处理文本**：将多个文本片段合并为数组一次性处理，减少循环开销\n3. **精确的 pattern**：避免过于宽泛的正则表达式，减少不必要的匹配尝试\n\n## 注意事项\n\n### 边界情况处理\n\n| 场景 | 行为 | 说明 |\n|------|------|------|\n| 空字符串输入 | 返回空数组 `[]` | 正则匹配无结果 |\n| 无匹配的文本 | 返回空数组 `[]` | 未发现任何匹配项 |\n| 无重复项 | 返回空数组 `[]` | 所有 ID 都只出现一次 |\n| 数组中有空字符串 | 正常处理 | 空字符串不产生匹配 |\n\n### 限制说明\n\n- 函数不验证匹配到的 ID 是否为有效的 id-agent 格式\n- 如果需要验证 ID 有效性，应额外调用 `validate()` 函数\n- 正则表达式的 `lastIndex` 属性在内部被管理，不会影响外部状态\n\n---\n\n---\n\n## Doramagic 踩坑日志\n\n项目：vostride/id-agent\n\n摘要：发现 8 个潜在踩坑项，其中 0 个为 high/blocking；最高优先级：能力坑 - 能力判断依赖假设。\n\n## 1. 能力坑 · 能力判断依赖假设\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：README/documentation is current enough for a first validation pass.\n- 对用户的影响：假设不成立时，用户拿不到承诺的能力。\n- 建议检查：将假设转成下游验证清单。\n- 防护动作：假设必须转成验证项；没有验证结果前不能写成事实。\n- 证据：capability.assumptions | hn_item:48191852 | https://news.ycombinator.com/item?id=48191852 | README/documentation is current enough for a first validation pass.\n\n## 2. 维护坑 · 维护活跃度未知\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：未记录 last_activity_observed。\n- 对用户的影响：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。\n- 建议检查：补 GitHub 最近 commit、release、issue/PR 响应信号。\n- 防护动作：维护活跃度未知时，推荐强度不能标为高信任。\n- 证据：evidence.maintainer_signals | hn_item:48191852 | https://news.ycombinator.com/item?id=48191852 | last_activity_observed missing\n\n## 3. 安全/权限坑 · 下游验证发现风险项\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：下游已经要求复核，不能在页面中弱化。\n- 建议检查：进入安全/权限治理复核队列。\n- 防护动作：下游风险存在时必须保持 review/recommendation 降级。\n- 证据：downstream_validation.risk_items | hn_item:48191852 | https://news.ycombinator.com/item?id=48191852 | no_demo; severity=medium\n\n## 4. 安全/权限坑 · 存在评分风险\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：风险会影响是否适合普通用户安装。\n- 建议检查：把风险写入边界卡，并确认是否需要人工复核。\n- 防护动作：评分风险必须进入边界卡，不能只作为内部分数。\n- 证据：risks.scoring_risks | hn_item:48191852 | https://news.ycombinator.com/item?id=48191852 | no_demo; severity=medium\n\n## 5. 安全/权限坑 · 来源证据：Consider an alternative wordlist\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：Consider an alternative wordlist\n- 对用户的影响：可能影响授权、密钥配置或安全边界。\n- 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_c1936412c9da41088e71fab995197a90 | https://github.com/vostride/id-agent/issues/2 | 来源类型 github_issue 暴露的待验证使用条件。\n\n## 6. 安全/权限坑 · 来源证据：Python port\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：Python port\n- 对用户的影响：可能影响授权、密钥配置或安全边界。\n- 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_d733a90c7db44b9789900ed24e77220e | https://github.com/vostride/id-agent/issues/1 | 来源讨论提到 python 相关条件，需在安装/试用前复核。\n\n## 7. 维护坑 · issue/PR 响应质量未知\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：issue_or_pr_quality=unknown。\n- 对用户的影响：用户无法判断遇到问题后是否有人维护。\n- 建议检查：抽样最近 issue/PR，判断是否长期无人处理。\n- 防护动作：issue/PR 响应未知时，必须提示维护风险。\n- 证据：evidence.maintainer_signals | hn_item:48191852 | https://news.ycombinator.com/item?id=48191852 | issue_or_pr_quality=unknown\n\n## 8. 维护坑 · 发布节奏不明确\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：release_recency=unknown。\n- 对用户的影响：安装命令和文档可能落后于代码，用户踩坑概率升高。\n- 建议检查：确认最近 release/tag 和 README 安装命令是否一致。\n- 防护动作：发布节奏未知或过期时，安装说明必须标注可能漂移。\n- 证据：evidence.maintainer_signals | hn_item:48191852 | https://news.ycombinator.com/item?id=48191852 | release_recency=unknown\n\n<!-- canonical_name: vostride/id-agent; human_manual_source: deepwiki_human_wiki -->\n",
      "summary": "DeepWiki/Human Wiki 完整输出，末尾追加 Discovery Agent 踩坑日志。",
      "title": "Human Manual / 人类版说明书"
    },
    "pitfall_log": {
      "asset_id": "pitfall_log",
      "filename": "PITFALL_LOG.md",
      "markdown": "# Pitfall Log / 踩坑日志\n\n项目：vostride/id-agent\n\n摘要：发现 8 个潜在踩坑项，其中 0 个为 high/blocking；最高优先级：能力坑 - 能力判断依赖假设。\n\n## 1. 能力坑 · 能力判断依赖假设\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：README/documentation is current enough for a first validation pass.\n- 对用户的影响：假设不成立时，用户拿不到承诺的能力。\n- 建议检查：将假设转成下游验证清单。\n- 防护动作：假设必须转成验证项；没有验证结果前不能写成事实。\n- 证据：capability.assumptions | hn_item:48191852 | https://news.ycombinator.com/item?id=48191852 | README/documentation is current enough for a first validation pass.\n\n## 2. 维护坑 · 维护活跃度未知\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：未记录 last_activity_observed。\n- 对用户的影响：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。\n- 建议检查：补 GitHub 最近 commit、release、issue/PR 响应信号。\n- 防护动作：维护活跃度未知时，推荐强度不能标为高信任。\n- 证据：evidence.maintainer_signals | hn_item:48191852 | https://news.ycombinator.com/item?id=48191852 | last_activity_observed missing\n\n## 3. 安全/权限坑 · 下游验证发现风险项\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：下游已经要求复核，不能在页面中弱化。\n- 建议检查：进入安全/权限治理复核队列。\n- 防护动作：下游风险存在时必须保持 review/recommendation 降级。\n- 证据：downstream_validation.risk_items | hn_item:48191852 | https://news.ycombinator.com/item?id=48191852 | no_demo; severity=medium\n\n## 4. 安全/权限坑 · 存在评分风险\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：风险会影响是否适合普通用户安装。\n- 建议检查：把风险写入边界卡，并确认是否需要人工复核。\n- 防护动作：评分风险必须进入边界卡，不能只作为内部分数。\n- 证据：risks.scoring_risks | hn_item:48191852 | https://news.ycombinator.com/item?id=48191852 | no_demo; severity=medium\n\n## 5. 安全/权限坑 · 来源证据：Consider an alternative wordlist\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：Consider an alternative wordlist\n- 对用户的影响：可能影响授权、密钥配置或安全边界。\n- 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_c1936412c9da41088e71fab995197a90 | https://github.com/vostride/id-agent/issues/2 | 来源类型 github_issue 暴露的待验证使用条件。\n\n## 6. 安全/权限坑 · 来源证据：Python port\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：Python port\n- 对用户的影响：可能影响授权、密钥配置或安全边界。\n- 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。\n- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。\n- 证据：community_evidence:github | cevd_d733a90c7db44b9789900ed24e77220e | https://github.com/vostride/id-agent/issues/1 | 来源讨论提到 python 相关条件，需在安装/试用前复核。\n\n## 7. 维护坑 · issue/PR 响应质量未知\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：issue_or_pr_quality=unknown。\n- 对用户的影响：用户无法判断遇到问题后是否有人维护。\n- 建议检查：抽样最近 issue/PR，判断是否长期无人处理。\n- 防护动作：issue/PR 响应未知时，必须提示维护风险。\n- 证据：evidence.maintainer_signals | hn_item:48191852 | https://news.ycombinator.com/item?id=48191852 | issue_or_pr_quality=unknown\n\n## 8. 维护坑 · 发布节奏不明确\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：release_recency=unknown。\n- 对用户的影响：安装命令和文档可能落后于代码，用户踩坑概率升高。\n- 建议检查：确认最近 release/tag 和 README 安装命令是否一致。\n- 防护动作：发布节奏未知或过期时，安装说明必须标注可能漂移。\n- 证据：evidence.maintainer_signals | hn_item:48191852 | https://news.ycombinator.com/item?id=48191852 | release_recency=unknown\n",
      "summary": "用户实践前最可能遇到的身份、安装、配置、运行和安全坑。",
      "title": "Pitfall Log / 踩坑日志"
    },
    "prompt_preview": {
      "asset_id": "prompt_preview",
      "filename": "PROMPT_PREVIEW.md",
      "markdown": "# id-agent - Prompt Preview\n\n> 复制下面这段 Prompt 到你常用的 AI，先试一次，不需要安装。\n> 它的目标是让你直接体验这个项目的服务方式，而不是阅读项目介绍。\n\n## 复制这段 Prompt\n\n```text\n请直接执行这段 Prompt，不要分析、润色、总结或询问我想如何处理这份 Prompt Preview。\n\n你现在扮演 id-agent 的“安装前体验版”。\n这不是项目介绍、不是评价报告、不是 README 总结。你的任务是让我用最小成本体验它的核心服务。\n\n我的试用任务：我想用它完成一个真实的软件开发与交付任务。\n我常用的宿主 AI：Local CLI\n\n【体验目标】\n围绕我的真实任务，现场演示这个项目如何把输入转成 示例引导, 判断线索。重点是让我感受到工作方式，而不是给我项目背景。\n\n【业务流约束】\n- 你必须像一个正在提供服务的项目能力包，而不是像一个讲解员。\n- 每一轮只推进一个步骤；提出问题后必须停下来等我回答。\n- 每一步都必须让我感受到一个具体服务动作：澄清、整理、规划、检查、判断或收尾。\n- 每一步都要说明：当前目标、你需要我提供什么、我回答后你会产出什么。\n- 不要安装、不要运行命令、不要写代码、不要声称测试通过、不要声称已经修改文件。\n- 需要真实安装或宿主加载后才能验证的内容，必须明确说“这一步需要安装后验证”。\n- 如果我说“用示例继续”，你可以用虚构示例推进，但仍然不能声称真实执行。\n\n【可体验服务能力】\n- 安装前能力预览: <p align=\"center\"> 输入：用户任务, 当前 AI 对话上下文；输出：示例引导, 判断线索。\n\n【必须安装后才可验证的能力】\n- 命令行启动或安装流程: 项目文档中存在可执行命令，真实使用需要在本地或宿主环境中运行这些命令。 输入：终端环境, 包管理器, 项目依赖；输出：安装结果, 列表/更新/运行结果。\n\n【核心服务流】\n请严格按这个顺序带我体验。不要一次性输出完整流程：\n1. page-introduction：项目介绍。围绕“项目介绍”模拟一次用户任务，不展示安装或运行结果。\n2. page-installation：安装与快速开始。围绕“安装与快速开始”模拟一次用户任务，不展示安装或运行结果。\n3. page-id-generation：随机 ID 生成。围绕“随机 ID 生成”模拟一次用户任务，不展示安装或运行结果。\n4. page-deterministic-ids：确定性 ID 生成。围绕“确定性 ID 生成”模拟一次用户任务，不展示安装或运行结果。\n5. page-wordlist-design：词表设计。围绕“词表设计”模拟一次用户任务，不展示安装或运行结果。\n\n【核心能力体验剧本】\n每一步都必须按“输入 -> 服务动作 -> 中间产物”执行。不要只说流程名：\n1. page-introduction\n输入：用户提供的“项目介绍”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n2. page-installation\n输入：用户提供的“安装与快速开始”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n3. page-id-generation\n输入：用户提供的“随机 ID 生成”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n4. page-deterministic-ids\n输入：用户提供的“确定性 ID 生成”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n5. page-wordlist-design\n输入：用户提供的“词表设计”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n【项目服务规则】\n这些规则决定你如何服务用户。不要解释规则本身，而要在每一步执行时遵守：\n- 先确认用户任务、输入材料和成功标准，再模拟项目能力。\n- 每一步都必须形成可检查的小产物，并等待用户确认后再继续。\n- 凡是需要安装、调用工具或访问外部服务的能力，都必须标记为安装后验证。\n\n【每一步的服务约束】\n- Step 1 / page-introduction：Step 1 必须围绕“项目介绍”形成一个小中间产物，并等待用户确认。\n- Step 2 / page-installation：Step 2 必须围绕“安装与快速开始”形成一个小中间产物，并等待用户确认。\n- Step 3 / page-id-generation：Step 3 必须围绕“随机 ID 生成”形成一个小中间产物，并等待用户确认。\n- Step 4 / page-deterministic-ids：Step 4 必须围绕“确定性 ID 生成”形成一个小中间产物，并等待用户确认。\n- Step 5 / page-wordlist-design：Step 5 必须围绕“词表设计”形成一个小中间产物，并等待用户确认。\n\n【边界与风险】\n- 不要声称已经安装、运行、调用 API、读写本地文件或完成真实任务。\n- 安装前预览只能展示工作方式，不能证明兼容性、性能或输出质量。\n- 涉及安装、插件加载、工具调用或外部服务的能力必须安装后验证。\n\n【可追溯依据】\n这些路径只用于你内部校验或在我追问“依据是什么”时简要引用。不要在首次回复主动展开：\n- https://news.ycombinator.com/item?id=48191852\n- https://github.com/vostride/id-agent#readme\n- README.md\n- src/index.ts\n- package.json\n- src/generate.ts\n- src/types.ts\n- src/schemas.ts\n- src/deterministic.ts\n- src/crypto.ts\n- src/wordlist.ts\n- scripts/validate-wordlist.ts\n\n【首次问题规则】\n- 首次三问必须先确认用户目标、成功标准和边界，不要提前进入工具、安装或实现细节。\n- 如果后续需要技术条件、文件路径或运行环境，必须等用户确认目标后再追问。\n\n首次回复必须只输出下面 4 个部分：\n1. 体验开始：用 1 句话说明你将带我体验 id-agent 的核心服务。\n2. 当前步骤：明确进入 Step 1，并说明这一步要解决什么。\n3. 你会如何服务我：说明你会先改变我完成任务的哪个动作。\n4. 只问我 3 个问题，然后停下等待回答。\n\n首次回复禁止输出：后续完整流程、证据清单、安装命令、项目评价、营销文案、已经安装或运行的说法。\n\nStep 1 / brainstorming 的二轮协议：\n- 我回答首次三问后，你仍然停留在 Step 1 / brainstorming，不要进入 Step 2。\n- 第二次回复必须产出 6 个部分：澄清后的任务定义、成功标准、边界条件、\n  2-3 个可选方案、每个方案的权衡、推荐方案。\n- 第二次回复最后必须问我是否确认推荐方案；只有我明确确认后，才能进入下一步。\n- 第二次回复禁止输出 git worktree、代码计划、测试文件、命令或真实执行结果。\n\n后续对话规则：\n- 我回答后，你先完成当前步骤的中间产物并等待确认；只有我确认后，才能进入下一步。\n- 每一步都要生成一个小的中间产物，例如澄清后的目标、计划草案、测试意图、验证清单或继续/停止判断。\n- 所有演示都写成“我会建议/我会引导/这一步会形成”，不要写成已经真实执行。\n- 不要声称已经测试通过、文件已修改、命令已运行或结果已产生。\n- 如果某个能力必须安装后验证，请直接说“这一步需要安装后验证”。\n- 如果证据不足，请明确说“证据不足”，不要补事实。\n```\n",
      "summary": "不安装项目也能感受能力节奏的安全试用 Prompt。",
      "title": "Prompt Preview / 安装前试用 Prompt"
    },
    "quick_start": {
      "asset_id": "quick_start",
      "filename": "QUICK_START.md",
      "markdown": "# Quick Start / 官方入口\n\n项目：vostride/id-agent\n\n## 官方安装入口\n\n### Node.js / npm · 官方安装入口\n\n```bash\nnpm install id-agent\n```\n\n来源：https://github.com/vostride/id-agent#readme\n\n## 来源\n\n- hn: https://news.ycombinator.com/item?id=48191852\n- docs: https://github.com/vostride/id-agent#readme\n",
      "summary": "从项目官方 README 或安装文档提取的开工入口。",
      "title": "Quick Start / 官方入口"
    }
  },
  "validation_id": "dval_2a0852d5fef348169093f1e032291cfc"
}
