1. 一个人怎么干十几家公司的活:先想清楚这件事的本质
“一个干十几家公司的活”这句话,第一次听像段子,做过自由职业、外包、独立开发或者小团队技术负责人的朋友应该都懂——它不是让你真的去注册十几家公司,而是你手上同时跑着十几个项目的交付、维护、迭代,每个项目都有自己的代码库、部署流程、文档、测试、沟通节奏。我以前同时接过六个项目就已经快崩了,后来慢慢摸到一套方法:把重复劳动交给工具,把判断留给自己。
这篇文章要聊的,就是围绕 GitHub 上四个开源项目搭起来的一套“多项目并行工作流”。核心关键词是 GitHub、开源项目、AI、无代码、MCP。它解决的问题很具体:当你一个人要维护多个代码仓库、要频繁处理文档转换、要跟多个 AI 工具打交道、还要让非技术协作者也能参与进来时,怎么用开源工具把这条流水线串起来,而不是每个环节都手动干。
适合谁看?三类人。第一类是自己接活的技术 freelancer,手上项目多、时间碎;第二类是小团队里那个“什么都管”的人,既要写代码又要写文档还要对接需求;第三类是对 AI 工具链感兴趣、想把 MCP 这类新东西落到实际工作里的人。不需要你是架构师,但需要你愿意动手配环境、读文档、踩坑。
先说清楚我的整体思路,避免你看到后面觉得“这不就是堆工具吗”。多项目并行的真正瓶颈从来不是写代码的速度,而是上下文切换成本和信息搬运成本。你从 A 项目的部署脚本切到 B 项目的接口文档,脑子里要重新加载一整套背景;你把一份 Word 需求文档转成 Markdown 喂给 AI,手动复制粘贴要花十分钟。这四个开源项目分别打的就是这两个成本:一个管文档转换,一个管浏览器自动化,一个管 AI 与工具的连接协议,一个管多仓库的批量操作。它们不是随便凑的,是各自环节里我实测下来最省心的选择。
下面我会按“整体设计思路 → 核心细节 → 实操过程 → 问题排查”的顺序展开,每个环节都告诉你为什么这么选、参数怎么定、坑在哪里。你不需要四个全用,按自己项目数量挑着上就行。
2. 四个开源项目到底各管什么:选型逻辑与核心能力拆解
2.1 MarkItDown:把一切文档变成 AI 能吃的 Markdown
第一个项目是微软开源的MarkItDown。它的定位非常单一:把 PDF、Word、Excel、PPT、图片、音频、HTML 等各种格式转成 Markdown。你可能会问,转换工具那么多,为什么偏偏是它?我试过 pandoc、试过各种在线转换,最后留在 MarkItDown 上的原因是它对AI 消费场景做了针对性优化——输出的 Markdown 结构干净,标题层级、列表、表格都保留得比较好,而且它支持直接处理图片里的文字和音频转写,这在处理客户发来的扫描件合同时特别有用。
为什么文档转换在多项目工作流里这么关键?因为现在几乎所有 AI 辅助工具——不管是代码补全、需求分析还是文档问答——都更擅长吃纯文本。你把一份 30 页的 PDF 需求书直接丢给 AI,它要么读不全要么理解偏差;转成结构化的 Markdown 之后,AI 能准确抓到章节和要点。我实测下来,同一份需求文档,转 Markdown 后再让 AI 提取功能点,准确率比直接喂 PDF 高出一大截。
它的安装和使用都很轻。核心就是 Python 包,命令行一行搞定单个文件,也可以写几行代码批量处理整个目录。对于手上同时跑多个项目的人来说,批量能力比单文件转换重要得多——你不可能一个个文件手动转。
2.2 Playwright:浏览器自动化里的“万能手”
第二个是Playwright。严格说它不算新项目,但在多项目场景里它的价值被严重低估。我做项目经常遇到这些事:要给客户演示某个网页功能,要定期检查十几个项目的线上页面是否正常,要从后台系统批量导出数据,要模拟用户操作复现 bug。这些事手动做,一个项目十分钟,十个项目就是一百分钟,一周下来全是这种碎活。
Playwright 能把这些全部脚本化。它支持 Chromium、Firefox、WebKit 三个内核,API 设计比早期的自动化工具清爽很多,而且自带等待机制,不用你到处写 sleep。更关键的是,它现在和 AI 工具链结合得很好——你可以让 AI 生成 Playwright 脚本,也可以让 Playwright 作为 MCP 的一个工具被 AI 调用。这就引出了第三个项目。
2.3 MCP:让 AI 真正“动手”的协议层
第三个是MCP,全称 Model Context Protocol。这是 Anthropic 推出来的开放协议,解决的问题是:AI 模型本身只能聊天,不能直接操作你的文件、数据库、浏览器、Git 仓库。MCP 定义了一套标准接口,让 AI 客户端(比如各种支持 MCP 的编辑器、桌面工具)能够调用外部工具服务器。
为什么这对“一个人干十几家公司的活”特别重要?因为你的工作里有大量“AI 能帮但需要它拿到上下文”的场景。比如你想让 AI 帮你 review 某个仓库的代码,传统做法是你手动把代码贴进去;有了 MCP,AI 可以直接通过文件系统工具读取仓库。你想让 AI 帮你查线上页面状态,通过 Playwright MCP,AI 能直接开浏览器去看。MCP 是那个把 AI 从“顾问”变成“能动手的助手”的中间层。
热词里出现的 playwright mcp、blender mcp、burpsuite mcp、蓝湖 mcp,本质上都是不同工具把自己的能力包装成 MCP server,供 AI 调用。你不需要全部装,按自己项目需要挑。我目前常驻的是文件系统 MCP 和 Playwright MCP 两个,已经能覆盖大部分场景。
2.4 多仓库批量操作工具:把 Git 命令变成一次执行
第四个严格说是一类工具,我选的是基于 GitHub CLI 加脚本的组合方案,核心是批量操作多个仓库。GitHub 官方有gh命令行工具,配合 shell 脚本或者简单的 Python 脚本,可以做到:一次性拉取十几个仓库的最新代码、批量创建 issue、批量检查 PR 状态、批量更新依赖版本。
为什么不用现成的多仓库管理平台?因为那些平台要么收费、要么绑定特定工作流,而gh加脚本的方案足够灵活,你想怎么组合就怎么组合。我现在的做法是维护一个仓库清单文件,里面列出所有项目的仓库地址和本地路径,然后写几个常用脚本:pull-all、status-all、branch-check。每天早上跑一次pull-all,所有项目的最新状态一目了然。
这四个东西组合起来的逻辑是这样的:MarkItDown 负责把非结构化信息变成结构化文本,Playwright 负责把网页操作自动化,MCP 负责让 AI 能调用这些能力,批量 Git 工具负责管理代码仓库本身。它们各自独立,但串起来就是一条从“接收信息”到“处理信息”到“操作执行”的完整链路。
3. 核心细节与实操要点:每个环节怎么配、参数怎么定
3.1 MarkItDown 的安装与批量转换脚本
MarkItDown 的安装很直接,用 pip 就行。我建议单独建一个虚拟环境,因为它依赖一些文档解析库,跟其他项目的依赖容易冲突。
python -m venv markitdown-env source markitdown-env/bin/activate # Windows 用 markitdown-env\Scripts\activate pip install markitdown装完之后命令行就能用了:
markitdown input.pdf > output.md markitdown input.docx > output.md但单个转换不是重点,重点是批量。我写了一个脚本,扫描指定目录下所有支持的文件,逐个转换到输出目录,并且保留相对路径结构。这样客户发来一个压缩包,解压后直接跑脚本,整个目录的文档就全变成 Markdown 了。
from markitdown import MarkItDown from pathlib import Path md = MarkItDown() src_dir = Path("./inbox") out_dir = Path("./converted") out_dir.mkdir(exist_ok=True) supported = {".pdf", ".docx", ".xlsx", ".pptx", ".html", ".png", ".jpg"} for f in src_dir.rglob("*"): if f.suffix.lower() in supported: rel = f.relative_to(src_dir) target = out_dir / rel.with_suffix(".md") target.parent.mkdir(parents=True, exist_ok=True) try: result = md.convert(str(f)) target.write_text(result.text_content, encoding="utf-8") print(f"OK: {rel}") except Exception as e: print(f"FAIL: {rel} -> {e}")这里有几个实操要点。第一,图片和扫描件转换质量取决于 OCR 效果,如果客户发来的是低分辨率扫描件,转换出来的文字会有错漏,重要文档建议人工核对关键数字。第二,Excel 转换会丢失公式,只保留计算后的值,如果你需要公式逻辑,得单独处理。第三,大文件转换会慢,一个 200 页的 PDF 可能要几十秒,批量处理时建议加个进度输出,不然你不知道卡在哪了。
提示:MarkItDown 对中文文档的支持整体不错,但遇到复杂排版的 PDF(比如多栏学术论文)时,阅读顺序可能会乱。这种情况我一般先用它转一遍,再手动调整关键段落。
3.2 Playwright 的脚本化与 MCP 接入
Playwright 的安装分两步:装 Python 包,再装浏览器内核。
pip install playwright playwright install chromium只装 chromium 是因为大部分场景够用,装全部三个内核会多占几百 MB 空间。如果你有跨浏览器测试需求,再补playwright install firefox webkit。
一个典型的“检查多个项目线上状态”脚本长这样:
from playwright.sync_api import sync_playwright sites = [ {"name": "项目A", "url": "https://a.example.com", "selector": ".app-loaded"}, {"name": "项目B", "url": "https://b.example.com", "selector": "#main-content"}, ] with sync_playwright() as p: browser = p.chromium.launch(headless=True) page = browser.new_page() for site in sites: try: page.goto(site["url"], timeout=15000) page.wait_for_selector(site["selector"], timeout=10000) print(f"{site['name']}: OK") except Exception as e: print(f"{site['name']}: FAIL - {e}") browser.close()参数上我踩过的坑:timeout 不要设太短,有些项目部署在慢速服务器上,15 秒是底线;wait_for_selector 比 wait_for_timeout 靠谱,前者是等元素出现,后者是死等固定时间,后者要么浪费时间要么不够用。headless 模式默认开启,调试的时候改成headless=False能看到浏览器实际操作过程,排查问题很有用。
接入 MCP 的话,Playwright 有官方的 MCP server,配置到支持 MCP 的客户端里,AI 就能直接调用浏览器能力。配置方式通常是在客户端的 MCP 配置文件里加一段:
{ "mcpServers": { "playwright": { "command": "npx", "args": ["-y", "@playwright/mcp@latest"] } } }配好之后,你可以直接对 AI 说“帮我打开某个页面,截图并告诉我首屏有没有报错”,它会自己调 Playwright 去执行。这个体验跟手动写脚本完全是两个层次——脚本是你预先想好要做什么,MCP 是你描述目标让 AI 现场决定怎么做。
3.3 MCP 的选型与安全边界
MCP 生态现在很热闹,热词里能看到各种 mcp server。我的建议是按需装,不要贪多。每多一个 MCP server,就多一个 AI 能操作你系统的入口,安全边界要自己心里有数。
我目前常驻的配置:
| MCP Server | 用途 | 风险等级 |
|---|---|---|
| filesystem | 让 AI 读写指定目录的文件 | 中,需限定目录范围 |
| playwright | 浏览器自动化 | 中,注意别让它访问敏感页面 |
| github | 操作仓库、issue、PR | 高,建议用只读 token 起步 |
| markitdown | 文档转换 | 低,纯本地处理 |
配置 filesystem MCP 时,一定要限定允许访问的目录,不要图省事给根目录权限。我一般给每个项目单独配一个允许目录,AI 只能在这个项目文件夹里活动。github MCP 的 token 权限也要收着给,先给只读,确认工作流稳定了再考虑加写权限。
注意:MCP server 本质上是本地跑的一个进程,AI 通过它执行操作。任何能执行命令的 MCP server 都要谨慎对待,尤其是那些能跑 shell 命令的。装之前看一眼它的源码或者文档,确认它做了什么。
3.4 多仓库批量操作的脚本设计
批量操作的核心是维护一份仓库清单。我用一个简单的 YAML 文件:
repos: - name: project-a path: ~/work/project-a remote: git@github.com:user/project-a.git - name: project-b path: ~/work/project-b remote: git@github.com:user/project-b.git然后写一个 Python 脚本读这个清单,批量执行 git 命令:
import subprocess import yaml from pathlib import Path with open("repos.yaml") as f: config = yaml.safe_load(f) for repo in config["repos"]: path = Path(repo["path"]).expanduser() if not path.exists(): print(f"{repo['name']}: 目录不存在,跳过") continue result = subprocess.run( ["git", "-C", str(path), "pull", "--ff-only"], capture_output=True, text=True ) status = "OK" if result.returncode == 0 else "FAIL" print(f"{repo['name']}: {status}") if result.returncode != 0: print(f" {result.stderr.strip()}")--ff-only这个参数很关键,它保证只做快进合并,遇到分叉就报错而不是自动 merge。多项目场景下,你绝对不希望某个仓库在你不知情的情况下产生一个 merge commit。报错了你再去手动处理,这样可控。
同样的思路可以扩展到批量检查状态、批量创建分支、批量查看未提交改动。我每天早上跑一遍pull-all和status-all,十分钟内掌握所有项目的代码状态。
4. 完整实操流程:从零搭起这套工作流
4.1 环境准备与目录规划
先把目录结构定下来,这决定了后面所有脚本的路径怎么写。我的习惯是在 home 目录下建一个work文件夹,里面每个项目一个子目录,另外单独建一个_tools目录放脚本和配置。
~/work/ ├── _tools/ │ ├── repos.yaml │ ├── pull_all.py │ ├── convert_docs.py │ └── check_sites.py ├── project-a/ ├── project-b/ └── project-c/_tools用下划线开头是为了在文件列表里排在最前面,方便找。所有脚本都假设自己在_tools目录下运行,路径引用用相对路径加expanduser,这样换机器也能用。
Python 环境我建议用一个统一的虚拟环境跑这些工具脚本,不要每个脚本单独建环境。因为 MarkItDown、Playwright、yaml 这些依赖可以共存,统一环境省事。
cd ~/work/_tools python -m venv .venv source .venv/bin/activate pip install markitdown playwright pyyaml playwright install chromium4.2 文档转换流水线的搭建
假设客户发来一个压缩包,里面是各种格式的需求文档。流程是:解压到inbox目录,跑转换脚本,输出到converted目录,然后把 Markdown 喂给 AI 做需求分析。
mkdir -p inbox converted # 解压客户文件到 inbox python convert_docs.py转换完成后,我会用 AI 对转换结果做一轮结构化提取。比如让 AI 读所有 Markdown,输出一份功能点清单和待确认问题清单。这一步用 MCP 的 filesystem server 最方便——AI 直接读converted目录,不用我手动粘贴。
这里有个经验:转换后的 Markdown 建议先人工扫一遍,尤其是表格和数字。OCR 在数字上出错率比文字高,一个金额或者日期错了,后面全错。我一般重点核对表格、金额、日期、专有名词这几类。
4.3 浏览器自动化的日常巡检
巡检脚本我设了定时任务,每天早上九点跑一次,结果输出到一个日志文件。有异常的话我会收到通知(简单做法是脚本最后判断如果有 FAIL 就发一封邮件或者写一个显眼的标记文件)。
# crontab 示例 0 9 * * * cd ~/work/_tools && .venv/bin/python check_sites.py >> check.log 2>&1巡检项包括:首页是否能打开、关键元素是否加载、有没有明显的错误提示、页面标题是否正确。这些检查看起来简单,但能挡住大部分“部署完忘了验证”的低级问题。我遇到过好几次部署脚本跑成功了但页面白屏的情况,都是巡检发现的。
4.4 AI 协作环节的串联
把前面几步串起来,一个典型的多项目工作日是这样的:
早上到工位,先跑pull_all.py拉取所有仓库最新代码,跑check_sites.py看所有线上项目状态。然后打开 AI 客户端,通过 MCP 让它读取今天需要处理的文档和代码。需要查网页的时候,让 Playwright MCP 去开浏览器。需要改代码的时候,直接在对应项目目录里操作,改完用批量脚本统一提交和推送。
这套流程的关键在于减少手动切换。以前我是在十几个终端窗口和浏览器标签之间来回跳,现在大部分操作通过脚本和 AI 完成,我只需要做判断和决策。时间省下来不是一点半点。
5. 常见问题与排查技巧实录
5.1 MarkItDown 转换失败的几种情况
| 现象 | 可能原因 | 解决方法 |
|---|---|---|
| 报缺少依赖 | 某些格式需要额外库 | 按报错提示补装,如pip install markitdown[all] |
| 中文乱码 | 源文件编码问题 | 确认源文件编码,必要时先用其他工具转码 |
| 表格错位 | PDF 表格结构复杂 | 转换后人工调整,或改用专门的表格提取工具 |
| 图片无文字 | OCR 未识别 | 检查图片分辨率,过低则无法识别 |
| 转换极慢 | 文件过大或页数过多 | 拆分文件分批处理 |
我踩过最坑的一次是一个加密 PDF,MarkItDown 直接报错退出,但错误信息很模糊。后来发现是 PDF 有打开密码,需要先解密。这类问题没有通用解法,只能遇到一个记一个。
5.2 Playwright 脚本不稳定的排查思路
Playwright 脚本最常见的失败是“元素找不到”。排查顺序是:先改成headless=False看实际操作过程,确认页面是否真的加载了;再检查 selector 是否唯一,有时候 class 名在多个元素上重复;然后看是不是有 iframe,iframe 里的元素需要先frame_locator切换上下文;最后考虑是不是网络慢导致超时,适当加大 timeout。
还有一个隐蔽问题:有些网站会检测自动化工具,headless 模式下返回的页面和真实浏览器不一样。这种情况可以试试加user_agent参数伪装,或者用channel="chrome"调用本机安装的 Chrome 而不是 Playwright 自带的 Chromium。
5.3 MCP 配置不生效的检查清单
MCP 配了没反应,按这个顺序查:第一,确认客户端支持 MCP 并且版本够新;第二,检查配置文件路径对不对,不同客户端放配置的位置不一样;第三,看 MCP server 进程有没有真的启动,可以在终端手动跑一遍启动命令看报不报错;第四,检查权限,比如 filesystem server 配的目录是不是你实际要访问的目录;第五,看客户端日志,大部分客户端会把 MCP 连接错误写在日志里。
提示:MCP 生态变化很快,配置格式和 server 名称可能随版本更新。遇到问题先看对应 server 的官方 README,比搜博客靠谱。
5.4 批量 Git 操作的避坑要点
批量操作最怕的是“一个仓库出问题影响全部”。我的脚本设计原则是每个仓库独立处理,单个失败不中断整体。上面给的脚本里用了 try 逻辑和 returncode 判断,就是为了这个。
另外,批量操作前先确认没有未提交的改动。如果某个仓库有本地修改,git pull可能会失败或者产生冲突。我的做法是在 pull 之前先跑一遍 status 检查,有未提交改动的仓库单独标记出来,不参与自动 pull。
还有一个细节:SSH key 和凭据管理。如果多个仓库用不同的 SSH key,批量操作时可能会遇到权限问题。统一用一套 key 或者配置好 SSH config 能省很多事。
6. 几个我实际用下来觉得值得说的点
这套工作流我跑了大概半年,最大的感受是:工具的价值不在于它多强,而在于它能不能嵌进你的日常习惯。MarkItDown 再强,如果你每次都要想起来手动跑,它就没价值;Playwright 脚本写得再好,如果不设成定时任务,你还是会忘记检查。所以配置的时候多花点心思在“自动化触发”上,比优化单个工具的性能重要得多。
另一个体会是,MCP 这类新东西不要一上来就全铺开。我一开始装了一堆 MCP server,结果配置冲突、权限混乱,反而添乱。后来砍到只留 filesystem 和 playwright 两个,稳定运行之后再逐步加。工具链是长出来的,不是一次搭好的。
最后分享一个具体的小技巧:给每个项目在_tools目录下建一个对应的配置文件,记录这个项目的仓库地址、线上地址、关键检查项、常用命令。这样你切换项目的时候不用回忆,打开配置文件一目了然。这个习惯看起来笨,但在我同时跑十几个项目的时候,它救了我很多次。