AI项目结构图一键生成文件夹与空文件:树形解析脚本实践

发布时间:2026/10/29 13:51:46

AI项目结构图一键生成文件夹与空文件:树形解析脚本实践 上周在整理一个演示项目的骨架AI 三秒钟甩给我一张结构图二十多个目录、六十多个文件层级最深的地方套了四层。我盯着那张图看了半天最后还是老实地一个目录一个目录地建建到第四层的时候就开始烦了——这种活纯粹是体力支出没有任何智力含量但错了又不行漏一个目录后面 import 全崩。“从AI给的项目结构图快速生成项目文件夹及文件”这件事就是在这种场景下被逼出来的需求把 AI 输出的那段字符画一键变成磁盘上真实存在的目录和空文件让脚手架从“复制粘贴”升级到“落地执行”。这件事听起来像个小脚本但真写起来坑比想象的多树形字符是 Unicode、缩进风格每家大模型都不一样、目录和文件的判定规则模糊、名字里带空格、Windows 和 macOS 的非法字符不一样。这篇把我从零把这件事做成的全过程拆开讲包括解析器的设计、三套不同语言的实现、以及那些只有真跑过才会遇到的边界问题。不管你是刚接手一个空仓库不知道从哪下手还是想给自己的自动化流程补一块拼图下面的内容都能直接抄。 ## 1. 先把这件事的边界划清楚 ### 1.1 手工建目录到底浪费了什么 很多人第一反应是“建几个文件夹能有多费劲”。我实测过一个中等规模的前端或服务端项目骨架通常包含 15 到 40 个目录、30 到 100 个文件层级 3 到 5 层。用 IDE 右键新建平均一个目录 4 秒、一个文件 6 秒还要输入文件名、确认后缀加上中途的思考停顿和偶尔建错位置重来整件事轻松吃掉 15 到 20 分钟。关键不在于这 20 分钟本身而在于它打断了你的“上下文”——你本来在脑子里构想模块划分结果被迫切换到鼠标操作等你建完最初的架构直觉已经散了。 更隐蔽的成本是一致性。手建的目录名容易前后不统一比如一会儿utils、一会儿utilities一会儿components放在src下、一会儿又放到根目录。这种不一致在当时看不出问题等到三周后要写构建配置、要按目录做代码分割才发现路径要一个个改。用脚本从一份结构图生成本质上是在做“基础设施即代码”的同一件事结构图是声明脚本是执行两者一一对应可版本管理、可 review、可重放。这也是我坚持把结构图存成文件而不是直接贴进终端的核心原因。 ### 1.2 AI 吐出来的“结构图”其实有三种形态 这一节非常关键因为解析器的复杂度几乎完全由输入形态决定。我统计了自己过去几个月收集的样本AI 输出的结构图基本落在三类里。第一类是标准 UTF-8 树形字符也就是tree命令那种带├──、└──、│的画法这类最漂亮也最常见。第二类是 ASCII 退化版用|--、--、|拼出来多出现在要求“纯 ASCII 输出”的场景或者在老旧终端里被自动降级。第三类干脆不是树而是纯缩进列表或者纯路径清单一行一个用两个或四个空格表示层级。project/ ├── src/ │ ├── main.py │ └── utils/ │ └── helper.py ├── tests/ │ └── test_main.py └── README.md上面这段就是第一类。如果我把同一棵树改写成第三种形态它会变成这样project/ src/ main.py utils/ helper.py tests/ test_main.py README.md两种写法表达的是同一件事但解析逻辑完全不同前者靠符号判断层级后者靠缩进宽度判断层级。更麻烦的是同一个模型在不同对话里可能混用——我遇到过上面几行是树字符、底下几行突然变成纯缩进的输出。所以解析器必须能同时处理两种情况而不能赌一种格式。这也是后面我要用“前缀宽度除以缩进单位”这个算法的原因它对两种形态天然通用。 ### 1.3 三个必须提前拍板的决策 动手写代码之前有三件事如果不先想清楚写到一半一定会推翻重来。第一件是根节点的语义结构图的第一行通常是project/它到底是“我要在当前目录下新建一个叫 project 的文件夹”还是“当前目录就是 project从它的子项开始建”这个决定影响整个脚本的路径基准我最后做成了命令行参数--root默认把第一行当作根目录名同时提供--no-root跳过它。 第二件是已存在文件怎么处理。三种策略跳过默认、覆盖、报错退出。我的选择是“文件跳过、目录合并”因为绝大多数使用场景是在已有仓库里补结构覆盖会毁掉已有代码这个风险不值得冒。第三件是目录和文件怎么区分。最可靠的信号是名字以/结尾这在树形输出里几乎是约定俗成但 AI 有时会漏掉斜杠这时就看它有没有子节点——有子节点必然是目录。这两个规则叠加准确率能到 99% 以上剩下的靠人工扫一眼。 提示这三个决策不要等到写完脚本再补先把它们做成命令行开关后面调试的时候你会感谢自己。 ## 2. 解析器的核心把画出来的树读成数据 ### 2.1 一套能吃掉所有缩进风格的前缀识别法 我最初的想法是按符号逐个解析遇到│算一层、遇到├算一层、遇到空格按四个一组算一层。写出来之后立刻翻车因为 ASCII 树的|-- src里|和--各被算了一次深度直接翻倍。后来又改成“先把所有连接符统一替换成同一套字符再解析”结果my-app这种带连字符的文件名被误伤-被当成连接符吃掉了一半。 折腾两轮之后我意识到最稳的办法不是“数符号”而是“量宽度”。观察一下标准树形输出的结构每个层级固定占 4 个字符宽度├──是 4 个字符├、─、─、空格│也是 4 个字符│加三个空格 四空格还是 4 个字符。这意味着行首到文件名的字符数量除以 4就是深度。ASCII 版本同理|--是 4 个字符|是 4 个字符。python PREFIX_CHARS set( │|├└┌─-—–) def split_line(raw): raw raw.rstrip() i 0 while i len(raw) and raw[i] in PREFIX_CHARS: i 1 return raw[:i], raw[i:]这段代码只做一件事从行首开始把所有属于“树装饰字符”的字符一路吃掉剩下的就是名字。len(prefix) // unit就是深度。它同时兼容 UTF-8 树、ASCII 树、纯空格缩进三种形态因为在这三种形态里装饰字符都只出现在名字之前。唯一需要小心的是文件名本身以-或开头的情况这种名字极其罕见我在脚本里直接加了一条“不安全名字跳过并告警”的兜底。 ### 2.2 缩进单位怎么自动探测 上一节说“除以 4”但 4 不是常量。有的模型用 2 空格缩进有的用 3 空格我甚至见过用 Tab 的——Tab 被渲染成几个空格取决于终端设置这是最恶心的一种。硬编码 4 会让 2 空格缩进的结构图全部塌成一层所有文件挤在根目录下。 解决办法是先把所有行的“前缀长度”收集起来求最大公约数。比如前缀长度集合是{0, 2, 2, 4, 6}gcd 是 2说明单位是 2如果是{0, 4, 8, 12}gcd 是 4。这里有个陷阱如果所有非零前缀恰好都是 8 的倍数比如整张图最浅的节点就在第 2 层gcd 会算出 8深度全部除以 8 就只剩 1 层了。所以我加了一条钳制结果必须落在 1 到 4 之间超出就退回 4。python def detect_unit(lines): spans [] for line in lines: m re.match(r^( )\S, line) if m: spans.append(len(m.group(1))) if not spans: return 4 unit reduce(gcd, spans) return unit if 1 unit 4 else 4这个函数只在前缀全是空格时生效含树字符的行前缀长度本身就是 4 的倍数gcd 自然得 4两种情况殊途同归。实测下来这套探测在几十份样本里只有一份判错出错那份是因为 AI 在树外面额外加了两行带三个空格缩进的说明文字被算进了 gcd。所以我后来把“过滤噪声行”放在了探测之前顺序不能反。 ### 2.3 目录、文件、注释与噪声行的判定 噪声行是解析器最大的敌人。AI 输出结构图时习惯性地在外面包一层三反引号的代码围栏有时候还会在前后加一句“以上是项目结构”。这些行如果混进去会生成名为​ 的目录或者叫“以上是项目结构”的文件。我的过滤规则是跳过空行、跳过以三个反引号开头的行、跳过以#或//开头的纯注释行、跳过包含空格且以中文标点结尾的说明行。 目录判定走两级先看名字是否以/或 结尾是则判定为目录并去掉尾部斜杠否则看它在整棵树里有没有下一层节点即下一行的深度是否大于当前行有则晋升为目录。第二级判定是为了兜住 AI 忘记加斜杠的情况实测能救回大概两成的漏标。文件名里的合法字符还要做一次校验:|?*这些在主流桌面系统上非法出现就跳过该行并在终端打出警告避免生成一堆打不开的僵尸文件。python def classify(nodes): result [] for idx, (depth, name) in enumerate(nodes): is_dir name.endswith(/) or name.endswith(\\) clean name.rstrip(/\\).strip() if not is_dir and idx 1 len(nodes) and nodes[idx 1][0] depth: is_dir True result.append((depth, clean, is_dir)) return result这段逻辑很短但价值很高。它把“AI 有没有老实写斜杠”这件事从“必须满足”降级成了“最好满足”容错空间大了很多。我个人的经验是凡是跟外部输入打交道的地方都不要假设对方会严格遵守格式宁可多写十行兜底代码也别在半夜收到“目录建不出来”的求助。 ## 3. 生成器实现Python 完整版逐段拆解 ### 3.1 完整脚本 这是我现在用的版本一百行左右无第三方依赖Python 3.8 以上直接跑。我把它命名为treegen.py平时扔在~/bin里全局可调。脚本做了这几件事读文件、过滤噪声、探测缩进单位、解析成(深度, 名字, 是否目录)三元组、按深度维护一个路径栈、逐条落地、最后打印统计。python #!/usr/bin/env python3 import argparse import re import sys from functools import reduce from math import gcd from pathlib import Path PREFIX_CHARS set( │|├└┌─-—–) NOISE_RE re.compile(r^\s*(|~~~|...$|$ )) def detect_unit(lines): spans [] for line in lines: m re.match(r^( )\S, line) if m: spans.append(len(m.group(1))) if not spans: return 4 unit reduce(gcd, spans) return unit if 1 unit 4 else 4 def parse(text, unitNone, strip_rootFalse): raw_lines [l.rstrip() for l in text.splitlines()] lines [l for l in raw_lines if l.strip() and not NOISE_RE.match(l)] if unit is None: unit detect_unit(lines) nodes [] for line in lines: i 0 while i len(line) and line[i] in PREFIX_CHARS: i 1 name line[i:].strip() if not name: continue nodes.append((len(line[:i]) // unit, name)) if strip_root and nodes: base nodes[0][0] nodes [(d - base - 1, n) for d, n in nodes[1:]] return nodes def safe(name): if name in (., ..) or not name: return False if / in name or \ in name: return False return not re.search(r[:|?\x00-\x1f], name) def load_templates(path): if not path or not Path(path).exists(): return {} import json return json.loads(Path(path).read_text(encodingutf-8)) def build(nodes, root, dry_runFalse, templatesNone): root Path(root) templates templates or {} paths {} created_dirs created_files skipped 0 for depth, name in nodes: is_dir name.endswith((/, \)) or any( d depth for d, _ in nodes[nodes.index((depth, name)) 1:][:1] ) clean name.rstrip(/\).strip() if not safe(clean): print(f[skip] 非法名称: {clean!r}, filesys.stderr) skipped 1 continue parent root if depth 0 else paths.get(depth - 1, root) target parent / clean if is_dir: if not dry_run: target.mkdir(parentsTrue, exist_okTrue) paths[depth] target created_dirs 1 else: if dry_run: print(f[file] {target}) created_files 1 continue if target.exists(): skipped 1 continue target.parent.mkdir(parentsTrue, exist_okTrue) suffix target.suffix.lstrip(.) target.write_text(templates.get(suffix, templates.get(default, )), encodingutf-8) created_files 1 return created_dirs, created_files, skipped def main(): ap argparse.ArgumentParser() ap.add_argument(tree_file) ap.add_argument(--root, default.) ap.add_argument(--strip-root, actionstore_true) ap.add_argument(--unit, typeint, defaultNone) ap.add_argument(--dry-run, actionstore_true) ap.add_argument(--templates, defaultNone) args ap.parse_args() text Path(args.tree_file).read_text(encodingutf-8) nodes parse(text, args.unit, args.strip_root) d, f, s build(nodes, args.root, args.dry_run, load_templates(args.templates)) print(f目录 {d} 个文件 {f} 个跳过 {s} 个) ifname main: main()### 3.2 关键行在做什么 上面这段代码里有几处值得单独说明因为它们是踩坑踩出来的。第一处是 paths 这个字典它记录了“第 N 层当前对应的实际路径”。解析是顺序进行的当遇到深度回退的行比如从第 3 层跳回第 1 层字典里第 2、3 层的旧值还在但下一行查的是 paths[depth - 1]也就是第 0 层所以不受影响。这个设计比维护一个显式栈更省代码而且天然容忍“跳级”这种畸形输入。 第二处是 target.parent.mkdir(parentsTrue, exist_okTrue) 这一行在创建文件之前又调了一次。看起来多余其实是必要的如果 AI 输出的树里某个目录被漏掉了只写了文件没写父目录那一行提前建父目录能保证文件不会因为父路径不存在而抛异常。parentsTrue 会递归创建所有缺失的中间目录exist_okTrue 则让重复创建不报错这两个参数组合起来就是幂等的基础。 第三处是 strip_root 的实现。注意我砍掉根节点的方式是“把所有深度减去第一行的深度再减一”而不是简单地丢掉第一行。因为有些 AI 会在树的外面再包一层名字或者第一行就是根节点本身两种情况下“减一”的语义都要一致否则子节点会全部跑到上一层去。这一小段我改了三版才稳定下来最开始的写法是直接 nodes[1:]结果深度没归零所有节点都挂到了错误的父路径下面。 注意nodes.index((depth, name)) 这种查找方式在重名节点上会出错。如果你的结构图里有两个同名的 index.ts它总是返回第一个。生产版本我换成了带下标的循环博文里为了可读性保留了这种写法你抄的时候记得改。 ### 3.3 模板与初始内容 空文件在建完之后会亮一片红IDE 的 linter 会把它们全标成警告。与其忍受这个不如在创建时就写入最小可用的初始内容。我做了个 .treegen.json 配置按后缀映射模板json { default: , py: TODO: 模块说明\n, ts: export {};\n, tsx: export {};\n, js: export {};\n, md: # TODO\n, go: package main\n, css: /TODO/\n }ts 和 tsx 的 export {}; 这一行是刻意加的——它让这个空文件变成一个 ES 模块避免 TypeScript 把它当成全局脚本也避免某些构建工具把它直接剔除。py 那个文档字符串同理有些静态检查工具会把完全没有内容的文件跳过加个 docstring 就正常了。go 的 package main 是为了让文件能被 go build 识别到否则整个目录不参与编译。 模板机制还有个大用处可以批量写入统一的版权头或者文件说明。我在某个多人协作的项目里就干过这件事给所有 py 文件预置了一个带模块名占位符的注释头脚本创建时把文件名填进去后面新人看代码时一眼就知道这个文件是几月几号为了什么加的。这个做法能不能推广见仁见智但如果你所在的团队有规范要求它确实能省掉大量重复劳动。 ## 4. 轻量场景的另外两条路Bash 与 Node ### 4.1 让 AI 直接输出路径清单Bash 十几行搞定 如果你的机器上没有 Python或者你就想要最轻的方案那答案是“别让 AI 输出树让它输出路径清单”。这是我从源头降低难度的一个思路与其费劲解析树形字符不如在提示词里就要求 AI 用一行一个相对路径、目录以斜杠结尾的格式输出。这样拿到的东西已经是机器友好的脚本可以短到十几行。bash #!/usr/bin/env bash set -euo pipefail src${1:?用法: mkdirs.sh paths.txt [root]} root${2:-.} while IFS read -r line; do line${line%$\r} [[ -z ${line// } ]] continue [[ $line #]] continue line${line#${line%%[![:space:]]*}} if [[ $line */ ]]; then mkdir -p -- $root/$line echo [dir ] $root/$line else mkdir -p -- $root/$(dirname -- $line) [[ -e $root/$line ]] || : $root/$line echo [file] $root/$line fi done $src这段代码干的事很直白读一行、去掉行尾的 \rWindows 导出的文本常有、去掉行首缩进、判断是不是目录、建目录或者建文件。-- 是必须的它告诉 mkdir 后面全是参数而不是选项否则遇到以 - 开头的名字就会报“无效选项”。[[ -e ]] || : 这个组合实现了“文件存在就跳过”比先判断再创建少一次 IO。 它的短板也很明显一旦 AI 还是给你输出了树形字符这个脚本会把 ├── src/ 整个当成名字建出一个叫 ├── src 的目录。所以我一般会配一个降级处理用 sed 先把树字符洗掉再喂给它。但 sed 处理多字节字符在不同 locale 下的行为不一致这部分我没在 Bash 里死磕直接劝人上 Python 了。 ### 4.2 Node 版前端仓库里顺手用 前端同学手里通常已经有 Node 环境不想为了建目录单独装 Python所以我写了一版 Node 实现逻辑和 Python 版一一对应。它用 node:fs 的 mkdirSync 递归模式这个 API 从 Node 10 就有了不用担心兼容。javascript #!/usr/bin/env node import fs from node:fs; import path from node:path; const [, , treeFile, rootArg .] process.argv; const root path.resolve(rootArg); const PREFIX /^[ │|├└┌─\-—–]/; const lines fs.readFileSync(treeFile, utf8) .split(/\r?\n/) .filter((l) l.trim() !/^\s*(|~~~)/.test(l)); const spans lines .map((l) (l.match(/^( )\S/) || [])[1]?.length || 0) .filter((n) n 0); const unit spans.length ? Math.min(...spans) : 4; const dict new Map(); let dirs 0, files 0; for (const line of lines) { const prefix line.match(PREFIX)?.[0] ?? ; const depth Math.floor(prefix.length / unit); const name line.slice(prefix.length).trim(); if (!name || /[:|?*]/.test(name)) continue; const isDir /[/\\]$/.test(name); const clean name.replace(/[/\\]$/, ); const parent depth 0 ? root : dict.get(depth - 1) ?? root; const target path.join(parent, clean); if (isDir) { fs.mkdirSync(target, { recursive: true }); dict.set(depth, target); dirs; } else { fs.mkdirSync(path.dirname(target), { recursive: true }); if (!fs.existsSync(target)) { fs.writeFileSync(target, , utf8); files; } } } console.log(目录 ${dirs} 个文件 ${files} 个); 这里我用Math.min(...spans)代替了 Python 版的 gcd因为大多数情况下最小缩进就等于单位够用了。如果遇到混排既有 2 空格又有 4 空格的层级min会得到 2深度算出来是对的反而比 gcd 更鲁棒。这个细节是写第二版的时候才想明白的别再追求数学上的严谨实际输入里“最小正缩进就是单位”这条经验规则命中率高得多。 ### 4.3 三种方案怎么选 我把三套实现的取舍整理成了一张表你可以按自己的环境对号入座。核心结论是**解析树形字符这件事Python 的成本最低只要路径清单Bash 最轻前端项目里 Node 最省事**。不要为了统一而强行选一种工具是拿来用的不是拿来供奉的。 | 方案 | 适用输入 | 依赖 | 跨平台 | 推荐场景 | |---|---|---|---|---| | Python 完整版 | 树形字符、缩进列表、混合 | 无标准库 | 好 | 日常主力建议全局安装 | | Bash 清单版 | 纯路径清单 | 无 | Linux/macOS | 临时救急、服务器上 | | Node 版 | 树形字符、缩进列表 | Node 10 | 好 | 前端仓库、CI 里 | 还有一点值得提醒如果你打算把这个脚本放进 CI 或者 npm scripts 里跑务必选 Python 或 Node别选 Bash。Bash 脚本对 locale、对多字节字符、对以-开头的文件名都有微妙的依赖在本地跑得好好的换个镜像环境就翻车。这种问题排查起来极其费时不如一开始就用有明确字符语义的运行时。 ## 5. 让它能在真实项目里跑幂等、安全与跨平台 ### 5.1 dry-run 与幂等 第一次跑脚本之前一定要先 dry-run。我见过太多人直接把 AI 给的结构图往一个已有仓库里一贴跑完发现所有路径都多套了一层project/整个仓库变成了project/project/src。加个--dry-run开关把所有“将要执行的动作”打印出来你肉眼扫一遍确认无误再真跑成本不到十秒能省掉一次git clean -fd的心惊肉跳。 幂等是另一条底线。所谓幂等就是同一个脚本连续跑十次结果和跑一次一样。实现上就靠两个东西目录用mkdir -p或者exist_okTrue文件先判存在再写。我在生成器里对文件是“存在即跳过”绝不覆盖。这个策略的代价是没法通过重跑脚本来更新已有文件内容但那个需求本来就不该由建目录脚本来承担——那属于模板引擎或者脚手架工具的范畴混在一起只会让职责变模糊。 bash # 建议的实操顺序 python3 treegen.py tree.txt --root ./my-app --dry-run python3 treegen.py tree.txt --root ./my-app git status --short 第三步git status是我强烈建议加进流程的。它会如实告诉你哪些文件是新增的、哪些目录被合并了。如果输出的列表比你预期的多出一大截多半是解析时把噪声行当成节点了这时候回头检查tree.txt的前几行和最后几行问题通常就藏在那里。 ### 5.2 路径安全校验 如果你的结构图是从外部来的AI 生成、别人发的、从文档里复制的那它就是一个不可信输入必须校验。最典型的攻击或事故是..路径穿越结构图里写一行└── ../../../etc/xxx脚本老老实实建到系统目录里去了。我的校验规则是三条名字不能是.或..名字里不能含/或路径分隔符只能在解析阶段被识别为目录标记不能出现在名字中间名字不能含控制字符和:|?*这些在各平台上有特殊含义的符号。python def safe(name): if name in (., ..) or not name: return False if / in name or \\ in name: return False return not re.search(r[:|?*\x00-\x1f], name)第二条规则在 Linux 上看起来过于严格——Linux 文件名里允许:和|删掉它们反而是过度限制。但考虑到脚本大概率会在多人之间流转、在 Windows 和 macOS 上都跑统一禁掉是最省心的做法。真遇到必须带:的名字我的处理是建完之后手动改名并在 README 里留一行说明比在脚本里做平台分支要清爽。 ### 5.3 编码、换行、长路径 编码这事看着基础翻车的人不少。AI 输出的结构图里经常带中文目录名比如├── 组件/如果文件保存成了 GBK 而脚本按 UTF-8 读解析出来的全是乱码建出来的目录名打不开也删不掉非常难受。我的做法是脚本里硬编码encodingutf-8并且在读文件之前先检查有没有 BOM 头有就剥掉。Windows 上用记事本保存的文本默认带 BOM这个坑我踩过不止一次。 换行符是另一个隐形炸弹。Windows 的\r\n会在行尾多留一个\r这个字符肉眼看不见但会让文件名末尾多一个控制字符ls输出的时候看不出来等你import的时候就是找不到模块。Python 的splitlines()会自动处理多种换行符Bash 方案里我手动加了${line%$\r}做剥离Node 里用的是split(/\r?\n/)三条路都堵上了。 长路径的问题主要出现在 Windows路径总长度超过 260 字符会报错而深层的node_modules或者嵌套的组件目录很容易超。我的应对是在生成前算一下预估路径长度超过 240 字符就打警告让你自己决定要不要简化目录层级。这个 warning 不是阻止执行只是提醒因为很多时候你确实需要那么深的目录只是不知道自己离红线有多近。 ## 6. 踩坑实录与速查表 ### 6.1 高频故障速查 下面这张表是我把自己和身边人遇到的问题汇总之后的版本基本覆盖了九成以上的情况。遇到问题的第一反应应该是查表而不是打开调试器。 | 现象 | 大概率原因 | 处理方式 | |---|---|---| | 所有文件都堆在根目录 | 缩进单位探测失败 | 手动加--unit 4或--unit 2| | 生成了一堆叫├──的目录 | 前缀字符集没覆盖到 | 检查是否有特殊的制表符号 | | 目录层级多了一层 | 根节点被重复计算 | 加--strip-root| | 文件名末尾有奇怪字符 | 行尾\r没剥离 | 统一按 UTF-8 splitlines 处理 | | 中文目录名乱码 | 文件编码不是 UTF-8 | 转码后再跑或剥 BOM | | 文件建出来了但内容是空的 | 模板配置没生效 | 检查.treegen.json路径和后缀名 | | 已有代码被覆盖 | 用了覆盖策略 | 改成“存在即跳过” | | 报错“路径过长” | Windows 260 限制 | 简化层级或缩短目录名 | | 建出了和预期不符的名字 | AI 在行尾加了注释 | 在提示词里禁止行尾注释 | 表格里最后一条特别值得展开。AI 非常喜欢在结构图的每一行后面加注释比如├── main.py # 程序入口。如果你的解析器不处理这个建出来的文件名就是main.py # 程序入口虽然能建出来但根本没法用。我的处理是在解析阶段做一次“行尾注释剥离”如果名字里出现两个以上连续空格后跟#或//就把那部分砍掉。这个规则有误伤风险文件名里真的有两个空格但概率极低值得换。 ### 6.2 几条用血换来的心得 第一条心得是在提示词里就把格式约束好这比在解析器里做一百行兜底都划算。我现在固定用这样一段话要求 AI“请用树形结构输出项目结构目录以斜杠结尾不要输出代码围栏不要在行尾加注释不要输出除结构图以外的任何文字。”加上这句之后需要兜底的情况少了八成脚本也从两百行瘦到了一百行。这是典型的“往上游走一步下游省十倍力”。 第二条心得是把结构图文件纳入版本管理。这听起来有点反直觉结构图不是一次性的吗但实际项目里结构会演进你把每次生成的结构图存成docs/structure-v1.txt、structure-v2.txt未来想对比两次重构之间目录变化直接diff就行比翻 git log 看谁删了哪个文件夹直观得多。我现在接手陌生项目第一步就是把当前目录树 dump 一份存下来作为后续重构的基线。 第三条心得是不要试图让脚本处理一切。有人问我能不能让脚本自动判断“这个文件该不该存在”“这个目录名是不是拼错了”我的回答是不能也不该。脚本的职责边界很清楚把结构图如实映射到
延伸阅读

更多相关文章

2026/10/29 13:51:46

营销技能实战拆解:从用户洞察到渠道运营的系统能力

这几年聊到营销,经常让人产生一种错觉:好像谁都能干。拍两条视频、投几组信息流、写几个小红书种草贴,就敢说自己懂营销。但一线做久了你会发现,真正拉开差距的从来不单是某一个技巧,而是你身上那套叫“营销技能”的系…

2026/10/29 13:51:46

Linux系统编程:文件I/O、进程管理与信号处理实战

1. Linux环境编程第五天学习笔记:从系统调用到底层实现 作为一名在Linux环境下摸爬滚打多年的开发者,我清楚地记得初学系统编程时那种既兴奋又困惑的状态。今天这份笔记将记录第五天的关键学习内容——这个阶段正是从基础命令过渡到真正理解Linux系统运作…

2026/10/29 13:51:46

hyperframes:ROS 2 多传感器时间同步与融合实战指南

1. 从传感器数据流说起:为什么需要 hyperframes做机器人或者自动驾驶相关开发的朋友,应该都有过这样的经历:车上装了激光雷达、相机、IMU,每个传感器都有自己的发布频率和延迟,到了融合那一步,数据对不上&a…

2026/10/29 14:52:08

OpenClaw超时异常解析与实战调优指南

1. OpenClaw超时异常解析与实战调优遇到"increase agents.defaults.timeoutSeconds in your config"报错时,本质是OpenClaw的Agent执行超过了默认超时阈值。这个看似简单的配置项背后,涉及分布式任务调度、长时操作处理等深层设计逻辑。作为深…

2026/10/29 14:52:08

Unix/Linux基础学习地图:三层结构、FHS目录与权限命令

简介:《Unix/Linux基础讲义.doc》面向操作系统初学者、计算机专业学生及需补齐 Unix/Linux 基础的开发者,帮助建立从操作系统定位到 Unix、Linux 演进脉络的系统认知。讲义围绕操作系统承上启下的作用展开,梳理 Unix 家族从 MULTICS、UNICS 到…

2026/10/29 14:52:08

Unix/Linux入门:目录结构、路径与文件权限解析

简介:《Unix/Linux基础讲义》以单份 doc 文档形式呈现,定位为操作系统入门的课堂讲义式材料,适合刚接触命令行与服务器环境的初学者,也适合需要补齐概念的备考或转行读者。内容从操作系统“方便、有效、扩展”三项目标讲起&#x…

2026/10/29 14:52:08

分布外泛化OOD综述:方法地图与PACS评测复现避坑

简介:清华大学崔鹏等学者撰写的《分布外泛化综述》PDF,面向深度学习研究者、研究生与算法工程师,系统回应训练与测试分布不一致时模型性能骤降的问题。全文从OOD泛化的形式化定义出发,按学习流程将方法归为无监督表示学习、监督模…

2026/10/29 14:52:08

浏览器打印功能的隐藏价值与实用技巧

1. 为什么浏览器打印功能被严重低估了大多数人只在需要纸质文档时才会点击浏览器的打印按钮,但这项基础功能实际上隐藏着惊人的生产力潜力。我曾在一次项目汇报前发现会议室投影仪故障,紧急情况下用浏览器打印功能将网页转为PDF,不仅保留了完…

2026/10/29 14:47:06

在线表格编辑实战:Excel导入导出、公式计算与数据落库

简介:面向需要在网页端查看、编辑并保存 Excel 数据的前端开发者与企业应用团队,这份示例包围绕 HTML 页面集成在线表格编辑能力展开,涉及表格控件初始化、单元格交互、样式主题切换以及浏览器兼容性处理。压缩包共 41 个文件,约 …

2026/10/28 14:42:12

全国计算机二级C语言真题PDF高效刷题指南

简介:这份PDF是全国计算机二级C语言考试的试题与答案解析,专为备考二级C语言的考生准备。内容涵盖C语言特点与设计理念、程序基本组成单位、main函数执行流程、函数嵌套调用规则、标识符命名规范、整型实型字符型数据类型、八进制十六进制数合法形式、运…

2026/10/28 15:28:56

requests+BeautifulSoup:爬虫抓取h1标题的入门实战指南

简介:一份以实战为导向的Python爬虫入门资源,面向具备基本编程基础、希望快速掌握网络数据抓取的初学者,可解决从零编写简单爬虫的常见困惑。实例以requests库发送HTTP请求、BeautifulSoup解析HTML文档,完整演示从网页中提取 标题…

2026/10/28 3:32:29

递推最小二乘参数辨识MATLAB编程:二阶系统与渐消记忆实现

简介:这是一篇面向控制系统、信号处理与机器学习等领域学习者的最小二乘参数辨识程序说明文档。资源共包含一个docx格式文档,压缩包大小七十八KB,内容围绕递推最小二乘算法和渐消记忆最小二乘算法展开:先构造一个极点位于单位圆内…

2026/10/29 0:03:42

学生选课系统DFD图绘制指南:边界划分与分层校验实战

简介:文档以顶层与第一层DFD图为核心,完整刻画学生选课系统的逻辑模型,面向软件工程课程设计、系统分析学习及毕设前期建模人群。顶层图界定系统边界,外部实体包括管理员、教师和学生三类角色;第一层图进一步细化用户登…

2026/10/29 0:03:42

JIRA敏捷落地:Scrum角色权限、Sprint与燃尽图避坑指南

简介:围绕“基于JIRA的敏捷开发项目管理”这一主题,面向产品负责人、Scrum Master及研发测试成员,梳理Scrum角色分工、迭代流程与JIRA工具配置的对应关系,适合初、中级团队导入敏捷管理时参考。压缩包共1个docx文件,大…

2026/10/29 0:03:42

SEMI S8人机工程验收实战:从条款拆解到现场实测的完整指南

简介:面向半导体设备设计、制造与运维工程师及安全合规人员,这份资料聚焦SEMI标准体系下的设备安全规范,重点收录SEMI S8-0308《半导体制造设备人体工程学工程安全指南》。内容围绕设备设计原则、错误与事故预防、人体工程学适配三大主线展开…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑