别再手动复制代码了!用 Rust 写个 CLI 把整个项目一锅端给 AI
1. 为什么我要自己写一个 Code2Prompt 风格的 CLI你有没有过这种体验想让 Claude Code 或 Codex 帮忙改一段登录逻辑结果它先find . -type f列一遍文件再grep -rn login搜一遍关键词然后对候选文件逐个 Read最后才拼出一个它自认为理解的项目视图。整个过程又慢又费 token而且它读到的往往是路径拼接、文件头注释、空行、配置文件这些对当前任务几乎没用的内容。Code2Prompt 这个思路就是来解决这个问题的一条命令把整个项目变成一张结构化的 LLM prompt。它用 Rust 写GitHub 上已经有 7.5k star。核心能力是把源码目录树、文件内容、Git 元数据、token 计数打包成一段 LLM 能直接理解的项目快照。但直接用现成工具有时候不够灵活——你可能想自定义忽略规则、想控制输出格式、想把它嵌进自己的脚本里。所以这篇我带你从零用 Rust 写一个 Code2Prompt 风格的 CLI把目录遍历、忽略规则、prompt 拼装这几件事讲透。适合有 Rust 基础、想把上下文工程自动化的人。我试过让 Agent 自己翻项目一个 Next.js 仓库能扫出几万个文件真正相关的可能就几十个。与其让 Agent 用 find grep 拼一个残缺视图不如我们主动生成一份结构完整的 prompt 喂给它。2. 前置准备Rust 环境与 TaoToken 接入写这个 CLI 之前先把两件事准备好Rust 工具链以及一个能调用的 LLM 接口。CLI 负责生成 promptTaoToken 负责把 prompt 投喂给模型验证效果。2.1 Rust 工具链如果你还没装 Rust用 rustup 一行搞定curl --proto https --tlsv1.2 -sSf https://sh.rustup.rs | sh source $HOME/.cargo/env rustc --version cargo --version确认版本在 1.75 以上因为后面会用到一些较新的标准库特性。2.2 为什么用 TaoToken 做验证端生成的 prompt 总得有个地方投喂。TaoToken 提供统一的 API 入口兼容 OpenAI 风格的接口你拿一个 Key 就能调多种模型。对于这个 CLI 的验证场景来说好处是prompt 生成完直接curl一下就能看到模型对项目结构的理解不用来回切平台。官网入口在 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 基址是 https://taotoken.net/api 这个不加 UTM。你需要先去控制台拿一个 API Key后面验证请求会用到。2.3 项目初始化新建一个 Rust 二进制项目cargo new code2prompt-rs cd code2prompt-rs编辑Cargo.toml把依赖配好。这里用ignore处理 .gitignore 规则ripgrep 同款库性能好walkdir做目录遍历兜底clap解析命令行参数anyhow做错误处理[package] name code2prompt-rs version 0.1.0 edition 2021 [dependencies] clap { version 4.5, features [derive] } ignore 0.4 walkdir 2.5 anyhow 1.0ignore这个 crate 是关键它直接复用 .gitignore 的匹配语义还能自动跳过.git目录和二进制文件省得我们自己写一堆过滤逻辑。2.4 拿 Key 与配置环境变量去 TaoToken 控制台的 API Keys 页面创建一个 Key然后写进环境变量别硬编码进代码export TAOTOKEN_API_KEYsk-你的key如果你用的是 Claude Code 这类工具配置里需要写全三件套——Base URL、Key、Model ID缺一不可{ base_url: https://taotoken.net/api, api_key: sk-你的key, model: claude-sonnet-4-20250514 }这个 JSON 片段后面在验证环节会直接用到。注意 Base URL 用https://taotoken.net/api不要带 UTM 参数那是给网页链接用的。3. 可复制配置目录遍历与忽略规则实现这一节是核心。我们把 CLI 拆成三块参数解析、目录遍历、prompt 拼装。每一块都给完整可复制的代码。3.1 命令行参数定义用 clap 的 derive 模式定义参数。我们要支持指定项目路径、输出文件、最大文件大小限制、是否包含 Git 信息。use clap::Parser; use std::path::PathBuf; #[derive(Parser, Debug)] #[command(name c2p, version, about 把项目打包成 LLM prompt)] struct Args { /// 项目根目录 #[arg(default_value .)] path: PathBuf, /// 输出文件不填则打印到 stdout #[arg(short, long)] output: OptionPathBuf, /// 单文件最大字节数超过则跳过 #[arg(long, default_value_t 100_000)] max_size: u64, /// 是否包含 Git 元数据 #[arg(long, default_value_t false)] git: bool, }max_size默认 100KB防止某个巨大的 lock 文件或压缩包把 prompt 撑爆。3.2 用 ignore crate 做目录遍历这是整个工具的灵魂。ignore::WalkBuilder会自动读取 .gitignore、.ignore还能配置是否跳过隐藏文件use ignore::WalkBuilder; use std::fs; fn collect_files(root: std::path::Path, max_size: u64) - anyhow::ResultVec(String, String) { let mut files Vec::new(); let walker WalkBuilder::new(root) .hidden(true) // 跳过隐藏文件 .git_ignore(true) // 遵循 .gitignore .git_global(true) // 遵循全局 gitignore .git_exclude(true) // 遵循 .git/info/exclude .build(); for result in walker { let entry result?; if !entry.file_type().map_or(false, |ft| ft.is_file()) { continue; } let metadata entry.metadata()?; if metadata.len() max_size { continue; } let path entry.path(); let rel path.strip_prefix(root)?.to_string_lossy().to_string(); // 只处理文本文件二进制直接跳过 let content match fs::read_to_string(path) { Ok(c) c, Err(_) continue, }; files.push((rel, content)); } files.sort_by(|a, b| a.0.cmp(b.0)); Ok(files) }几个细节值得说hidden(true)会跳过.git、.env这类隐藏项read_to_string失败说明是二进制文件直接continue跳过最后按路径排序保证每次生成的 prompt 顺序一致方便 diff。3.3 生成目录树LLM 需要空间信息才能理解模块关系。我们用一个简单的缩进树来表示use std::collections::BTreeMap; fn build_tree(paths: [String]) - String { let mut tree: BTreeMapString, VecString BTreeMap::new(); for p in paths { let parts: Vecstr p.split(/).collect(); if parts.len() 1 { let dir parts[..parts.len() - 1].join(/); tree.entry(dir).or_default().push(parts[parts.len() - 1].to_string()); } else { tree.entry(..to_string()).or_default().push(p.clone()); } } let mut out String::new(); for (dir, files) in tree { out.push_str(format!({}/\n, dir)); for f in files { out.push_str(format!( {}\n, f)); } } out }3.4 拼装最终 prompt把目录树、文件内容、可选的 Git 信息拼成一段结构化文本fn build_prompt(root: std::path::Path, files: [(String, String)], git: bool) - String { let paths: VecString files.iter().map(|(p, _)| p.clone()).collect(); let tree build_tree(paths); let mut prompt String::new(); prompt.push_str(# 项目快照\n\n); prompt.push_str(format!(根目录: {}\n\n, root.display())); prompt.push_str(## 目录结构\n\n\n); prompt.push_str(tree); prompt.push_str(\n\n); if git { if let Ok(branch) std::process::Command::new(git) .args([rev-parse, --abbrev-ref, HEAD]) .current_dir(root) .output() { prompt.push_str(format!(当前分支: {}\n\n, String::from_utf8_lossy(branch.stdout).trim())); } } prompt.push_str(## 文件内容\n\n); for (path, content) in files { prompt.push_str(format!(### {}\n\n\n{}\n\n\n, path, content)); } prompt }3.5 main 函数串起来fn main() - anyhow::Result() { let args Args::parse(); let root args.path.canonicalize()?; let files collect_files(root, args.max_size)?; let prompt build_prompt(root, files, args.git); let token_estimate prompt.len() / 4; eprintln!(文件数: {}, 预估 token: {}, files.len(), token_estimate); match args.output { Some(p) std::fs::write(p, prompt)?, None println!({}, prompt), } Ok(()) }prompt.len() / 4是个粗略的 token 估算英文代码大致 4 字符 1 token够用了。4. 验证请求一条命令生成 prompt 并投喂给 AI代码写完编译并跑起来cargo build --release ./target/release/c2p . --output prompt.md --git你会看到 stderr 打印出文件数和预估 token同时prompt.md里是完整的项目快照。打开看一眼目录树在最上面每个文件内容用代码块包着结构清晰。4.1 用 curl 投喂给模型拿到 prompt 后直接调 TaoToken 的接口验证模型能不能理解项目结构PROMPT$(cat prompt.md) curl https://taotoken.net/api/v1/chat/completions \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -H Content-Type: application/json \ -d $(jq -n --arg p $PROMPT { model: claude-sonnet-4-20250514, messages: [ {role: user, content: (这是一个 Rust CLI 项目请分析它的模块划分和主要职责\n\n $p)} ] })这里用jq -n --arg是为了安全地把大段 prompt 塞进 JSON避免转义问题。4.2 期望的成功结果模型返回的内容应该能准确说出项目有几个模块、collect_files负责遍历、build_prompt负责拼装、依赖了ignore和clap。如果它能复述出目录树里的文件名说明空间信息传递到位了。对比一下如果你只把main.rs单独贴给模型它看不到Cargo.toml就不知道依赖了什么看不到目录结构就不知道模块怎么组织。这就是结构化 prompt 的价值。4.3 用 MCP 模式让 Agent 自主调用如果你想让 Claude Code 或 Cursor 直接调用这个工具可以把它包成 MCP 服务器。核心思路是暴露一个get_project_context工具Agent 传路径进来你返回 prompt。这样 Agent 就不用自己 find grep 了直接拿到结构化上下文。配置 MCP 时同样要写全三件套{ mcpServers: { code2prompt: { command: ./target/release/c2p, args: [--output, -], env: { TAOTOKEN_API_KEY: sk-你的key } } } }Base URL、Key、Model ID 这三样在 Agent 侧配置里缺一不可否则调用会失败。5. 本篇常见错误排查写完跑起来大概率会踩几个坑。这里列几个真实报错和对应解法。5.1 401 Unauthorized{error:{message:Invalid API key,type:invalid_request_error}}原因通常是环境变量没生效或者 Key 复制时带了空格。检查echo $TAOTOKEN_API_KEY | head -c 10确认前缀是sk-且没有换行。如果用的是 Claude Code 配置检查 JSON 里api_key字段有没有写错。5.2 local proxy failed / connection refusederror sending request: error trying to connect: tcp connect error这个一般是 Base URL 写错了。确认是https://taotoken.net/api不要漏掉/api也不要带 UTM 参数。如果你在配置文件里写了https://taotoken.net/api/v1而代码里又拼了一次/v1就会变成/api/v1/v1同样报错。5.3 reading choices: unexpected end of JSON inputfailed to parse response: reading choices: unexpected end of JSON input这个报错说明返回体不是合法 JSON常见原因是 prompt 太大导致请求被截断或者jq拼 JSON 时转义失败。解法先用小项目测试确认链路通了再上大仓库用jq -n --arg而不是字符串拼接。5.4 OAuth / 认证方式不匹配OAuth authentication is not supported for this endpoint如果你在 Claude Code 里配了 OAuth 登录又同时想用 API Key会冲突。统一用 API Key 方式把 OAuth 相关配置清掉。5.5 生成的 prompt 里混进了 node_modules如果发现目录树里全是依赖包说明 .gitignore 没生效。检查项目根目录有没有.gitignore或者用--max-size限制单文件大小。ignorecrate 只在有 .gitignore 时才按规则过滤没有的话它只跳过隐藏文件。5.6 中文文件名乱码to_string_lossy()在极端情况下会替换非法字符。如果你的项目有中文路径建议在Cargo.toml里确认 edition 是 2021标准库对 UTF-8 处理已经够用。真遇到乱码检查终端 locale 设置。6. 把上下文工程变成你的日常习惯写到这里这个 CLI 已经能跑通完整链路了遍历项目、应用忽略规则、生成结构化 prompt、投喂给模型验证。你可以把它加到 shell alias 里alias c2p~/code2prompt-rs/target/release/c2p以后在任意项目目录下c2p . --output /tmp/prompt.md就能拿到一份项目快照。几个实用技巧给不同任务准备不同的忽略规则比如做代码审查时排除测试文件做架构分析时只保留入口文件把生成的 prompt 存成带时间戳的文件方便对比不同版本的项目结构token 估算超过模型窗口时用--max-size调小阈值或者先按目录分批生成。如果你想让 Agent 长期自主调用这个能力建议走 Coding Plan 那条路把 MCP 服务器配好让 Agent 自己决定什么时候拉取项目上下文。需要 Key 的话去 API Keys 页面创建接入细节看接入文档。验证模型对 prompt 的理解效果可以直接在模型对话里贴一段试试。上下文工程的核心不是把整个项目扔进去而是选对文件、用对格式、带上空间信息。这个 CLI 只是起点真正的功夫在于你对自己项目的理解——知道哪些文件对当前任务重要比任何工具都关键。

相关新闻

【OpenClaw】安装 + 配置 + API(Kimi + DeepSeek) + 启动 + 更新 + 卸载 + Skills + 飞书:把 settings 改到 TaoToken

【OpenClaw】安装 + 配置 + API(Kimi + DeepSeek) + 启动 + 更新 + 卸载 + Skills + 飞书:把 settings 改到 TaoToken

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 15:57:25 阅读更多 →
AI Coding IDE 入门指南:用 TaoToken 统一 Key 打通 Cursor 的 Base URL 配置

AI Coding IDE 入门指南:用 TaoToken 统一 Key 打通 Cursor 的 Base URL 配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 11:53:57 阅读更多 →
【Node.js】MongooseServerSelectionError: connect ECONNREFUSED 127.0.0.1:27017 与 mongod.exe 闪退排查:把本地连接配

【Node.js】MongooseServerSelectionError: connect ECONNREFUSED 127.0.0.1:27017 与 mongod.exe 闪退排查:把本地连接配

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 20:29:26 阅读更多 →

最新新闻

绝缘子缺陷检测数据集清洗与工业级训练实战指南

绝缘子缺陷检测数据集清洗与工业级训练实战指南

简介:本资源是面向电力AI研发人员、工业视觉工程师及智能巡检系统开发者的绝缘子缺陷检测专用YOLO格式数据集,解决无人机航拍场景下绝缘子破损、污闪、积雪等9类典型缺陷的精准识别与定位难题。数据集共2139张真实巡检图像(含训练/验证/测试集…

2026/10/12 0:05:01 阅读更多 →
牙科影像龋齿四级像素级分割数据集与临床落地实践

牙科影像龋齿四级像素级分割数据集与临床落地实践

简介:本资源是一套面向医学影像AI研究者与口腔临床算法开发者的专业蛀牙分割数据集,专为U-Net、DeepLab等分割模型训练设计,解决真实场景下多类别蛀牙区域精细识别与程度量化评估难题。数据集含400张高精度口腔内窥镜及X光影像(对…

2026/10/12 0:05:01 阅读更多 →
条形码目标检测数据集实战:从YOLOv8训练到部署

条形码目标检测数据集实战:从YOLOv8训练到部署

简介:这是一份面向目标检测与计算机视觉学习者的条形码识别数据集,涵盖零售、物流、制造等场景下的真实商品条码图像,适合用于训练YOLO系列模型或开展算法实验。数据集共684张图片,按训练集624张、验证集60张划分,采用…

2026/10/12 0:04:01 阅读更多 →
MongoDB复制集扩缩容实战:从rs.add到选主事故复盘

MongoDB复制集扩缩容实战:从rs.add到选主事故复盘

月初帮业务团队扩容一套 MongoDB 复制集,需求描述只有一句话:“加一台新机器进复制集,扛一下读流量。”我反问了一句:“你打算怎么加?”对方很自信:“rs.add() 啊,一行命令的事。”我当场就把计…

2026/10/12 0:04:01 阅读更多 →
Debian新手入门:从部署到日常操作的完整指南

Debian新手入门:从部署到日常操作的完整指南

第一次装完Debian,盯着黑乎乎的终端窗口迷茫好一会儿,这是我至今印象很深的场景。系统能开机、能登录,但下一步该敲什么命令完全没头绪。后来用久了才想明白一件事:Linux的入门难点从来不是"怎么把系统装上"&#xff0c…

2026/10/12 0:04:01 阅读更多 →
多模态大模型入门:从原理到实战,一文搞懂图文音视频一体模型

多模态大模型入门:从原理到实战,一文搞懂图文音视频一体模型

一、什么是多模态大模型? 💡 核心定义:多模态大模型是能够同时处理、理解和生成文本、图像、音频、视频等多种模态信息的人工智能模型。它打破了传统单模态模型(如仅处理文本的GPT-3或仅处理图像的ResNet)的限制&#…

2026/10/12 0:04:00 阅读更多 →

日新闻

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

在数码相机、高清显示屏与现代矢量图形技术高度发达的今天,画面可以做到绝对的锐利、平滑与无瑕。然而,当一张秋日手账插画或拍立得照片过于“平整无瑕”时,往往会散发出一种冰冷生硬的“数码塑料感(Digital Plasticity&#xff0…

2026/10/12 0:00:59 阅读更多 →
活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

在现代网页与移动端设计中,横排(Horizontal Layout)早已经成为了绝对的主流。然而,当我们翻开泛黄的线装古籍、宋版木刻诗集,或是欣赏一张茶道雅集的手写便签时,那种**自上而下纵向书写、自右向左逐列铺展&…

2026/10/12 0:00:59 阅读更多 →
周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

每到周日的晚上八点到十点,很多人心里都会悄悄亮起一盏警示灯。 在心理学上,这种现象有一个专门的称谓——“周日夜晚焦虑症(Sunday Scaries)”。明天又是周一,闹钟又要重新在七点响彻卧房;脑海里仿佛有一个…

2026/10/12 0:00:59 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 10:45:37 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:53 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:54 阅读更多 →