| name | auto-feedback-loop |
| description | Implement self-correcting agent loops — run tests, capture failures, feed error context back to the writing agent, and repeat until pass or max-attempts reached. Inspired by Microsoft AutoGen's multi-agent reflection pattern. Use when asked about "auto-feedback loop", "self-correcting agent", "AutoGen reflection", "agent retry on failure", "tdd feedback loop", "automatic fix loop", "agent keeps fixing until tests pass", "feedback-loop script", "run-until-green", or "agent self-correction". Do NOT use for: one-shot test runs — see tdd-workflow. Do NOT use for: multi-agent task assignment — see ai-team-workflow.
|
| origin | adapted:MIT © Microsoft/AutoGen |
| license | MIT © 2026 Vũ Văn Tâm |
| version | 1.0.0 |
| compatibility | bash ≥ 5, Claude Code agent. Any test runner. |
When to Use
- Use when: an agent writes code that fails tests, needs to self-correct without human
- Use when: wiring
/tdd-cycle to run continuously until all checks pass
- Use when: building a CI gate that lets the agent fix its own failures
- Do NOT use for: infinite retry loops — always set a max attempt limit
- Do NOT use for: human-in-the-loop correction — this is fully automated
The AutoGen Reflection Pattern
Writer Agent ──► produces output
│
▼
Critic/Test Agent runs checks
│
┌─────────┴─────────┐
│ PASS │ FAIL
▼ ▼
accept extract error context
│
▼
feed error back to Writer
│
▼
Writer revises output
│
loop (max N)
feedback-loop.sh — The Core Script
#!/usr/bin/env bash
set -uo pipefail
TEST_CMD="${1:-npm test}"
MAX_ATTEMPTS="${2:-5}"
SIGNAL_DIR=".claude/signals"
mkdir -p "$SIGNAL_DIR"
attempt=1
while [[ $attempt -le $MAX_ATTEMPTS ]]; do
echo "=== Attempt $attempt / $MAX_ATTEMPTS ==="
set +e
OUTPUT=$(eval "$TEST_CMD" 2>&1)
EXIT_CODE=$?
set -e
if [[ $EXIT_CODE -eq 0 ]]; then
echo "✅ PASS on attempt $attempt"
rm -f "$SIGNAL_DIR/feedback.pending"
echo '{"status":"pass","attempt":'"$attempt"'}' > "$SIGNAL_DIR/feedback.done"
exit 0
fi
echo "❌ FAIL (exit $EXIT_CODE) — extracting error context"
jq -n \
--arg cmd \
--arg output \
--argjson attempt \
--argjson max \
>
-f
[[ -f ]]; 2;
-f
attempt=$((attempt + ))
>
1
Agent-Side: Read Feedback + Fix + Signal
FEEDBACK=$(cat .claude/signals/feedback.pending)
ERROR_OUTPUT=$(echo "$FEEDBACK" | jq -r '.error_output')
ATTEMPT=$(echo "$FEEDBACK" | jq -r '.attempt')
echo "=== Fix attempt $ATTEMPT ==="
echo "Errors to fix:"
echo "$ERROR_OUTPUT" | head -50
echo '{"agent":"code-agent","fix_applied":true,"ts":"'$(date -Iseconds)'"}' \
> .claude/signals/fix.applied
Wiring into /tdd-cycle
<!-- In a Claude Code session — invoke the loop -->
Use the feedback-loop script to run skill trigger tests until they all pass.
Max 3 attempts.
1. Run: bash core/scripts/feedback-loop.sh "bash core/tests/skills/test-skill-triggering.sh" 3
2. If FAIL: read .claude/signals/feedback.pending, fix the SKILL.md trigger phrases
3. Signal: echo '{}' > .claude/signals/fix.applied
4. Loop repeats until PASS or max attempts
Inline (No Script) — Python Pattern
MAX_ATTEMPTS = 5
for attempt in range(1, MAX_ATTEMPTS + 1):
result = run_tests()
if result.passed:
print(f"✅ Passed on attempt {attempt}")
break
error_summary = extract_errors(result.output, max_lines=30)
context = f"""
Attempt {attempt}/{MAX_ATTEMPTS} failed.
Test output:
{error_summary}
Fix the implementation to make these tests pass.
Do NOT modify test assertions.
"""
apply_fix(context)
else:
raise RuntimeError(f"Tests still failing after {MAX_ATTEMPTS} attempts")
Anti-Fake-Pass Rules
Before claiming auto-feedback loop is working, you MUST show:
Reference: gates/anti-fake-pass-gate.md