Why agents are good at this
A 10-minute log at 50 Hz is 30,000 rows across 30+ channels. People scrub through it looking for the obvious spike. An agent that can run code will filter, group and cross-reference all of it in seconds, and it doesn't get bored at row 20,000.
Filters
"Only rows where TPS > 90% and MAP > 150 kPa." This pulls just the boosted pulls out of a whole drive.
Bins
Groups every sample into the RPM × load cells of your VE or ignition table, so findings land on cells you can edit.
Explains
Writes up why it thinks something is wrong, with timestamps you can check yourself in the log viewer.
What to log
An agent can only reason about what's in the file. This is the minimum set for fuel and ignition work. Log at 20 Hz or faster for transient work, and at least 10 Hz for steady-state.
| Channel | Why the agent needs it | Priority |
|---|---|---|
| Engine speed (RPM) | X-axis of nearly every table | must |
| MAP / load / TPS | Y-axis of fuel & ignition tables; detects boost, cruise, overrun | must |
| Wideband lambda (actual) | The truth about fuelling | must |
| Lambda target | Without it the agent has to guess what you wanted | must |
| Ignition angle | Spots timing pulled by knock control or limits | must |
| Knock level / count | The most important safety channel | must |
| Closed-loop / fuel trims | Shows how hard the ECU is correcting your base map | should |
| IAT, coolant temp | Explains drift between pulls and heat soak | should |
| Injector duty / pulse width | Spots injectors running out of capacity | should |
| Fuel pressure, battery voltage | Rules out the fuel system and charging before blaming the map | should |
| Gear, vehicle speed, boost target | Context: which gear, boost control behaviour | nice |
Export the log
Every major ECU package can export a log to CSV, and CSV is what agents read best. Native binary log formats usually can't be opened without the vendor's software. The menu labels move around between versions, so the general pattern is:
- Open the log in your ECU software's log viewer (NSP, PCLink, MTune…).
- Find Export (usually under File, or a right-click on the log).
- Choose CSV and include all channels. If there's an option for units in the header, turn it on.
- Name it with context:
2026-11-02_wot-3rd_E85_18psi.csv.
No export button? A computer-use agent can open the log viewer and do the export for you. You can also screenshot the log viewer and have the agent read the graph, but that's far less precise than a CSV.
Hand it over
There are two easy ways to give an agent your log:
Chat upload
Attach the CSV in the Claude app. Claude can run code on uploaded files, so it can work on the whole log rather than skimming it. Best for one-off questions.
Claude Code / a project folder
Keep logs, your engine brief and scripts in one folder. The agent can compare this week's logs against last week's and keep notes. Best once you're tuning regularly.
Then ask a specific question. Here's a good starter prompt:
Attached is a datalog from my [ECU] on a [engine / fuel / boost]. It's a [3rd-gear WOT pull from 2,500 to 7,200 rpm]. 1. Load it with code. Tell me the row count, sample rate and channel list. 2. Find the steady full-load section (TPS > 90%) and ignore tip-in and overrun. 3. Compare actual lambda with target. Report every region off by more than 3%, with time range, RPM and MAP. 4. Check knock level and ignition angle for timing pulled by knock control. 5. Rank findings by risk to the engine. Show evidence for each. Don't suggest any changes yet. I want the diagnosis first.
Interactive example
This is our sample WOT pull (a synthetic log, free to download and try yourself). Hover to scrub through it like a log viewer. Toggle the findings to see what a well-briefed agent picks out.
3rd-gear pull · 200 kPa · E85
5,100–5,300 rpm at ~200 kPa: λ peaks at 0.857 against a 0.780 target (+9.9%). This is consistent and not transient, so it points to a VE table hole, not lag.
6,050–6,100 rpm: knock level hits 1.24 V (normal is ~0.2) and ignition drops about 3°. Investigate before adding timing anywhere near here.
The first 0.4 s at full throttle reads λ 0.97 against a 0.85 target. Look at accel enrichment / transient fuel, not the VE table.
λ 1.25 with throttle closed is overrun fuel cut. It's expected, so it's excluded from the analysis.
IAT climbs 28 → 42 °C over the pull. Normal, but compare pulls at the same IAT.
MAP holds ~200 kPa from 4,500 rpm, tapering slightly above 6,300. Boost control looks healthy.
Show data as a table (every 4th row)
Notice what it ignored. The biggest lambda error in the whole file is the overrun at 10.5 s (λ 1.25). A naive "find the leanest point" script would flag it first. A briefed agent knows closed throttle plus fuel cut means lean is expected. This is why the teaching step matters.
From findings to table changes
Once you agree with the diagnosis, ask the agent to bin the error into your table's cells. Each sample's lambda error is assigned to the nearest RPM × MAP cell. Cells with too few samples are left alone. The result is a map of where the base table is wrong, cell by cell:
Lambda error by cell (% lean of target)
Don't paste +7.8% straight into the 5,250 cell. Apply about half the correction, re-log and repeat. Lambda error isn't perfectly linear with VE. Wideband lag shifts samples between cells, and adding fuel changes knock behaviour. Ask the agent to cap any single step (we use 3–5%).
I agree with findings ② and ①. For ② only: - Bin TPS > 90% samples into my VE table axes: RPM [4000 to 7000 in 250 steps], MAP kPa [160, 180, 200]. - Shift lambda back by ~0.1 s to allow for wideband lag before binning. - For cells with ≥ 5 samples, suggest % change = (actual/target − 1) × 100 × 0.5. - Cap every change at ±4%. Output a table plus a plain-English change log. Don't touch ignition. Don't apply anything. I'll make the edits myself.
The script approach
Once you've found a workflow you like, ask the agent to save it as a script. Every future log then gets the same consistent analysis, and you can see exactly what it did. Here's a cut-down version of our free log_summary.py:
import pandas as pd df = pd.read_csv("sample-wot-pull.csv") wot = df[df["Throttle Position (%)"] > 90].copy() wot = wot.iloc[8:] # skip the tip-in transient wot["err_%"] = (wot["Lambda 1"] / wot["Lambda Target"] - 1) * 100 # flag sustained lean: > 3% off for 5+ consecutive samples lean = wot["err_%"] > 3 runs = (lean != lean.shift()).cumsum() for _, g in wot[lean].groupby(runs[lean]): if len(g) >= 5: print(f"LEAN {g['Engine Speed (rpm)'].min():.0f}-{g['Engine Speed (rpm)'].max():.0f} rpm " f"peak {g['err_%'].max():+.1f}%") knock = wot[wot["Knock Level (V)"] > 0.8] if len(knock): print(f"KNOCK at {knock['Engine Speed (rpm)'].min():.0f} rpm, peak {knock['Knock Level (V)'].max():.2f} V")
Pitfalls to teach your agent
These are the mistakes agents (and new tuners) make most often. Put them in your engine brief so the agent checks for them every time.
Wideband lag
Lambda arrives 50–200 ms after the cell that caused it. On fast transients, uncorrected lag puts the error in the wrong cell.
Closed-loop trims
If closed loop is active, lambda can look perfect while the trims are doing the work. Analyse the trims as well as lambda.
Transients & overrun
Tip-in, gear changes and fuel cut aren't VE problems. Filter them out or handle them separately.
Sensor faults
A lambda reading pinned at a limit, an IAT of −40 °C, or a flat-lined MAP means wiring, not tuning. Ask the agent to sanity-check sensors first.
Units & names
Lambda vs AFR, kPa vs psi, absolute vs gauge pressure. Say which in your channel dictionary.
Too little data
Three samples in a cell isn't evidence. Make the agent report sample counts and skip thin cells.
Seen something in a log you want to watch live? A KrispyGauge shows lambda, knock or boost on your dash as it happens.
See KrispyGauge →