Every week I scroll through Cloudflare’s blog and find a nugget of insight that could be turned into a reusable Python helper. Manually translating those posts into code takes hours, and bugs creep in when I rush. In this post you’ll see how I wired a self‑healing LLM agent that pulls the latest RSS entries, generates a design document and skeleton module, validates the syntax, runs unit tests, and automatically repairs any issues—all in a repeatable script. By the end, you’ll have a pipeline that can spin up a new feature module from a blog post in under ten minutes.
Key Takeaways
- Automated ingestion of real RSS feeds eliminates manual copy‑paste bottlenecks.
- Combining AST parsing with unit‑test harnesses provides fast, deterministic feedback for LLM‑generated code.
- A simple self‑healing loop that re‑prompts the model on failures keeps the pipeline resilient without human intervention.
The Problem
Modern Python teams often waste time turning blog insights or feature briefs into working code. They need a way to ingest real‑world content (e.g., Cloudflare blog posts), automatically generate design documents and skeleton modules, and then validate and repair the output in a single, repeatable pipeline.
Data and Sources
Data accessed on 2026-10-14. - Cloudflare Blog RSS Feed - feedparser documentation - OpenAI API reference
Loading the Data
We use feedparser to fetch and parse the RSS feed. The first five entries are enough to demo the pipeline.
import feedparser
feed = feedparser.parse('https://blog.cloudflare.com/rss/')
entries = feed.entries[:5]
The Core Logic
Below are the core functions that drive the pipeline. Each snippet focuses on a single sub‑problem.
1. Generate Design & Skeleton with LLM
We ask the model to produce a short design doc and a minimal Python module based on the post title.
def generate_code(title, content):
prompt = (f"Write a short design document for a Python module that implements the ideas in the Cloudflare blog post titled \"{title}\". Then provide a skeleton module with function stubs. The module should be named {title.replace(' ', '_').lower()}.py")
response = openai.ChatCompletion.create(
model="gpt-4",
messages=[{"role": "user", "content": prompt}],
temperature=0.0,
)
return response.choices[0].message.content
2. Validate Syntax with AST
We parse the generated code to catch syntax errors early.
def validate_syntax(code_str):
try:
ast.parse(code_str)
return True, None
except SyntaxError as e:
return False, str(e)
3. Run Unit‑Test Harness
A tiny test suite imports the generated module and checks that the expected function exists.
def run_tests(module_path, expected_func):
spec = importlib.util.spec_from_file_location("generated_mod", module_path)
mod = importlib.util.module_from_spec(spec)
spec.loader.exec_module(mod)
return hasattr(mod, expected_func)
4. Self‑Healing Loop
If syntax or tests fail, we re‑prompt the model with the error message so it can correct the code.
def heal_and_generate(title, content, error_msg):
prompt = (f"Your previous code had an error: {error_msg}. Fix the code so that it compiles and passes the tests.")
response = openai.ChatCompletion.create(
model="gpt-4",
messages=[{"role": "user", "content": prompt}],
temperature=0.0,
)
return response.choices[0].message.content
5. Persist & Publish
We write the final, validated code to disk.
def persist_code(code_str, filename):
with open(filename, "w") as f:
f.write(code_str)
Putting It Together
The main flow orchestrates the steps, handles errors, and loops until the code passes validation. Edge cases such as network failures or LLM timeouts are caught and retried.
def process_entry(entry):
title = entry.title
content = entry.summary
try:
code = generate_code(title, content)
except openai.error.OpenAIError as e:
raise RuntimeError(f"LLM request failed: {e}")
valid, err = validate_syntax(code)
if not valid:
code = heal_and_generate(title, content, err)
valid, err = validate_syntax(code)
if not valid:
raise RuntimeError(f"Syntax still failing after healing: {err}")
filename = f"{title.replace(' ', '_').lower()}.py"
persist_code(code, filename)
expected_func = "process_" + title.replace(' ', '_').lower()
if not run_tests(filename, expected_func):
code = heal_and_generate(title, content, "Missing function")
persist_code(code, filename)
return filename
Complete Script
The full runnable script combining all steps:
#!/usr/bin/env python3
import os
import ast
import importlib.util
import feedparser
import openai
from typing import Tuple
def generate_code(title: str, content: str) -> str:
prompt = (
f"Write a short design document for a Python module that implements the ideas in the Cloudflare blog post titled \"{title}\". "
f"Then provide a skeleton module with function stubs. The module should be named {title.replace(' ', '_').lower()}.py"
)
try:
response = openai.ChatCompletion.create(
model="gpt-4",
messages=[{"role": "user", "content": prompt}],
temperature=0.0,
)
except openai.error.OpenAIError as e:
raise RuntimeError(f"LLM request failed: {e}")
return response.choices[0].message.content
def heal_and_generate(title: str, content: str, error_msg: str) -> str:
prompt = f"Your previous code had an error: {error_msg}. Fix the code so that it compiles and passes the tests."
try:
response = openai.ChatCompletion.create(
model="gpt-4",
messages=[{"role": "user", "content": prompt}],
temperature=0.0,
)
except openai.error.OpenAIError as e:
raise RuntimeError(f"LLM healing failed: {e}")
return response.choices[0].message.content
def validate_syntax(code_str: str) -> Tuple[bool, str]:
try:
ast.parse(code_str)
return True, None
except SyntaxError as e:
return False, str(e)
def persist_code(code_str: str, filename: str) -> None:
with open(filename, "w") as f:
f.write(code_str)
def run_tests(module_path: str, expected_func: str) -> bool:
spec = importlib.util.spec_from_file_location("generated_mod", module_path)
mod = importlib.util.module_from_spec(spec)
try:
spec.loader.exec_module(mod)
except Exception as e:
return False
return hasattr(mod, expected_func)
def process_entry(entry) -> str:
title = entry.title
content = entry.summary
code = generate_code(title, content)
valid, err = validate_syntax(code)
if not valid:
code = heal_and_generate(title, content, err)
valid, err = validate_syntax(code)
if not valid:
raise RuntimeError(f"Syntax still failing after healing: {err}")
filename = f"{title.replace(' ', '_').lower()}.py"
persist_code(code, filename)
expected_func = "process_" + title.replace(' ', '_').lower()
if not run_tests(filename, expected_func):
code = heal_and_generate(title, content, "Missing function")
persist_code(code, filename)
return filename
def load_entries() -> list:
feed = feedparser.parse("https://blog.cloudflare.com/rss/")
return feed.entries[:5]
def main():
entries = load_entries()
for entry in entries:
try:
module_file = process_entry(entry)
print(f"Generated module: {module_file}")
except Exception as e:
print(f"Failed to process entry '{entry.title}': {e}")
if __name__ == "__main__":
main()
Expected Output
When you run the script, you’ll see lines like:
Generated module: cloudflare_blog_post_title.py
Generated module: another_blog_post_title.py
...
Each file contains a design doc comment and a skeleton function named after the post title.
Limitations and Tradeoffs
• The approach relies on the LLM’s ability to generate syntactically correct code; complex logic may still require manual review. • The unit‑test harness is minimal; real projects would need comprehensive tests for coverage and edge cases. • Re‑prompting the model on every failure can be costly if the API is rate‑limited; caching or batching could mitigate this. • The pipeline assumes the post title uniquely maps to a function name; ambiguous titles can cause name clashes.
Frequently Asked Questions
How do I avoid duplicate function names if two posts have the same title?
Append a hash of the post URL or use a namespace package. This ensures each module remains unique.
What if the LLM keeps generating code that fails the test?
Increase the prompt’s specificity, add a retry counter, or fall back to a human‑review step after a threshold.
Can I use a different LLM provider?
Yes. Replace the OpenAI calls with the corresponding SDK, ensuring the prompt format matches the new provider’s API.
How do I handle API key management securely?
Store the key in environment variables or a secrets manager, and never commit it to version control.
Is the script thread‑safe for parallel processing?
Not by default. To process multiple entries concurrently, wrap each entry in a thread or process pool and isolate the LLM calls.
What I'd Change
In a production setting I would replace the ad‑hoc unit tests with a full test suite generated from the design doc, add a CI pipeline that automatically runs the healing loop on each commit, and implement a lightweight caching layer for LLM responses to cut costs. The current script is a solid proof‑of‑concept, but scaling it to a real feature‑development workflow requires tighter integration with the team’s code review and deployment processes.