跪拜 Guibai
← All articles
Agent · Architecture · Open Source

When LLMs Hallucinate Code References, Regex and Grep Catch What Self-Review Misses

By Erishen ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

LLM-as-judge patterns are spreading fast in agent frameworks, but they inherit the same hallucination problem they're supposed to catch. Swapping in deterministic verification — regex plus a filesystem grep — costs almost nothing and eliminates an entire class of silent failures where fabricated API names or file paths sail through review.

Summary

Multi-agent pipelines that let one LLM review another's output suffer a fundamental trust problem: the reviewer hallucinates just as easily as the writer. crewai-pse sidesteps this by pulling verification out of the LLM entirely. A `_verify_article()` function extracts every backtick-wrapped identifier and `def`/`class` declaration from the generated text, then greps the actual source tree to confirm existence — a deterministic check that cannot be fooled by an LLM's false confidence. Python keywords and virtual-environment paths are explicitly excluded to avoid false positives.

When fictitious references are found, the pipeline does not re-run the full Planner–Specialist–Evaluator crew. Instead, it calls the OpenAI API directly with a fix prompt that instructs deletion, not creative replacement, keeping the repair cheap and controlled. If three LLM fix rounds still leave exaggerated claims, a programmatic fallback strips sentences containing banned terms by splitting on Chinese punctuation boundaries.

File access is sandboxed: the `read_file` tool resolves paths and rejects any request outside `PSE_ROOT`, blocking symlink escapes and access to `/etc/passwd` or private keys. The full pipeline runs source code through CrewAI for drafting, then through verification, fix loops, and finally translation into English with explicit instructions to preserve all code identifiers unchanged.

Takeaways
A `_verify_article()` function uses regex to pull every backtick-wrapped identifier and `def`/`class` declaration from generated text, then greps the source tree to confirm existence.
Python keywords like `def`, `class`, `True`, and `None` are explicitly excluded from verification to prevent false positives on ordinary language.
The grep search skips `.venv` and `__pycache__` directories so that virtual-environment copies of installed packages don't produce misleading matches.
When fictitious references are detected, the pipeline calls the OpenAI API directly with a fix prompt that demands deletion — not creative replacement — avoiding a full three-agent re-run.
A programmatic fallback `_strip_exaggerated()` splits text on Chinese punctuation and removes any clause containing a banned exaggerated term, acting as a final guard when LLM fixes fail after three rounds.
The `read_file` tool resolves paths with `Path.resolve()` and refuses any request outside `PSE_ROOT`, blocking symlink escapes and access to system files like `/etc/passwd`.
The translation step explicitly instructs the model to keep all code examples, file paths, class names, and function names unchanged, preserving technical accuracy across languages.
Conclusions

The Evaluator agent is created and assembled into the Crew but never actually used for verification — its role is purely ceremonial, while the real quality gate is the programmatic function. This is a quiet admission that LLM self-review adds so little trust that it's better to just not call it.

Bypassing CrewAI's orchestration for the fix loop isn't just about saving API calls. It also avoids the framework's fuzzy retry semantics, giving the developer exact control over when and how a fix is triggered.

The fix prompt's insistence on deletion over creative replacement targets a specific failure mode: LLMs asked to 'correct' hallucinations often invent new plausible-sounding but equally false substitutes.

Sandboxing file access at the tool level rather than relying on agent prompts or system messages is a defense-in-depth move — no matter what the LLM is tricked into requesting, the tool itself refuses.

Concepts & terms
Programmatic verification
Using deterministic code (regex, filesystem search, type checks) to validate LLM output instead of asking another LLM to judge it. The result is reproducible and cannot be swayed by the model's confidence level.
PSE (Planner–Specialist–Evaluator)
A three-role agent architecture for article generation: Planner structures the outline, Specialist writes the draft, and Evaluator reviews quality — though in crewai-pse the Evaluator's review role is replaced by programmatic checks.
Sandboxed file access
Restricting an agent's filesystem operations to a declared root directory (`PSE_ROOT`) and rejecting paths that resolve outside it, including symlink escapes, so the agent cannot read sensitive system files even if prompted to.
From the discussion
Featured comments
dsh_daily_pulse 1 likes

I feel like adding to the agent's soul md: must not fabricate, must not take things for granted, must not assume — it feels like that already improves things a lot.

Erishen

Indeed effective 👍 My article actually takes it one step further: MD is responsible for constraints, Programmatic Verification is responsible for verification. If a program can judge it, don't let the Agent say "I didn't fabricate" by itself.

See top comments, translated →
Source: juejin.cn ↗ Google Translate ↗ Backup ↗