agent-failure-debugger 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- agent_failure_debugger-0.2.0/LICENSE +21 -0
- agent_failure_debugger-0.2.0/PKG-INFO +522 -0
- agent_failure_debugger-0.2.0/README.md +502 -0
- agent_failure_debugger-0.2.0/pyproject.toml +32 -0
- agent_failure_debugger-0.2.0/setup.cfg +4 -0
- agent_failure_debugger-0.2.0/src/agent_failure_debugger/__init__.py +117 -0
- agent_failure_debugger-0.2.0/src/agent_failure_debugger/abstraction.py +380 -0
- agent_failure_debugger-0.2.0/src/agent_failure_debugger/auto_apply.py +510 -0
- agent_failure_debugger-0.2.0/src/agent_failure_debugger/autofix.py +222 -0
- agent_failure_debugger-0.2.0/src/agent_failure_debugger/causal_resolver.py +143 -0
- agent_failure_debugger-0.2.0/src/agent_failure_debugger/config.py +96 -0
- agent_failure_debugger-0.2.0/src/agent_failure_debugger/decision_support.py +416 -0
- agent_failure_debugger-0.2.0/src/agent_failure_debugger/diagnose.py +210 -0
- agent_failure_debugger-0.2.0/src/agent_failure_debugger/evaluate_fix.py +334 -0
- agent_failure_debugger-0.2.0/src/agent_failure_debugger/execute_fix.py +364 -0
- agent_failure_debugger-0.2.0/src/agent_failure_debugger/execution_quality.py +395 -0
- agent_failure_debugger-0.2.0/src/agent_failure_debugger/explain.py +61 -0
- agent_failure_debugger-0.2.0/src/agent_failure_debugger/explainer.py +598 -0
- agent_failure_debugger-0.2.0/src/agent_failure_debugger/fix_templates.py +242 -0
- agent_failure_debugger-0.2.0/src/agent_failure_debugger/formatter.py +259 -0
- agent_failure_debugger-0.2.0/src/agent_failure_debugger/graph_loader.py +44 -0
- agent_failure_debugger-0.2.0/src/agent_failure_debugger/labels.py +196 -0
- agent_failure_debugger-0.2.0/src/agent_failure_debugger/main.py +39 -0
- agent_failure_debugger-0.2.0/src/agent_failure_debugger/pipeline.py +385 -0
- agent_failure_debugger-0.2.0/src/agent_failure_debugger/pipeline_post_apply.py +97 -0
- agent_failure_debugger-0.2.0/src/agent_failure_debugger/pipeline_summary.py +62 -0
- agent_failure_debugger-0.2.0/src/agent_failure_debugger/policy_loader.py +96 -0
- agent_failure_debugger-0.2.0/src/agent_failure_debugger/reliability.py +785 -0
- agent_failure_debugger-0.2.0/src/agent_failure_debugger/templates/system_prompt.txt +22 -0
- agent_failure_debugger-0.2.0/src/agent_failure_debugger/templates/user_prompt.txt +8 -0
- agent_failure_debugger-0.2.0/src/agent_failure_debugger.egg-info/PKG-INFO +522 -0
- agent_failure_debugger-0.2.0/src/agent_failure_debugger.egg-info/SOURCES.txt +34 -0
- agent_failure_debugger-0.2.0/src/agent_failure_debugger.egg-info/dependency_links.txt +1 -0
- agent_failure_debugger-0.2.0/src/agent_failure_debugger.egg-info/entry_points.txt +2 -0
- agent_failure_debugger-0.2.0/src/agent_failure_debugger.egg-info/requires.txt +13 -0
- agent_failure_debugger-0.2.0/src/agent_failure_debugger.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025-2026 llm-failure-atlas contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,522 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: agent-failure-debugger
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Diagnose why your LLM agent failed. Deterministic causal analysis with fix generation.
|
|
5
|
+
License: MIT
|
|
6
|
+
Project-URL: Homepage, https://github.com/kiyoshisasano/agent-failure-debugger
|
|
7
|
+
Requires-Python: >=3.11
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Requires-Dist: llm-failure-atlas>=0.1.0
|
|
11
|
+
Provides-Extra: langchain
|
|
12
|
+
Requires-Dist: langchain-core<1.0,>=0.3; extra == "langchain"
|
|
13
|
+
Provides-Extra: langsmith
|
|
14
|
+
Requires-Dist: langsmith>=0.1; extra == "langsmith"
|
|
15
|
+
Provides-Extra: crewai
|
|
16
|
+
Requires-Dist: crewai>=0.50; extra == "crewai"
|
|
17
|
+
Provides-Extra: all
|
|
18
|
+
Requires-Dist: agent-failure-debugger[crewai,langchain,langsmith]; extra == "all"
|
|
19
|
+
Dynamic: license-file
|
|
20
|
+
|
|
21
|
+
# agent-failure-debugger
|
|
22
|
+
|
|
23
|
+
[](https://pypi.org/project/agent-failure-debugger/)
|
|
24
|
+
[](https://pypi.org/project/agent-failure-debugger/)
|
|
25
|
+
|
|
26
|
+
Diagnoses agent execution behavior — not just *what* failed, but *why*, and whether execution quality is healthy, degraded, or failed. Deterministic causal analysis with fix generation.
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pip install agent-failure-debugger
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
```python
|
|
33
|
+
from agent_failure_debugger import diagnose
|
|
34
|
+
|
|
35
|
+
result = diagnose(raw_log, adapter="langchain")
|
|
36
|
+
print(result["summary"]["execution_quality"]["status"]) # healthy / degraded / failed
|
|
37
|
+
print(result["explanation"]["context_summary"])
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Use the Debugger
|
|
43
|
+
|
|
44
|
+
Use this when:
|
|
45
|
+
- An agent gives confident answers without data
|
|
46
|
+
- Tools return empty results or errors
|
|
47
|
+
- Behavior changes between runs and you need to understand why
|
|
48
|
+
|
|
49
|
+
Choose your entry point:
|
|
50
|
+
|
|
51
|
+
- **During development** — use Atlas [`watch()`](https://github.com/kiyoshisasano/llm-failure-atlas) to observe live executions and diagnose behavior as it happens
|
|
52
|
+
- **After failures** — use `diagnose()` to analyze a raw log or exported trace after the fact
|
|
53
|
+
|
|
54
|
+
Atlas detects failures; the debugger explains why they happened and proposes fixes. You can use Atlas alone for detection, but diagnosis requires the debugger.
|
|
55
|
+
|
|
56
|
+
### From a raw log (simplest)
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
from agent_failure_debugger import diagnose
|
|
60
|
+
|
|
61
|
+
# Example: LangChain agent trace (no tool data)
|
|
62
|
+
raw_log = {
|
|
63
|
+
"steps": [
|
|
64
|
+
{"type": "llm", "output": "The Q4 revenue was $4.2M, up 31% year-over-year."}
|
|
65
|
+
],
|
|
66
|
+
"tool_calls": [],
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
result = diagnose(raw_log, adapter="langchain")
|
|
70
|
+
|
|
71
|
+
print(result["summary"])
|
|
72
|
+
# → {'root_cause': '...', 'failure_count': ..., 'gate_mode': '...', ...}
|
|
73
|
+
|
|
74
|
+
print(result["explanation"]["context_summary"])
|
|
75
|
+
# → describes what happened and why
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
`raw_log` is a loosely structured dict — its format depends on the source. The adapter normalizes it into the telemetry format Atlas expects. The more structured and complete the log (especially tool calls and outputs), the more accurate the diagnosis. Minimal logs may result in incomplete or degraded analysis.
|
|
79
|
+
|
|
80
|
+
One function: adapt → detect (via Atlas) → diagnose → explain. Atlas is installed automatically as a dependency. Output quality depends entirely on the input log — incomplete telemetry will silently degrade detection and diagnosis.
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
**Which adapter to use:**
|
|
85
|
+
|
|
86
|
+
Adapters normalize raw logs from different sources into Atlas's telemetry format.
|
|
87
|
+
|
|
88
|
+
| Adapter | Use for |
|
|
89
|
+
|---|---|
|
|
90
|
+
| `langchain` | LangChain / LangGraph traces |
|
|
91
|
+
| `langsmith` | LangSmith run-tree exports |
|
|
92
|
+
| `crewai` | CrewAI crew execution logs |
|
|
93
|
+
| `redis_help_demo` | [Redis workshop](https://github.com/bhavana-giri/movie-recommender-rag-semantic-cache-workshop) Help Center |
|
|
94
|
+
|
|
95
|
+
If unsure: use `"langchain"` for agent traces, `"redis_help_demo"` for the Redis workshop demo. For the JSON format each adapter expects, see [Adapter Formats](https://github.com/kiyoshisasano/llm-failure-atlas/blob/main/docs/adapter_formats.md).
|
|
96
|
+
|
|
97
|
+
Note: `crewai` and `redis_help_demo` adapters do not yet produce `state` or `grounding` telemetry. Some failure patterns (e.g., `agent_tool_call_loop`) may not fire through these adapters. See the [Atlas adapter verification status](https://github.com/kiyoshisasano/llm-failure-atlas#tested-with-real-agents) for details.
|
|
98
|
+
|
|
99
|
+
**CLI:**
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
# From a raw log (full pipeline)
|
|
103
|
+
python -m agent_failure_debugger.diagnose log.json --adapter langchain
|
|
104
|
+
|
|
105
|
+
# From matcher output (diagnosis only)
|
|
106
|
+
python -m agent_failure_debugger.main matcher_output.json
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### From matcher output (direct)
|
|
110
|
+
|
|
111
|
+
```python
|
|
112
|
+
from agent_failure_debugger.pipeline import run_pipeline
|
|
113
|
+
|
|
114
|
+
result = run_pipeline(
|
|
115
|
+
matcher_output,
|
|
116
|
+
use_learning=True,
|
|
117
|
+
include_explanation=True,
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
print(result["summary"]["root_cause"])
|
|
121
|
+
print(result["explanation"]["interpretation"])
|
|
122
|
+
print(result["explanation"]["risk"]["level"])
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Use this when you already have matcher output, or when building a custom adapter.
|
|
126
|
+
|
|
127
|
+
### From a live agent (via Atlas watch)
|
|
128
|
+
|
|
129
|
+
Atlas's `watch()` wraps a LangGraph agent and runs the debugger pipeline on completion. It is a separate entry point from `diagnose()` — both produce the same pipeline output but from different starting points: `watch()` captures telemetry from a live execution, while `diagnose()` accepts a raw log after the fact.
|
|
130
|
+
|
|
131
|
+
If you use [llm-failure-atlas](https://github.com/kiyoshisasano/llm-failure-atlas) for detection, `watch()` runs the debugger automatically:
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
from llm_failure_atlas.adapters.callback_handler import watch
|
|
135
|
+
|
|
136
|
+
graph = watch(workflow.compile(), auto_diagnose=True, auto_pipeline=True)
|
|
137
|
+
result = graph.invoke({"messages": [...]})
|
|
138
|
+
# → detection + debugger pipeline + explanation printed automatically
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
For a copy-paste example without an API key, see [Reproducible Examples](#reproducible-examples) below.
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## Quick Start
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
pip install agent-failure-debugger
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### From Python (copy-paste-run)
|
|
152
|
+
|
|
153
|
+
```python
|
|
154
|
+
from agent_failure_debugger import diagnose
|
|
155
|
+
|
|
156
|
+
raw_log = {
|
|
157
|
+
"inputs": {"query": "Change my flight to tomorrow morning"},
|
|
158
|
+
"outputs": {"response": "I've found several hotels near the airport for you."},
|
|
159
|
+
"steps": [
|
|
160
|
+
{"type": "llm", "outputs": {"text": "Let me check available flights."}},
|
|
161
|
+
{"type": "tool", "name": "search_flights", "inputs": {"date": "2025-03-20"},
|
|
162
|
+
"outputs": {"flights": []}, "error": None},
|
|
163
|
+
{"type": "tool", "name": "search_flights", "inputs": {"date": "2025-03-20"},
|
|
164
|
+
"outputs": {"flights": []}, "error": None},
|
|
165
|
+
{"type": "tool", "name": "search_flights", "inputs": {"date": "2025-03-20"},
|
|
166
|
+
"outputs": {"flights": []}, "error": None},
|
|
167
|
+
{"type": "llm", "outputs": {"text": "I've found several hotels near the airport."}}
|
|
168
|
+
],
|
|
169
|
+
"feedback": {"user_correction": "I asked about flights, not hotels."}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
result = diagnose(raw_log, adapter="langchain")
|
|
173
|
+
print(result["summary"]["root_cause"])
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### From matcher output (advanced)
|
|
177
|
+
|
|
178
|
+
If you already have matcher output (e.g., from a custom integration):
|
|
179
|
+
|
|
180
|
+
```python
|
|
181
|
+
from agent_failure_debugger.pipeline import run_pipeline
|
|
182
|
+
|
|
183
|
+
result = run_pipeline(matcher_output, use_learning=True)
|
|
184
|
+
print(result["summary"])
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
See [Quick Start Guide](docs/quickstart.md) for more usage patterns including `watch()` and direct telemetry.
|
|
188
|
+
|
|
189
|
+
## Common Mistakes
|
|
190
|
+
|
|
191
|
+
| Problem | Cause | Fix |
|
|
192
|
+
|---|---|---|
|
|
193
|
+
| "0 failures detected" | Adapter got insufficient data | Provide complete trace with tool calls |
|
|
194
|
+
| Wrong results | Input format doesn't match adapter | See [Adapter Formats](https://github.com/kiyoshisasano/llm-failure-atlas/blob/main/docs/adapter_formats.md) |
|
|
195
|
+
| Pattern doesn't fire | Adapter doesn't produce required fields | Check [Adapter Coverage](docs/limitations_faq.md#adapter-coverage) |
|
|
196
|
+
|
|
197
|
+
**⚠ No error is raised for wrong inputs.** The system silently returns zero failures if the adapter cannot extract signals.
|
|
198
|
+
|
|
199
|
+
## This Tool Cannot
|
|
200
|
+
|
|
201
|
+
- Verify factual correctness of agent responses
|
|
202
|
+
- Detect semantic mismatch (requires embeddings)
|
|
203
|
+
- Analyze multi-agent system coordination
|
|
204
|
+
|
|
205
|
+
See [Limitations & FAQ](docs/limitations_faq.md) for details.
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## API Details
|
|
210
|
+
|
|
211
|
+
### Execution quality
|
|
212
|
+
|
|
213
|
+
Every `diagnose()` and `run_pipeline()` result now includes execution quality assessment in the summary:
|
|
214
|
+
|
|
215
|
+
```python
|
|
216
|
+
eq = result["summary"]["execution_quality"]
|
|
217
|
+
print(eq["status"]) # "healthy" | "degraded" | "failed"
|
|
218
|
+
print(eq["termination"]["mode"]) # "normal" | "silent_exit" | "error_exit" | "partial_exit" | "unknown"
|
|
219
|
+
print(eq["indicators"]) # list of degradation concerns (empty if healthy)
|
|
220
|
+
print(eq["summary"]) # one-line human-readable assessment
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
- **healthy** — no significant issues detected
|
|
224
|
+
- **degraded** — output may have been produced but quality indicators are weak (low alignment, weak grounding, unmodeled failures)
|
|
225
|
+
- **failed** — execution did not produce usable output (silent exit or error)
|
|
226
|
+
|
|
227
|
+
Execution quality uses existing telemetry and diagnosis results. No new matcher patterns are added.
|
|
228
|
+
|
|
229
|
+
### Multi-run analysis
|
|
230
|
+
|
|
231
|
+
```python
|
|
232
|
+
from agent_failure_debugger import compare_runs, diff_runs
|
|
233
|
+
|
|
234
|
+
# Step 1: Is the agent stable across runs?
|
|
235
|
+
stability = compare_runs(all_run_results)
|
|
236
|
+
print(stability["stability"]["root_cause_agreement"]) # 1.0 = fully stable
|
|
237
|
+
print(stability["interpretation"])
|
|
238
|
+
|
|
239
|
+
# Step 2: What separates success from failure?
|
|
240
|
+
diff = diff_runs(success_runs, failure_runs)
|
|
241
|
+
print(diff["hypothesis"])
|
|
242
|
+
print(diff["failure_set_diff"]["failure_only"]) # patterns only in failures
|
|
243
|
+
print(diff["causal_path_diff"]) # where paths diverge
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
`compare_runs()` measures stability — whether the same task produces consistent diagnoses across runs. `diff_runs()` identifies divergence — what structural differences separate successful runs from failed ones.
|
|
247
|
+
|
|
248
|
+
### Enhanced explanation
|
|
249
|
+
|
|
250
|
+
```python
|
|
251
|
+
expl = result["explanation"]
|
|
252
|
+
print(expl["context_summary"]) # what happened
|
|
253
|
+
print(expl["interpretation"]) # why it happened
|
|
254
|
+
print(expl["risk"]["level"]) # HIGH / MEDIUM / LOW
|
|
255
|
+
print(expl["recommendation"]) # what to do
|
|
256
|
+
print(expl["observation"]) # signal coverage info
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
When observation coverage is low (many signals were not observed), the risk level is automatically raised and the interpretation notes that the diagnosis may be incomplete.
|
|
260
|
+
|
|
261
|
+
CLI: `python -m agent_failure_debugger.explain --enhanced debugger_output.json`
|
|
262
|
+
|
|
263
|
+
### Individual steps
|
|
264
|
+
|
|
265
|
+
```python
|
|
266
|
+
from agent_failure_debugger.pipeline import run_diagnosis, run_fix
|
|
267
|
+
|
|
268
|
+
diag = run_diagnosis(matcher_output)
|
|
269
|
+
fix_result = run_fix(diag, use_learning=True, top_k=2)
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### External evaluation
|
|
273
|
+
|
|
274
|
+
```python
|
|
275
|
+
def my_staging_test(bundle):
|
|
276
|
+
fixes = bundle["autofix"]["recommended_fixes"]
|
|
277
|
+
# apply fixes in your staging env
|
|
278
|
+
return {
|
|
279
|
+
"success": True,
|
|
280
|
+
"failure_count": 0,
|
|
281
|
+
"root": None,
|
|
282
|
+
"has_hard_regression": False,
|
|
283
|
+
"notes": "passed staging tests",
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
result = run_pipeline(
|
|
287
|
+
matcher_output,
|
|
288
|
+
auto_apply=True,
|
|
289
|
+
evaluation_runner=my_staging_test,
|
|
290
|
+
)
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
If `evaluation_runner` is not provided, the built-in counterfactual simulation is used. If the runner raises an exception, the pipeline falls back to `staged_review` deterministically.
|
|
294
|
+
|
|
295
|
+
For real-world interpretation examples — including before/after fix effects — see [Applied Debugging Examples](https://github.com/kiyoshisasano/llm-failure-atlas/blob/main/docs/applied_debugging_examples.md) and [Operational Playbook](https://github.com/kiyoshisasano/llm-failure-atlas/blob/main/docs/operational_playbook.md) in the Atlas repository.
|
|
296
|
+
|
|
297
|
+
---
|
|
298
|
+
|
|
299
|
+
## Input Format
|
|
300
|
+
|
|
301
|
+
A JSON array of failure results from the matcher. Each entry needs `failure_id`, `diagnosed`, and `confidence`:
|
|
302
|
+
|
|
303
|
+
```json
|
|
304
|
+
[
|
|
305
|
+
{
|
|
306
|
+
"failure_id": "premature_model_commitment",
|
|
307
|
+
"diagnosed": true,
|
|
308
|
+
"confidence": 0.7,
|
|
309
|
+
"signals": {
|
|
310
|
+
"ambiguity_without_clarification": true,
|
|
311
|
+
"assumption_persistence_after_correction": true
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
]
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
The pipeline validates input at entry and rejects malformed data with clear error messages.
|
|
318
|
+
|
|
319
|
+
---
|
|
320
|
+
|
|
321
|
+
## Output Format
|
|
322
|
+
|
|
323
|
+
```json
|
|
324
|
+
{
|
|
325
|
+
"root_candidates": ["premature_model_commitment"],
|
|
326
|
+
"root_ranking": [{"id": "premature_model_commitment", "score": 0.85}],
|
|
327
|
+
"failures": [
|
|
328
|
+
{"id": "premature_model_commitment", "confidence": 0.7},
|
|
329
|
+
{"id": "semantic_cache_intent_bleeding", "confidence": 0.7,
|
|
330
|
+
"caused_by": ["premature_model_commitment"]}
|
|
331
|
+
],
|
|
332
|
+
"causal_paths": [
|
|
333
|
+
["premature_model_commitment", "semantic_cache_intent_bleeding", "rag_retrieval_drift"]
|
|
334
|
+
]
|
|
335
|
+
}
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
---
|
|
339
|
+
|
|
340
|
+
## Auto-Apply Gate
|
|
341
|
+
|
|
342
|
+
| Score | Mode | Behavior |
|
|
343
|
+
|---|---|---|
|
|
344
|
+
| >= 0.85 | `auto_apply` | Apply, evaluate, keep or rollback |
|
|
345
|
+
| 0.65-0.85 | `staged_review` | Write to patches/, await human approval |
|
|
346
|
+
| < 0.65 | `proposal_only` | Present fix proposal only |
|
|
347
|
+
|
|
348
|
+
Hard blockers (force proposal_only regardless of score):
|
|
349
|
+
- `safety != "high"`
|
|
350
|
+
- `review_required == true`
|
|
351
|
+
- `fix_type == "workflow_patch"`
|
|
352
|
+
- Execution plan has conflicts or failed validation
|
|
353
|
+
- `grounding_gap_not_acknowledged` signal active
|
|
354
|
+
|
|
355
|
+
## Fix Safety
|
|
356
|
+
|
|
357
|
+
Fixes are generated from predefined templates, not learned behavior. They are deterministic and reproducible, but not guaranteed to be correct — some fixes may introduce regressions in complex workflows.
|
|
358
|
+
|
|
359
|
+
Safety mechanisms: the confidence gate prevents low-evidence fixes from auto-apply, hard blockers prevent unsafe categories of changes, the evaluation runner validates fixes before acceptance, and rollback is triggered automatically if evaluation fails.
|
|
360
|
+
|
|
361
|
+
Always review or evaluate fixes before applying in production environments.
|
|
362
|
+
|
|
363
|
+
## Automation Guidance
|
|
364
|
+
|
|
365
|
+
| Environment | Recommended mode | Notes |
|
|
366
|
+
|---|---|---|
|
|
367
|
+
| Development | `auto_apply` | Iterate quickly, evaluate fixes automatically |
|
|
368
|
+
| Staging | `staged_review` | Use evaluation_runner to validate before applying |
|
|
369
|
+
| Production | `proposal_only` | Human approval required, avoid auto_apply |
|
|
370
|
+
|
|
371
|
+
The debugger is designed for assisted decision-making, not fully autonomous system modification.
|
|
372
|
+
|
|
373
|
+
---
|
|
374
|
+
|
|
375
|
+
## Pipeline Steps
|
|
376
|
+
|
|
377
|
+
```
|
|
378
|
+
matcher_output.json
|
|
379
|
+
→ pipeline.py (orchestrator)
|
|
380
|
+
├ main.py causal resolution + root ranking
|
|
381
|
+
├ abstraction.py top-k path selection (optional)
|
|
382
|
+
├ decision_support.py priority scoring + action plan
|
|
383
|
+
├ autofix.py fix selection + patch generation
|
|
384
|
+
├ auto_apply.py confidence gate + reason_code
|
|
385
|
+
├ pipeline_post_apply.py evaluation runner or counterfactual
|
|
386
|
+
├ pipeline_summary.py summary + execution quality assessment
|
|
387
|
+
├ execution_quality.py healthy/degraded/failed classification
|
|
388
|
+
└ explainer.py explanation (context + risk + observation)
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
---
|
|
392
|
+
|
|
393
|
+
## File Structure
|
|
394
|
+
|
|
395
|
+
| File | Role |
|
|
396
|
+
|---|---|
|
|
397
|
+
| `diagnose.py` | Single entry point: raw log → full diagnosis |
|
|
398
|
+
| `pipeline.py` | Pipeline orchestrator (from matcher output) |
|
|
399
|
+
| `pipeline_post_apply.py` | Post-apply evaluation (runner + counterfactual) |
|
|
400
|
+
| `pipeline_summary.py` | Summary generation |
|
|
401
|
+
| `main.py` | CLI entry point for diagnosis only (from matcher output) |
|
|
402
|
+
| `config.py` | Paths, weights, thresholds |
|
|
403
|
+
| `graph_loader.py` | Load failure_graph.yaml |
|
|
404
|
+
| `causal_resolver.py` | Normalize, find roots, build paths, rank |
|
|
405
|
+
| `formatter.py` | Path scoring + conflict resolution |
|
|
406
|
+
| `labels.py` | SIGNAL_MAP (34) + FAILURE_MAP (17) |
|
|
407
|
+
| `explainer.py` | Deterministic + optional LLM explanation |
|
|
408
|
+
| `explain.py` | CLI for explanation generation (`--enhanced`, `--deterministic`) |
|
|
409
|
+
| `decision_support.py` | Failure to action mapping |
|
|
410
|
+
| `autofix.py` | Fix selection + patch generation |
|
|
411
|
+
| `fix_templates.py` | 17 fix definitions (14 domain + 3 meta) |
|
|
412
|
+
| `auto_apply.py` | Confidence gate + auto-apply |
|
|
413
|
+
| `execute_fix.py` | Dependency ordering + staged apply |
|
|
414
|
+
| `evaluate_fix.py` | Counterfactual simulation |
|
|
415
|
+
| `policy_loader.py` | Read-only learning store access |
|
|
416
|
+
| `reliability.py` | Cross-run stability and differential analysis |
|
|
417
|
+
| `execution_quality.py` | Single-run execution behavior assessment |
|
|
418
|
+
|
|
419
|
+
---
|
|
420
|
+
|
|
421
|
+
## Graph Source
|
|
422
|
+
|
|
423
|
+
The canonical `failure_graph.yaml` is bundled in the `llm-failure-atlas` package. The debugger loads the graph automatically via the Atlas package.
|
|
424
|
+
|
|
425
|
+
```python
|
|
426
|
+
from agent_failure_debugger.config import GRAPH_PATH
|
|
427
|
+
print(GRAPH_PATH) # shows which graph is loaded
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
---
|
|
431
|
+
|
|
432
|
+
## Configuration
|
|
433
|
+
|
|
434
|
+
| Variable | Default | Description |
|
|
435
|
+
|---|---|---|
|
|
436
|
+
| `LLM_FAILURE_ATLAS_GRAPH_PATH` | Bundled in package | Override graph location |
|
|
437
|
+
| `LLM_FAILURE_ATLAS_PATTERNS_DIR` | Bundled in package | Override patterns directory |
|
|
438
|
+
| `LLM_FAILURE_ATLAS_LEARNING_DIR` | Bundled in package | Override learning store |
|
|
439
|
+
|
|
440
|
+
All scoring weights and gate thresholds are in `config.py`.
|
|
441
|
+
|
|
442
|
+
---
|
|
443
|
+
|
|
444
|
+
## Design Principles
|
|
445
|
+
|
|
446
|
+
- **Deterministic** — same matcher output, same root cause, same fix, same gate decision
|
|
447
|
+
- **Graph is for interpretation only** — not used during detection
|
|
448
|
+
- **Signal names are contracts** — no redefinition allowed
|
|
449
|
+
- **Learning is suggestion-only** — structure is never auto-modified
|
|
450
|
+
- **Fail fast on invalid input** — pipeline validates at entry
|
|
451
|
+
- **Enhanced explanations** — `include_explanation=True` adds context, interpretation, risk, and recommendation
|
|
452
|
+
|
|
453
|
+
---
|
|
454
|
+
|
|
455
|
+
## Related Repositories
|
|
456
|
+
|
|
457
|
+
| Repository | Role |
|
|
458
|
+
|---|---|
|
|
459
|
+
| [llm-failure-atlas](https://github.com/kiyoshisasano/llm-failure-atlas) | Failure patterns, causal graph, matcher, adapters |
|
|
460
|
+
| [agent-pld-metrics](https://github.com/kiyoshisasano/agent-pld-metrics) | Behavioral stability framework (PLD) |
|
|
461
|
+
|
|
462
|
+
---
|
|
463
|
+
|
|
464
|
+
## Reproducible Examples
|
|
465
|
+
|
|
466
|
+
**Try without an API key** (copy-paste-run):
|
|
467
|
+
|
|
468
|
+
```bash
|
|
469
|
+
pip install agent-failure-debugger[langchain] langgraph
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
```python
|
|
473
|
+
from langchain_core.language_models import FakeListLLM
|
|
474
|
+
from langchain_core.messages import HumanMessage, AIMessage
|
|
475
|
+
from langgraph.graph import StateGraph, MessagesState, START, END
|
|
476
|
+
from llm_failure_atlas.adapters.callback_handler import watch
|
|
477
|
+
|
|
478
|
+
llm = FakeListLLM(responses=[
|
|
479
|
+
"The revenue was $4.2M in Q3 2024, representing 31% year-over-year "
|
|
480
|
+
"growth. The Asia-Pacific segment contributed 45% of total revenue. "
|
|
481
|
+
"Operating margins expanded to 19.3% across all regions."
|
|
482
|
+
])
|
|
483
|
+
|
|
484
|
+
def agent(state: MessagesState):
|
|
485
|
+
return {"messages": [AIMessage(content=llm.invoke(state["messages"]))]}
|
|
486
|
+
|
|
487
|
+
workflow = StateGraph(MessagesState)
|
|
488
|
+
workflow.add_node("agent", agent)
|
|
489
|
+
workflow.add_edge(START, "agent")
|
|
490
|
+
workflow.add_edge("agent", END)
|
|
491
|
+
|
|
492
|
+
graph = watch(workflow.compile(), auto_diagnose=True)
|
|
493
|
+
graph.invoke({"messages": [HumanMessage(content="What was Q3 revenue?")]})
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
**Regression test examples:**
|
|
497
|
+
|
|
498
|
+
10 examples in [llm-failure-atlas](https://github.com/kiyoshisasano/llm-failure-atlas) under `examples/`. Each contains `log.json`, `matcher_output.json`, and `expected_debugger_output.json`.
|
|
499
|
+
|
|
500
|
+
```bash
|
|
501
|
+
python -m agent_failure_debugger.main matcher_output.json
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
---
|
|
505
|
+
|
|
506
|
+
## Internals
|
|
507
|
+
|
|
508
|
+
**Root ranking formula:**
|
|
509
|
+
|
|
510
|
+
```
|
|
511
|
+
score = 0.5 * confidence + 0.3 * normalized_downstream + 0.2 * (1 - normalized_depth)
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
More downstream impact ranks higher, even with lower confidence. This reflects causal priority, not detection confidence alone.
|
|
515
|
+
|
|
516
|
+
This tool implements a single control step within the [PLD](https://github.com/kiyoshisasano/agent-pld-metrics) loop: post-incident causal analysis and intervention decision.
|
|
517
|
+
|
|
518
|
+
---
|
|
519
|
+
|
|
520
|
+
## License
|
|
521
|
+
|
|
522
|
+
MIT License. See [LICENSE](LICENSE).
|