SenseNova-Skills 引用渲染实战:sn-prepare-citations 如何把 `[^key]` 脚注一键转换为 `[N]` 编号引用并产出最终报告

发布时间:2026/10/13 8:16:54
SenseNova-Skills 引用渲染实战:sn-prepare-citations 如何把 `[^key]` 脚注一键转换为 `[N]` 编号引用并产出最终报告 AI 技能人工智能深度研究数据分析媒体生成【免费下载链接】SenseNova-SkillsModular SenseNova skills for building AI-powered office assistants and productivity workflows项目地址https://gitcode.com/gh_mirrors/se/SenseNova-Skills点击查看免费下载本篇技术指南围绕 SenseNova-Skills 仓库中的sn-prepare-citationsSkill 展开深入讲解它如何承接sn-deep-research的终稿stitched.md完成引用去重、编号化渲染、L0 摘要框与 TOC 生成、参考文献追加的全套后处理工序。读完本文你将掌握该脚本的两种运行模式、全部命令行参数、基于源码的九步处理流水线细节以及如何在控制器层用其 stdout 结构化输出做交付门控。定位deep-research 流水线的最后一道渲染工序sn-prepare-citations在 SenseNova-Skills 中的职责非常聚焦终稿完成且脚注需要后处理时去重[^key]引用、转换为[N]编号并追加参考文献。其官方能力描述定义在 skills/sn-prepare-citations/SKILL.md 的 frontmatter 中。它面向的典型输入是sn-deep-researchheavy 模式产出的stitched.md。在 sn-deep-research 主 SKILL 的第 5.10 节「rendersn-prepare-citations 脚本」中该脚本被明确编排为渲染阶段的执行者从evidence.json收集sources[]将正文中的[^source_id]转换为[N]编号引用插入 L0/TOC并追加参考文献。整个 render 阶段的实际实现位于 scripts/prepare_citations.py当前版本 v2.2。三个关键标记理解引用渲染的对象在深入命令之前先厘清流水线中流转的三种引用形态这是理解整个 Skill 的前提标记形态出现位置含义[^source_id]writer / stitcher 产出的正文引用键指向evidence.json中sources[].id如[^semi_industry_2024][^d1.c1]正文异常形态claim-id 泄漏writer 把 evidence 内部索引d1.c1误当成引用键[N]render 后的report.md最终编号引用按正文首次出现顺序分配如[1]、[2]其中[^source_id]是唯一合法的引用键形式。按 evidence.schema.md 的契约每个 source 包含id形如^[a-z][a-z0-9_]*$、url、title、qualityprimary/secondary/tertiary与可选的published_at而每个 claim 的evidence[]通过source_id指回sources[]。sn-prepare-citations正是以这些元数据为来源构建引用池。快速上手两种运行模式脚本通过python3 scripts/prepare_citations.py运行支持两种模式。v2.1/v2.2 完整渲染模式推荐传入--outline与--output自动启用 L0 摘要框渲染与 TOC 自动生成除非显式用--no-l0/--no-toc关闭。SKILL.md 给出的推荐用法sn-deep-research v2为python3 scripts/prepare_citations.py \ --report report_dir/stitched.md \ --evidence report_dir/sub_reports/d1.evidence.json report_dir/sub_reports/d2.evidence.json \ --outline report_dir/outline.json \ --output report_dir/report.md这也是 sn-deep-research 主 SKILL 中 §5.10 的实际调用形态其--evidence参数可写成{report_dir}/sub_reports/d*.evidence.json由 shell 展开。v2.0 旧兼容模式不传--outline/--output时脚本直接覆写--report指向的文件仅做引用编号和参考文献追加不生成 L0 与 TOCpython3 prepare_citations.py --report report.md \ --evidence d1.evidence.json d2.evidence.json ...按 SKILL.md 的说明sn-deep-research 正常流程不使用该模式——它是为向后兼容而保留的 v2.0 行为。参数详解参数说明--report输入 markdown。sn-deep-research 中通常是stitched.md必填--evidence全部d*.evidence.json用于收集 source 元数据和修复 claim-id 泄漏必填可传多个nargs--outline可选但推荐。提供 L0、TOC 和标题结构信息即outline.json--output输出 markdown。sn-deep-research 中通常是report.md缺省时覆写--report--no-l0关闭 L0 摘要层渲染即使提供了--outline--no-toc关闭 TOC 渲染即使提供了--outline源码层面的行为细节见 prepare_citations.py 的main()L419-L536--report指向的文件不存在、任一--evidence文件缺失、--outline文件不存在或不是合法 JSON都会在 stdout 输出{success: false, error: ...}并以exit 1退出--evidence中无法解析OSError/JSONDecodeError的文件会被跳过并在 stderr 打印WARN不会中断流程若从所有 evidence.json 中未收集到任何有效 sourceidurl对脚本会报错退出输出文件所在目录会自动创建output_path.parent.mkdir(parentsTrue, exist_okTrue)citations.json始终写在输出文件同目录下。处理逻辑源码级九步流水线SKILL.md 将处理逻辑概括为九个步骤下面结合 prepare_citations.py 的实现逐一展开。第 1 步从所有 evidence.json 收集引用元数据collect_sources()L67-L131遍历全部d*.evidence.json读取其顶层sources[]为每个 source 构建Citation数据类实例L44-L51字段包括primary_id、url、title、quality缺省tertiary、aliases与index。同时它还索引claims[]对每个 claim 收集其evidence[].source_id构建claim_to_sources[claim_id] [source_id, ...]映射表供后续 claim-id 泄漏修复使用。第 2 步按 URL 归一化去重_normalize_url()L56-L62对每条 source 的 URL 做归一化小写 scheme 与 host、去掉 path 末尾斜杠、丢弃 fragment保留 query 与 params。归一化后的 URL 作为去重键同一 URL 出现在多个 evidence.json 时合并为同一个Citation首个出现的id胜出成为primary_id后续出现的同 URL 不同id被记录为该 primary 的aliases并写入alias_map[任意id] primary_id。这意味着d1.evidence.json与d3.evidence.json引用了同一个网页时最终报告里只会出现一个编号不会重复列参考文献。第 3 步检测并修复 claim-id 泄漏这是 v2.2 新增的核心能力。writer agent 偶尔会把 evidence 内部索引[^d{N}.c{M}]如[^d8.c19]误当引用键。repair_claim_id_leakage()L144-L194用正则\[\^(d\d\.c\d)\]扫描正文若该 claim-id 能在某个 evidence.json 的claims[]中找到就查询claim_to_sources把它替换为该 claim 的evidence[].source_id列表可能展开为多个[^source_id]若找不到对应 claim则保留原样后续作为 orphan 暴露出来。修复结果被完整记录在claim_id_leakage日志中包含total_occurrences、unique_claims、resolved含claim_id、occurrences、substituted_sources与unresolved含claim_id、occurrences。第 4 步扫描[^source_id]并按首次出现顺序编号process_citations()L197-L230用正则\[\^([\w\-.])\](?!:)匹配正文中的引用键负向断言(?!:)用于排除[^key]:形式的脚注定义行。处理规则按finditer的自然顺序遍历即按首次出现顺序分配[1]、[2]、[3]……编号同一 primary source 的多次引用包括别名共享同一个编号不重复计数在 evidence 中找不到对应 source 的 key 会被记入orphans并在正文中原样保留[^key]以保持可见方便后续修复。第 5 步替换[^source_id]→[N]清理脚注定义行编号确定后正文中所有[^source_id]被替换为[N]L226随后用_FOOTNOTE_DEF_RE行首^\[\^([\w\-.])\]:删除 writer 偶尔留下的脚注定义行并压缩连续空行re.sub(r\n{3,}, \n\n, ...)。这一步保证了终稿中不会残留任何 Markdown 脚注语法。第 6 步根据 outline 插入或校准 L0 / TOCL0 摘要框当传入--outline且未指定--no-l0时源码enable_l0 bool(args.outline) and not args.no_l0先检测正文顶部 2000 字符内是否已存在 L0 框识别三种 marker **核心摘要**、 **Key Findings**、 **TL;DR**_L0_MARKERSL236若已存在则标记l0_already_present不重复插入否则读取outline.json的L0_draft.key_findings渲染为 Markdown blockquote 形式的「核心摘要」框并插入到第一个 H1 之后insert_l0_after_h1()L255-L272无 H1 时退化为前置到文首。TOC 自动生成用_HEADING_RE^(##|###)\s扫描 H2/H3 标题跳过 H4 及更深层级跳过标题集合_TOC_SKIP_TITLES {参考文献, References, 目录, Table of Contents, TOC}避免循环引用与噪音L282每个标题经slugify()L285-L295生成 GitHub 风格锚点小写化、去除[N]前缀标记、非词字符转连字符、折叠连续连字符且保留中文CJK字符因此中文标题的锚点可直接用于文档内跳转若正文中已有 stitcher 放置的占位符!-- TOC will be inserted by render stage --则原位替换否则在第一个非跳过 H2 之前插入## 目录块insert_toc()L315-L333。第 7 步追加## 参考文献按编号顺序渲染参考文献列表render_bibliography()L338-L341每行格式为{index}. {title}追加在正文末尾## 参考文献 1. [中国半导体行业 2024 年度报告](https://www.semi.org.cn/report/2024) 2. [Chinas chip industry: domestic substitution drive](https://www.ft.com/content/china-chip-2024)若没有收集到任何编号引用则不追加参考文献章节L408-L412。第 8 步写出report.md与同目录citations.json终稿写入--output或覆写--report。同时导出结构化引用数据citations.jsonexport_citations_json()L344-L359schema_version为2.1每条引用包含index、id、url、title、quality与排序后的aliases排除 primary 自身。该 JSON 可作为后续链路如工作台 UI、审计消费机器可读的引用清单。第 9 步stdout 输出结构化 JSON脚本在 stdout 打印完整的结构化结果L495-L532字段包括基础信息success、schema_version、input_report、output_report、citations_path、total_citations扫描统计evidence_files_scanned、sources_in_pool去重后 source 总数、deduped_aliases跨文件合并的别名数量渲染状态render内含l0_inserted、l0_already_present、toc_items、toc_inserted、claim_id_leakage质量告警按需出现orphan_citations与warning说明「已在终稿保留[^key]原样需要回头由 review/writer agent 修复」claim-id 泄漏明细claim_id_leakage与可读化的claim_id_leakage_message。main()全程没有print以外的日志混入 stdoutWARN 走 stderr因此控制器可以稳定地把 stdout 整体解析为 JSON。交付门控控制器如何处理渲染结果SKILL.md 明确规定了控制器orchestrator的检查要求这也是 sn-deep-research 主 SKILL §5.10 的「门控」逻辑stdout 信号控制器动作orphan_citations非空不要交付回 writer/stitcher 修正引用或删除 unsupported 内容claim_id_leakage.unresolved非空不要交付回 writer 修正[^dN.cM]claim_id_leakage.resolved非空但unresolved为空可以继续但记录为警告writer 后续应直接输出[^source_id]无 orphan / unresolved完成交付report.md与citations.json这与 review agent 的检查口径一致渲染前stitched.md中[^source_id]必须存在于 evidence sources[^dN.cM]claim-id 泄漏属于硬伤渲染后的report.md再检查最终引用编号与参考文献渲染。注意 stitcher 阶段本身也受合同约束——report-stitcher.md 规定 stitched.md 中不得包含参考文献章节或脚注定义引用键[^source_id]原样保留统一由 render 阶段生成编号。在 deep-research 流水线中的三种用法从 sn-deep-research 主 SKILL §5.10 的表格可知render 阶段的输入随模式不同而不同模式--report输入--outlineheavy{report_dir}/stitched.md带normal{report_dir}/sections/s_full.md省略quick{report_dir}/sections/s_full.md省略无 outline.json其中有两个值得注意的编排细节heavy 模式固定传--no-l0L0 摘要已由 stitcher 按organization_decision.opening_summary写入stitched.mdrender 阶段不再重复生成通用摘要TOC 开关跟随 outlineorganization_decision.tocfalse时同时传--no-toc为true时不传让脚本替换 stitcher 放置的 TOC 占位符。toc与numbered_headings字段定义于 outline.schema.md 的organization_decision中。quick / normal 模式无 outline.json由一次成文 writer 自行确定标题与主体结构render 不额外套摘要或目录默认值。常见问题与排查建议出现orphan_citations正文中有[^key]在任意 evidence.json 的sources[]中都找不到对应 id。典型原因是 writer 引用了未经研究阶段登记的来源或 source 被后续编辑改名。处理方式是回 writer/stitcher 修正引用或删除 unsupported 内容切勿强行交付。出现claim_id_leakage.unresolved[^dN.cM]在 evidence.json 的claims[]中找不到根因是 writer 把 claim.id 当引用键使用源码中的claim_id_leakage_message明确提示「根本原因writer agent 把 claim.id 当引用键应改用 source.id」。应回 writer 修正。claim_id_leakage.resolved但unresolved为空脚本已自动查表完成替换可以继续交付但应把警告传递给 writer要求后续直接输出[^source_id]。同 URL 出现重复编号正常现象——脚本按 URL 归一化自动合并为同一编号这正是「去重[^key]引用」的设计目标deduped_aliases字段可查看合并数量。总体而言sn-prepare-citations把「人工逐个处理脚注」的繁琐工作收敛为一条可审计、可门控的自动化流水线以evidence.json为唯一事实来源以 stdout JSON 为质量信号最终交付编号干净、带摘要与目录、附参考文献的report.md是 SenseNova-Skills 中 deep-research 类技能稳定输出高质量终稿的关键一环。赞分享AI 技能人工智能深度研究数据分析媒体生成【免费下载链接】SenseNova-SkillsModular SenseNova skills for building AI-powered office assistants and productivity workflows项目地址https://gitcode.com/gh_mirrors/se/SenseNova-Skills点击查看免费下载相关推荐Nitter完整部署指南快速搭建无广告隐私版Twitter前端Nitter完整部署指南快速搭建无广告隐私版Twitter前端 Nitter 是一个免费开源的 Twitter 前端替代品本指南带你完整走完 NitterAI 技能人工智能深度研究数据分析媒体生成如何用 jq 的 csv 过滤器把 JSON 数组转为 CSV 并正确处理字段引号如何用 jq 的 csv 过滤器把 JSON 数组转为 CSV 并正确处理字段引号 手头有一批 JSON 数组数据需要输出为 CSV 文本比如给表格软件或CLI数据分析SenseNova-Skills 深度研究引擎sn-deep-research 多 Agent 编排流水线完全指南SenseNova Skills 深度研究引擎sn deep research 多 Agent 编排流水线完全指南 本指南以 SenseNova SkillsAI 技能人工智能深度研究数据分析媒体生成上一篇如何解决分布式计算难题Fluent数据驱动计算平台完整指南下一篇企业级BPM平台架构深度解析Camunda流程引擎的5个最佳实践与性能调优策略创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询