ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

软著申请自动化:用智能体Skill高效生成合规源代码文档

软著申请自动化:用智能体Skill高效生成合规源代码文档 关于“写软著”我折腾了大半个月从最初手动整理几百页源代码文档到最后用一套自研的 Copyright Forge Skill 跑通完整闭环中间踩过的坑和最后沉淀下来的方法值得拿出来仔细聊聊。这篇东西不是科普软著是什么而是记录我如何把一个重复、机械、高出错率的文档生产流程改造成一个半自动、可复用的智能体工作流。如果你也在搞软著申请或者对如何构建一个真正实用的 Agent Skill 感兴趣这篇内容应该能帮到你。1. 项目全貌为什么需要一套“写软著”的完整闭环1.1 “写软著”这件事到底卡在哪软件著作权申请听起来是个流程性事务但真正动手准备材料时大部分人都会在“源程序文档”和“软件说明书”这两个交付物上耗费大量时间。先说源程序文档的痛点需要提交前、后各30页源代码每页50行不足60页全部提交要求页眉标注软件名称和版本号右上角标注页码代码字体、字号有隐性要求不能出现敏感信息注释不能过于潦草不能贴明显的第三方开源协议头更不能直接截IDE的图。最坑的是如果你的代码总量超过60页你需要挑选“核心”部分而这个挑选标准往往很主观。我处理过一个项目代码总量接近2000行但分布在十几个文件里手动去拼凑这3000行代码60页 x 50行光复制粘贴就要几个小时还要处理编码格式、全角半角符号、注释乱码、页眉错位等问题。这还没有算上软件说明书撰写需要截图、排版、流程描述又得大半天。这类工作完全属于“低认知密度、高操作成本”的典型场景——它不考验你的编程能力但极度消耗耐心而且一旦中途被打断极易出错。我决定不再硬扛把它拆解成一个可编程、可驱动Agent执行的标准流程。1.2 从需求到产出Copyright Forge Skill 的核心定位我在设计的时候先给自己提了一个硬性要求这个Skill不能只是“帮我整理代码”它必须能独立完成从“读取仓库”到“生成符合软著办要求的PDF”的全过程中间不需要我人工修改格式。定位明确了它需要具备四个核心能力读取指定Git仓库的分支、文件结构识别核心源文件排除编译产物、依赖目录和配置文件。按软著要求进行代码采集过滤空行、合并行数、控制页数、嵌套页眉页脚。生成标准PDF并附带可选的“缩略版”源程序部分中心要求提交前30页与后30页中间可以省略但需要在文档中注明。对生成的PDF做自动校验检查页数、行数、格式、敏感词不满足条件就自动重新生成。这套闭环跑通后我从拿到一个代码仓库到获得可提交的文档耗时压缩到分钟级而且是全自动的。接下来我会拆解这个Skill的完整技术实现。2. 方案选型与核心设计思路2.1 为什么选择自研Skill而不是直接用现成脚本很多人一看这需求第一反应是“这不就是个Python脚本吗”确实用reportlab或wkhtmltopdf也能做。但我当时需要的是一个能放进Claude Code、Codex这类Agent环境里可以被自然语言驱动的工具集。纯粹的脚本有个问题它不理解上下文。比如说你的代码仓库里有“example”、“test”、“migration”这类目录哪些算核心代码哪些不算这需要判断。Skill的形态优势在于它把“指令”、“脚本”、“知识约束”打包在一起。我可以用自然语言对Agent说“基于当前仓库生成软著申请材料”Agent会调用Skill内置的处理流程按预设约束执行任务。一旦代码仓库更新重新执行一次对话即可不用改脚本逻辑。另外还有一个现实原因2026年3月15日软著新规开始实施对于“AI生成代码”的权属说明、原创性声明有了更严格的要求。如果只是跑一个脚本很难把这套合规检查纳入流程但做成Skill我就可以把“AI诚信承诺”相关的检测步骤做成强制检查节点避免因为代码中含有AI生成痕迹而被认定为权属不清。2.2 闭环的五个核心节点任何一个闭环流程本质是“输入 → 处理 → 输出 → 校验 → 反馈迭代”。我在设计时没有把校验放在最后而是放在输出之后并让它能回写到处理节点。五个节点分别是仓库扫描从Git仓库读取文件计算每个文件的代码行数排除非目标类型文件生成“待选文件清单”。代码筛选与清洗设定过滤规则剔除空行、注释比例过高的行、明显的第三方许可证头、纯装饰性分割线同时做编码统一统一为UTF-8无BOM。分页与排版将筛选后的代码按50行/页进行拆分生成带页眉的样张页脚居右页眉居中字体使用等宽字体我推荐Courier New或SongTi Mono避免字符宽度不一致导致行列错乱。PDF渲染将排版后的内容渲染为PDF同时生成一份“源代码文档结构说明”用于放在文档起始部分。自动校验重新解析PDF统计每页实际行数、总页数、页眉文字是否正确检查是否存在“TODO”、“FIXME”、“console.log”等可能被认为是不成熟代码的标志并将检查结果返回给用户。每一轮处理结束后校验结果会驱动下一轮修正。比如行数不足50行就补页超了就压缩代码密度或调整筛选阈值。这就是“Forge”的含义——反复锻打直到满足要求。2.3 与软著新规的适配思考这里特别提一下热词里频繁出现的“2026年3月15日软著新规”和“AI诚信承诺”。根据我的观察和资料确认新规的核心变化之一是对软件原创性的审核趋严特别是对使用AI辅助编程工具生成的项目可能需要提供更多的创作过程说明。我的应对方案是在Skill的生成物中除了标准的源程序和说明书增加一个可选的“AI生成内容声明模板”它不是必须提交的但可以在补正阶段作为解释材料。这个模板会列出开源框架名称、AI辅助工具名称、人类作者对代码最终审查与修改的说明。把这个部分纳入闭环是为了不让新规变成一个临时应对的问题而是一开始就考虑进去。3. 核心实现从Git仓库到符合软著要求的代码文档这一节是纯实操我从头到尾走一遍关键代码和配置逻辑。3.1 仓库扫描阶段如何识别“真正需要提交的代码”目标拿到一个代码仓库快速生成一个候选文件列表并按“核心程度”排序。我的做法是三步走第一步排除非源码目录。常规要排除node_modules, vendor, dist, build, .git, .idea, .vscode, __pycache__, target, venv, .env第二步按文件后缀过滤。不同的项目语言不同所以我会用配置项来指定SUPPORTED_EXTENSIONS { .py, .js, .ts, .java, .go, .c, .cpp, .h, .vue, .jsx, .tsx, .rb, .php, .swift, .kt, .rs }第三步计算每个文件的“核心度分数”。我的算法很简单但很有效被主入口文件import或require引用的文件得分3。文件行数在100行到2000行之间的得分2超过2000行的得分-1因为太大可能包含生成代码或大量资源类常量。文件名包含main、index、app、core、service、util、controller、model的按不同权重加分。测试文件和配置文件直接排除或最低分。核心度分数用于后续“如果代码超长优先从低分文件开始修剪”。3.2 代码清洗不能被提交的几类“脏数据”真实项目的源代码直接拿去生成PDF通常会遇到几类硬伤。第一类是编码问题。很多历史项目是GBK编码直接读UTF-8会导致乱码。我的方案是先用chardet检测编码再统一转为UTF-8import chardet def safe_read_code_file(filepath): raw open(filepath, rb).read() detected chardet.detect(raw) encoding detected.get(encoding) or utf-8 try: return raw.decode(encoding) except (UnicodeDecodeError, LookupError): return raw.decode(utf-8, errorsreplace)第二类是无效行。空行、只有花括号的行、纯注释行这些在软著文档里会占用大量空间而且行数虚高。但注意不能全部删干净那样代码可读性极差评审员可能觉得你造假。所以我的策略是最多合并连续空行为一行并保留结构性的空行。第三类是敏感信息。这是最有必要严格筛查的部分。硬编码的IP地址、数据库连接字符串、云厂商AccessKey、私钥片段等都需要被自动替换为脱敏占位符SENSITIVE_PATTERNS [ (r(?i)(AKIA[0-9A-Z]{16}), AKIA****************), (r((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d), x.x.x.x), (r-----BEGIN [A-Z ]*PRIVATE KEY-----.*?-----END [A-Z ]*PRIVATE KEY-----, [REDACTED]), ]这一步必须在任何排版之前做否则一旦渲染成PDF再发现敏感信息就得重新生成前面的工作全部白费。3.3 分页逻辑与“正文50行/页”的精确定制软著源程序文档的常规格式是每页不少于50行如果你的代码不足3000行可以全部提交如果超过就需要选择前、后各30页中间可以截断。但这里面有个容易忽略的细节页眉和页码本身占空间但每页代码行数按正文行数计算不是按物理行数。也就是说一页A4纸上面有页眉软件全称版本号、页码、代码正文代码正文字号通常在五号到小四之间用单倍行距或固定行距留足上下左右边距后要能放下50行。我的分页逻辑参考def paginate_code_lines(clean_lines, lines_per_page50): pages [] for i in range(0, len(clean_lines), lines_per_page): pages.append(clean_lines[i:i lines_per_page]) return pages这只是最简单的情况。实际中一页50行是上限如果你使用固定行距不同字体会导致行高不一致。我在实验中发现使用**固定行距16pt、字体12pt小四**时一页可以稳定放下50行代码但页边距必须设置为上下2.54cm、左右3.18cmWord默认或者更紧凑一点。如果一页放50行会挤压到页脚我建议减少为48行并且边上留出足够空间。毕竟评审员不会数每页是不是50行但如果你的一页只放30行且总页数虚高这就会被视为格式问题。我的经验是切到48行/页更保险因为不少PDF渲染引擎对行高的处理跟Word不同写着50行实际渲染后可能溢出一两行。3.4 用Python生成PDF两种方案对比生成PDF常见有两种路径我实测下来各有利弊。方案一先生成纯文本或HTML再通过工具转PDF。优点是排版灵活能精确控制页眉页脚缺点是需要额外依赖如wkhtmltopdf。方案二直接使用reportlab。它是Python生态里老牌PDF生成库控制精度很高但中文支持需要注册字体。我最终选的是混合方案先用Pillow或纯Python方式生成“模拟A4页面布局”再调用底层PDF库绘图。听起来有点土但实际效果非常可控。核心渲染伪代码如下from reportlab.lib.pagesizes import A4 from reportlab.pdfgen import canvas from reportlab.pdfbase.ttfonts import TTFont def generate_code_pdf(pages, output_path, software_name, version): pdf canvas.Canvas(output_path, pagesizeA4) width, height A4 font_path /usr/share/fonts/truetype/noto/NotoSansMonoCJK-Regular.ttc pdf.addFont(CodeFont, font_path, UTF-8) pdf.setFont(CodeFont, 10.5) top_margin 40 left_margin 50 line_height 14 max_lines_per_page 50 for page_idx, lines in enumerate(pages, start1): # 页眉 pdf.drawString(left_margin, height - 25, f{software_name} V{version}) # 页码 pdf.drawRightString(width - 50, 20, str(page_idx)) # 正文 y height - top_margin for line in lines: pdf.drawString(left_margin, y, line.rstrip()) y - line_height pdf.showPage() pdf.save()注意几个关键点字体必须使用支持中文的等宽字体Noto Sans Mono CJK 是我在Linux下试过比较稳的macOS下可以用 MenloWindows下可以用 Consolas 或 SimSun。line_height要配合字号和字体实际行高。设置14pt行距、10.5pt字号时50行需要占用高度为14 * 50 700pt。在A4页面高度842pt上减去页眉40pt、页脚30pt正文可用高度是772pt完全放得下700pt的内容。如果行数超出pdf.drawString会画到页面外但不会报错。必须在渲染后做一次文本高度校验。4. 从代码文档到“完整交付物”软件说明书与申请文件的一体化生成源程序PDF生成只是第一关。实际软著申请还需要一份《软件用户操作说明书》或《软件设计说明书》里面要包含软件功能结构、操作界面截图、操作流程描述、技术特点说明。这套资料以前也是纯手工活但既然流程已经闭环了我依然用Skill自动完成。4.1 基于README和代码结构生成说明书初稿其实80%的项目都写了README里面涵盖项目简介、安装步骤、使用方式。说明书的基础框架可以直接从README提取再结合代码结构补足“技术架构”章节。我的Skill里内置了一个“说明书装配器”步骤是读取README.md按段落拆解为Code, Modules, Install, Usage, Features等章节。扫描入口文件、核心模块的注释docstring提取每个模块的职责说明生成“系统模块结构”章节。扫描配置文件如package.json,pom.xml,requirements.txt 提取依赖信息生成“运行环境”表格。如果仓库里有截图目录或Markdown中引用了本地图片会自动转换为PDF兼容的相对路径。这样生成的是“初稿”不是最终成品。说明书必须有人的参与和润色但初稿自动化可以将时间从一整个下午压缩到十分钟。4.2 操作截图自动生成最佳尝试与局限关于截图这是最麻烦的部分。我试过用Selenium或Playwright启动Web应用自动截图再插入文档。如果项目有前端界面这条路走得通npx playwright install chromium python -m playwright screenshot --viewport-size1280,800 http://localhost:3000/home ./docs/screenshot_home.png但很多工具类软件、命令行软件、后端服务根本没有UI界面这时候说明书怎么办我的建议是不要硬生成截图而是把核心调用接口、命令行交互过程、核心输出的示例以“代码块运行日志”的方式放进说明书。软著审查时说明书的目的是让人理解这个软件是做什么的、怎么工作只要能说清楚就行。截图不是硬要求逻辑清晰比花哨的界面截图更重要。如果你非要带截图还有一个稳妥的办法画结构图或流程图。可以用draw.io或Graphviz生成模块调用关系图导成PNG再插入。这个方式对于后端起服务类项目尤其有效。4.3 合并打包一个“标准交付物”目录长什么样流程跑完后我会让Skill输出一个固定的目录结构这样每次提交给代理机构或自己填报时所有材料都是一致的output/ ├── 01_源程序_前30页.pdf ├── 02_源程序_后30页.pdf ├── 03_软件著作权_源程序_完整版.pdf可选 ├── 04_软件说明书.pdf ├── 05_源代码文件清单.txt ├── 06_AI生成声明.md可选 └── 07_申请信息校对表.md这个目录结构本身也是一种“闭环”设计——从最关键的源代码到说明文档到补充声明层层递进缺啥补啥。5. 自动校验如何确保生成了“能直接提交”的材料5.1 校验指标与阈值设定校验阶段的核心问题只有一个我生成的文件到底能不能直接交上去我设定了四类校验指标页数前30页、后30页是否满足要求如果不足60页是否提交了全部代码并且页数不少于60页对应的“全部代码”页数。每页行数随机抽查3页每页正文行数不低于48行不高于52行。字体与嵌入PDF中使用的字体是否已嵌入避免在打印或系统流转时字体丢失。用pdffonts命令可以验证。敏感内容遍历文本检测IP、密钥、电话、邮箱等模式。如果校验失败Skill会输出一条明确提示并自动回退到前一步重新调整参数生成。比如“第3页行数为47低于48需要调整行距或字号重新生成”。5.2 对“AI生成代码”的新合规检查项结合新规我在校验中增加了一个特殊步骤AI生成内容占比粗估。做法不复杂但很有参考意义。我用一个简单的规则统计文件中的注释行、文档字符串占整个文件比例偏高的加分可能是AI写代码时附带的大量注释。代码里出现大段重复性样板代码如大量相似的getter/setter可能有AI生成嫌疑。命名风格不一致的片段一部分用snake_case一部分用camelCase且没有任何规律可能存在AI混合生成。这个“检测”无法做到100%准确但它的目的并不是证明什么而是让我在提交之前心里有数。如果某部分确实是AI生成且没有经过人工充分修改我会在《AI生成声明》里如实填写而不是隐瞒。新规下诚实声明比事后被发现要好得多。5.3 一次完整的自动校验日志示例下面是我跑一个真实项目时得到的校验输出片段可以直观看到闭环效果[Copyright Forge] 开始校验生命周期 [OK] 源程序前段页数: 30 [OK] 源程序后段页数: 30 [OK] 中段省略说明已添加 [WARN] 第17页代码行为47行低于阈值 [INFO] 自动触发重新排版... [INFO] 行距调整: 14pt - 13.8pt [OK] 重新生成完成校验通过 [OK] 字体已嵌入 [OK] 未检测到明显敏感信息 [OK] AI生成内容声明已生成这个日志是我设计的“给人看”的迷你看板它不是为了炫技而是为了让我在提交之前花10秒确认一切正常而不是打开PDF一页一页数。6. 复盘这轮闭环改造中的“值”与“不值”6.1 哪些环节是真正省时间的整个流程跑下来最值钱的是“清洗—排版—校验”这个循环一旦代码仓库几百个文件手动挑选和清洗是最耗时的。自动化的价值不在于它写了多复杂的代码而在于它把“反复试错”变成了“一次计算”。源程序PDF的生成过去至少需要1到2个小时现在1分钟出初稿10分钟完成校验和调整这还不算反复修改的时间。说明书初稿自动化也能省下至少半小时文档整理时间。如果是多项目并行的场景这个Skill的复用价值能被放大到极致。6.2 哪些环节是“机器替代不了”的不要以为有了Skill就万事大吉。说明书里的“软件创新点”、“主要功能与技术指标”必须有人的判断与总结特别是评审员最关注的“软件运行效果”和“技术架构设计”这些不是能从代码里自动挖出来的。另一个是“代码排版的真实性”。如果自动清洗过度把项目原本的空行、注释全部删光产生的文档看起来会非常“假”。我用一个真实仓库测过如果清洗规则过于激进生成的PDF会出现大量连续的同构短行一眼看上去就是机器拼接的。系统或人工审查员见到这种文本第一反应就是材料有问题。所以我的规则始终是“清洗不改变代码语义排版不欺骗阅读者。”这就像做菜可以切好、摆盘但不能把食材本身换掉。6.3 后续可扩展的方向这套Skill后续有两个扩展方向。一个是接入软著局的在线填报系统把生成好的PDF自动填写到对应的栏目里需要处理验证码和登录目前合规性有待评估另一个是做成一个“批量管理工具”针对公司十几个软件产品一键生成各自独立的申请材料包并把每个项目的版本号、迭代日志统一管理起来。还有一个更贴合实际的小方向把它和CI/CD流水线结合。当代码仓库打上新的tag时自动触发一次软著文档的重新生成确保交到代理手里的材料永远与最新代码版本同步。这个方向对持续迭代的SaaS产品尤其有价值。7. 常见问题速查你大概率也会遇到的5个坑7.1 生成的PDF在别人电脑上打开中文全部变成方块这是字体没有嵌入的问题。我在reportlab里自定义字体时如果用了系统字体文件但未调用addFont注册或者注册之后没有在setFont里指定同一个名称PDF查看器在缺少字体环境时就会显示方块。解决方案是在本地渲染后用pdffonts检查pdffonts 03_源代码_完整版.pdf如果输出里有no embed字样说明字体没有正确嵌入。换用NotoSansMonoCJK或者将字体文件放在项目目录内显式注册通常都能解决。7.2 源代码里含有效邮箱导致PDF被判定为疑似个人信息泄露有些代码里会写开发者邮箱做联系方式。软著材料里的源代码是会被存档和抽查的不必要的个人信息应该全部剔除。我自己的模板里把邮箱正则加了进去EMAIL_PATTERN r[a-zA-Z0-9._%-][a-zA-Z0-9.-]\.[a-zA-Z]{2,}替换为[EMAIL REDACTED]。需要注意的是如果代码里用了SMTP配置替换后要保证上下文仍然可读最好同时替换为类似your_emailexample.com的占位演示值而不是一串星号。7.3 从Git仓库读取时把二进制文件也拉进来了如果后缀过滤不严格像图片、模型权重、SQLite数据库文件可能会被当成源码读进来导致PDF里有大量乱码甚至直接报错。必须在读取前检查is_binarydef is_binary(filepath): with open(filepath, rb) as f: chunk f.read(1024) return b\x00 in chunk这是最稳的二进制判定方式比单纯看后缀更可靠。7.4 页眉里软件名称过长折行导致页面错乱软著要求页眉写全称但有些全称真的特别长比如“基于大数据和人工智能的某某综合管理系统V2.0”。当页眉文本超过行宽drawString不会自动换行而是截断或溢出。我的解决方法是设置自动缩放逻辑如果页眉字符串超过多少像素就逐渐缩小字号而不是换行。到了极限还没放下就使用缩写版本并在文档说明中标注全称。7.5 新规后提交系统一直提示“AI生成内容声明未填写”这是我在测试时踩过的真实问题。2026年3月15日后的新填报系统里在“创作说明”部分加入了AI工具使用情况的自愿声明。但很多代理平台会把“未填写”视为“未完成”。规避方式是在Skill里生成一份内容明确的software_ai_declaration.md即便是声明“本项目未使用AI生成代码全部由人工编写”也要有书面说明以便随时上传解释。8. 最终经验与技巧关于“写软著”的几条个人心得第一不要把软著材料当成纯文档处理任务来做。它本质上是一个信息组织与合规审查任务。早一点把“源程序清洗”、“说明说撰写”、“AI声明”打包到一个流程里后面就能节省大量返工时间。我自己第一次手动交材料时因为格式小问题被补正过两次每一次来回路程加上修改都是半天。第二Skill的设计不要追求一步到位。最初我做第一版只聚焦在“源代码生成PDF”这一件事上。跑通之后才陆续加入说明书生成、敏感信息脱敏、AI声明这些模块。如果一开始就规划一个巨大的“软著全自动机器人”很可能几个月都完不成。从最小可用的闭环开始再迭代。第三生成文档这件事永远保留人工复核的责任。Skill可以帮你把页面排得整整齐齐但它不能在手机上替你看一眼PDF是否多了个奇怪的空白页也不能判断某个模块的描述是否会让审核员产生误解。我现在的习惯是任何由Skill生成的文件在提交前必须由我本人过目一遍重点看页数、页眉、敏感信息和说明书的开头段落。最后分享一个小技巧。我发现在生成的PDF元信息里把“作者”字段设置为空而不是默认的Python脚本名称会让材料的专业度提升不少。很多工具生成的PDF默认作者是reportlab或Python虽说不影响申请但万一碰上较真的审核员多少会留下“机器生成”的印象。清空作者字段再从文档内排版上做到与手工排版本无差异这个细节值得做。写软著本来就不该是个辛苦活把重复的交给流程把判断的留给自己效率和质量就都有了。
返回列表