Revising 67 Old Posts with Parallel AI Agents
How we turned 67 tutorial posts from 2021 into verified en/ja/ko articles with 18 parallel AI sub-agents: shared brief, waves, validators, one merge.
This is for anyone sitting on a pile of old blog posts or docs who wonders whether AI sub-agents can revise them in parallel without the result turning into a mess. We revised all 67 tutorial posts from 2021 on this blog into checked English, Japanese and Korean articles; the last 54 went out in one deploy after 18 agents worked on them in parallel. It worked, but only because of four things: a shared brief, strict file ownership, validators every agent had to pass, and a single merge step that no agent was allowed to do.
The guardrails for letting an agent touch a live server are covered in AI Coding Agent on a Live Server: Guardrails That Held. This post is about the other half: many agents, one shared repository, no conflicts.
The job in numbers
Every number below comes from the session's tool output or from counting files afterwards.
| Item | Value |
|---|---|
| 2021 posts revised | 67 (all of them) |
| Posts in the three parallel waves | 54 |
| Sub-agents in those waves | 18 (6 per wave) |
| Posts per agent | 2 to 4 |
| Agent working time, summed | about 349 minutes |
| Wall clock, first launch to last finish | about 50 minutes |
| Tool calls made by the 18 agents | 1,313 |
| New figures on the 54 posts | 91 (108 across all 67) |
| Files changed by the final deploy | 839 of 1,368 |
| Legacy images moved out and deleted from the server | 85 (11 + 74) |
| Content checker before the deploy | 0 errors, 0 warnings |
After that deploy each language had 86 posts, and the sitemap listed 326 URLs.
Before the waves: 13 posts the slow way
We did not start with 18 agents. The first 13 posts went in small steps, and each step taught us something the brief later needed.
- 1 post by the main session alone, to set the format: the Korean original rewritten in place, plus new English and Japanese versions.
- 3 posts by the main session, one at a time. This is where "re-run every 2021 sample" proved its worth: one sorting example printed
23457instead of2 3 4 5 7, and the 2021 quicksort crashed with a stack overflow on already-sorted input. - 3 posts by one sub-agent, as a test of whether a single agent could follow the format unaided. It took 17.3 minutes.
- 6 posts by three sub-agents at once, two each. They took 13.9, 14.6 and 15.4 minutes. That was the first time several agents shared the figure folder and the checker, and the first time two problems showed up: an old screenshot with a Windows account name in it, and validator warnings caused by other agents' figures.
When the operator said "revise the rest, all of them, without asking me each time", 54 posts were left. We wrote the brief before launching anything.
The shared brief
Each agent got a short prompt: "Read and follow the brief exactly", then its own list of posts and a few scope notes. Everything else lived in one Markdown file that every agent read. That kept 18 prompts consistent and let us fix a rule in one place.
What the brief contained:
- Outputs per post. Rewrite the Korean 2021 file in place (keep its slug, original date and old WordPress fields), create English and Japanese versions, and add one or two figures. Localise, do not translate line by line.
- Verification as the main job. Extract every code sample, compile and run it (.NET 10 for C#, clang for C and C++), and show the real output and the real warnings with their codes. Fix 2021 mistakes and say so in the post. Check every "added in C# N" claim by compiling with an older language version.
- Windows-only code. WinForms and Win32 code can be compiled on a Mac but not run. The brief said: compile it, say plainly "compiled, not run", and never invent output.
- Old images. Open every image the post references. Remove anything with personal data, anything outdated, and anything that looks copied from third-party material.
- Privacy in the text. Look for Windows user folders in pasted compiler output and for real names used as sample data.
- File ownership. Write only your own
content/*/<slug>.mdanddata/figures/<slug>.yaml. Do not touch other posts, scripts, templates or the server. - Do not build or deploy. Other agents are working in parallel.
- Validators to pass before reporting, and a fixed report format: titles, lengths, headings, figure ids, 2021 errors fixed, measurements, removed images, and the checker's last line.
The brief also changed during the run. After wave 1, one agent had removed a diagram because it looked copied from a textbook, and another had found the operator's name used as sample data. Both checks went into the brief before waves 2 and 3 started, so the later 36 posts got them from the beginning.
Waves, and how we grouped the posts
We grouped posts by topic, not by size, so that posts that overlap ended up with the same agent:
- Wave 1: 18 C# basics posts. Six agents with three posts each.
- Wave 2: 19 posts. Collections, LINQ query syntax with reflection and file I/O, Registry and WinForms (four posts for one agent), two Win32 API groups, and the regex introductions.
- Wave 3: 17 posts. Regex character sets and quantifiers (four posts), stack and queues, linked lists, tree, heap and BST, BFS and DFS, greedy and sequential search.
Grouping by topic mattered more than balancing the load. The three collection posts from 2021 overlapped heavily, so one agent got all three with the instruction "give each a clearly separate scope and cross-link them". When related posts had to go to different agents, the prompt said so. The wave 3 regex agent was told that another agent was writing the regex introductions in parallel, and to link to them instead of repeating them.
Wave 2 started while three wave 1 agents were still running, and wave 3 started four minutes later. So from then until the end, twelve agents were working at once. Per agent, the time ranged from 13.1 minutes (two posts) to 26.0 minutes (four regex posts tested in four engines).
To watch progress without reading agent output, we counted finished posts from the files themselves. A post counts as done when its Korean file says legacy: false and both translations exist. This is the same loop, run again for this article (zsh):
n=0
for f in content/ko/_legacy/*.md; do
s=$(basename $f .md)
if grep -q "^legacy: false" $f && [ -f content/en/$s.md ] && [ -f content/ja/$s.md ]; then
n=$((n+1))
fi
done
echo "revised $n / $(ls content/ko/_legacy/*.md | wc -l | tr -d ' ')"
revised 67 / 67
During the run the same loop printed 완료 38 / 67 at one check and 완료 64 / 67 ten minutes later. The file system is the shared truth, and a count like this does not depend on any agent's word.
Why every agent compiles and runs every snippet
An agent can rewrite a 2021 tutorial so that it reads well without running a line of it. That version would look fine and still be wrong. The reports showed how much "reads fine" would have missed:
- A C# collections post had a
Colsoletypo, which gives error CS0103, so that example had never compiled as published. - A heap implementation in C++ was logically right: 400,000 random operations matched
std::priority_queue. But copying the heap object caused a double free, which AddressSanitizer reported. - A Win32 sample called
FindWindowAwith a Korean window title. With GCC the string is stored as UTF-8 in the executable, so on a Korean Windows system the ANSI call would never match. - One 2021 sample contained an invisible U+200B after a closing brace. Pasted as-is, it fails with
error: '\U0000200b' does not name a type.
None of these show up when you read the code. All of them show up when you compile it. That is why the brief made running the code the main job and treated the writing as the second one. It is also the part of the article no search summary can supply: the real error codes, the real output, and what was changed and why.
The validators each agent had to pass
Before reporting, each agent had to show:
check_figures.pywith 0 errors, and no warnings on its own figures. It renders every figure in three languages, plus the vertical phone layout, and warns when a figure is wider than 1000 px.- Rendered previews of the Korean and Japanese figures, looked at. Agents used
qlmanageto turn SVGs into PNGs and opened them. Several fixed overlapping labels this way. - Frontmatter parsed as YAML, with title and description lengths checked by a short script.
- A text scan of its own files for personal paths and names.
One problem with a shared validator: check_figures.py renders every figure file in the folder, so each agent saw warnings from figures that other agents were still working on. One report read: "All 12 warnings are on other agents' figures; my 6 figures have none." That was correct, but it meant every agent had to sort the output by owner. If we did this again, the checker would take a slug list and report only on those slugs by default.
The merge: one build, one check, one deploy
When the last agent finished, the main session did the merge alone, in this order:
- A site-wide scan for personal names and paths, across all languages (not only the files that changed).
- A list of legacy images that no post references any more.
- Moving those images to a local backup folder.
- One build, the content checker, and the figure checker.
- A dry run of the deploy with
--prune, plus a check that prune would delete images only. - The real deploy, then spot checks on live URLs, including one removed image that had to return 404.
The relevant lines from that run (our tools print Korean; the comments are ours):
build ok → …/public (posts: en 86, ja 86, ko 86, sitemap urls: 326)
검사: 파일 1368개, HTML 330개 → 오류 0건, 경고 0건 # 1,368 files, 0 errors, 0 warnings
그림 144개 · 오류 0 · 경고 0 # 144 figures, 0 errors, 0 warnings
prune would delete: 74 | non-image: []
빌드 파일 1368개 중 변경 839개 # 839 of 1,368 files changed
404 /static/img/legacy/2021/06/20190404_171228_204.png
8/8 통과 # quick URL test passed
The deploy took about 15 minutes, because more than 800 files changed. Building once at the end also prevented a problem that is easy to miss: a post that is halfway through revision should never go live, and the only way to guarantee that with 18 writers is to have no writer deploy.
What the human still checked
Parallel agents reduce writing time. They do not reduce review time to zero. This is what review actually cost on our side:
- Reading 18 reports. Each one listed titles, lengths, headings, the 2021 errors it fixed and the images it removed. This is where the cross-agent findings came from: the first report that mentioned a Windows account name led to a site-wide search, which found two more posts with the same path before their agents had started.
- Following up on a flagged image. An earlier agent removed a screenshot from its post because it showed a local user path, but the file itself was still on the server. Removing a reference is not removing a file.
- Checking an agent's own admission. One agent reported that it had created a stray file through a path typo and deleted it. We checked that the folder was really gone.
- Broadening our own search. A word-boundary grep for the operator's name missed one variant where the name was joined to another word. An agent found it in the text; we widened the pattern and searched everything again.
- Reviewing the delete list. The prune list was read line by line, and the script confirmed it contained no non-image file.
- Operator-only steps. The go-ahead for the whole run, then two follow-ups handed to the operator: a CDN cache purge in the hosting panel, so deleted images stop being served from cache, and Search Console indexing for the new URLs (183 waiting, about 10 a day).
There is one thing the review missed, and we found it only while counting for this article: one unused image was not moved, because of a shell loop bug. That story is in When the AI Agent's First Diagnosis Was Wrong, and the audit of the images is in Old Blog Posts: A Privacy and Copyright Audit.
When parallel agents help, and when they hurt
| Situation | Parallel agents? | Why |
|---|---|---|
| Each task writes its own files (one post, its translations, its figure file) | Yes | No merge conflicts, so the only shared step is the build |
| Tasks share a file (a topic list, a template, a config) | No, or give one agent ownership | Two agents editing one file means one of them loses work |
| Task B needs task A's output (an index page, cross-links to finished posts) | In waves | Put B in a later wave, as we did with posts that link to already revised siblings |
| Every task can be checked by a script (compiles, renders, parses) | Yes | The agent can prove its own work before reporting |
| Quality is a judgment call with no script (tone, legal wording) | Few agents, more review | The review cost grows with the number of agents |
| The step changes shared state (build, deploy, delete) | Never in parallel | Keep it in one session, after everyone has finished |
| Overlapping topics | One agent per cluster | Overlap is easier to resolve inside one agent than between two |
Honest limits
- Speed is not the main win. 349 agent-minutes in about 50 minutes looks impressive, but the posts are only as good as the checks. Without compile-and-run, faster would simply mean wrong sooner.
- Windows-only code was compiled, not run. Posts that use WinForms, the Registry or Win32 say so. Runtime behaviour there comes from documentation, not from us.
- "Looks copied" is a judgment. Agents removed diagrams that resembled textbook material. We could not prove where each one came from, so we chose the safe side.
- Validators only check what they check. Every post passed the figure and content checkers, and the shell loop bug still got through. A count comparison would have caught it, and that is now on our checklist.
The pattern we would reuse: write the brief first, give every agent its own files, make every agent prove its work with scripts, and keep build, deploy and delete in one place.
FAQ
How many agents ran at once, and how long did it take?
The last 54 posts went to 18 sub-agents in three waves of six, with two to four posts each. Their working time added up to about 349 minutes, but the wall-clock time from the first launch to the last finish was about 50 minutes, because waves 2 and 3 overlapped.
Why not let each agent build and deploy its own posts?
The build writes the whole public folder and the sitemap, and the deploy prunes files that are no longer referenced. Both are shared state. One agent deploying while another is halfway through a post would publish half-written work, so only the main session built and deployed, once, after every agent had finished.
What did a human still have to check?
The main session read every agent report, re-ran a site-wide personal-data scan, looked at flagged images, and reviewed the exact list of files the deploy would delete. The operator approved the run and was left the steps only an account owner can do: purging the CDN cache and submitting the new URLs for indexing.