In Part 5 I fixed
the Korean/English duplicate detection problem. The question that came right after went in
a completely different direction: “to speed up note creation (ingest), is it OK to raise
the number of parallel requests (ingestConcurrency) from 2 to 4?”
Does more parallelism hurt quality? — parallel LLM API requests and sequential writes
ingestConcurrency is the value that sets how many sources are sent to the AI at the same
time (default 2). Raising it finishes the same work in less time, but first I needed to
check whether requests processed at the same time could affect each other and tangle the
results.
Opening the code, the answer was clear. The part that sends requests to the AI fires
several at once, but the part that takes the responses and actually writes note files was
written to always handle them one at a time, in order. So even with several requests in
flight, there was no way for results from different requests to get mixed up at the point
of writing files. ingestConcurrency is purely a knob for “how fast it finishes”; it’s
structurally unrelated to result accuracy or how finely notes get split.
Actually raising it to 4 and running a full audit — parallel processing speed and quality
Rather than stopping at theory, I actually raised the parallel count to 4 and ran the same 30 sources again. The result: 225 notes in 17 min 46 s, clearly faster than the same conditions with 2 in parallel (25 min 35 s). Auditing all 30 sources against the wiki notes found essentially zero fidelity problems. The hypothesis that more parallelism doesn’t affect quality was confirmed by measurement.
It would have been nice to stop there, but in the course of that full audit, two new bugs turned up somewhere completely different.
Bug 1 — a pair that still wouldn’t merge even after the threshold fix (duplicate note detection scope)
Even though I’d lowered the Korean/English duplicate detection threshold to 0.70 in Part 5, this audit found that a note pair clearly pointing to the same thing, “클로드 코드” (Korean for “Claude Code”) and “Claude Code” (English), still wasn’t merging. Recomputing this pair’s similarity from the actual embedding cache gave 0.72–0.77, already above the new threshold (0.70). If not the threshold, what was filtering this pair out?
The cause was in how notes are “classified.” When this plugin creates a note, it also classifies whether the note is an abstract concept or a concrete entity (product names, company names, people, and so on). But the duplicate detection logic fixed in Part 5 only compared notes classified as concepts with each other. Product and company names like “Claude Code,” “Uber,” and “Anthropic” are all classified as entities, so no matter how low the similarity threshold went, they never even got onto the list of things to compare.
In fact, this part had been deliberately left out of scope at design time, “because we’d never seen entity pairs actually cause a problem.” This was exactly that real-world case. I settled it by widening the comparison scope to “concepts or entities, but only when both files share the same classification.” Comparing concepts against entities stayed excluded, since a specific product and an abstract concept can’t be the same thing in the first place.
Bug 2 — a 100% English source, but only the headings came out in Korean (an LLM copying the prompt’s example)
The same audit also turned up something stranger. For all four notes made from a source written entirely in English (a technical proposal about C++), the body was correct English but only the headings were in Korean (“배경과 목적” for “background and purpose,” “기술적 접근” for “technical approach,” and so on).
At first I suspected the parallel processing (concurrency) covered earlier in this post. The hypothesis was that one of the requests processed at the same time had a Korean source, and its language leaked into processing the English source. But on checking, it didn’t hold. The code that sends requests to the AI shares no state between concurrent requests, so this kind of mixing was structurally impossible, and compared with the earlier result that processed the same source with 2 in parallel, the problem didn’t exist at all then.
The real cause was in the prompt. The instruction “structure the body with headings,” shared by the note-creation and note split/merge prompts, had Korean headings like “핵심 개념” (“key concepts”), “실제 사례” (“real examples”), and “한계점” (“limitations”) baked in as an example to show the format. That example was purely there to illustrate “split it like this,” but the model appeared to copy the language of the concrete example in the prompt more strongly than the separate explicit rule that heading language should follow the source. So I fixed it right away by adding a caveat that the example wording only shows the structure, and that the language of the actual headings should follow the source regardless of the example.
Summary
Both bugs in this post popped up somewhere completely unrelated to the original goal of verifying parallel processing. If they have anything in common, it’s that both were caught “because I didn’t skimp on the full audit.” Had I only measured speed and stopped, both would have slipped by.
Now just one thing remained: the question I’d been putting off since early in the investigation. What was Laptop 2’s actual reasoning effort value, really?
Continued in Part 7.