2 November 2026
Use AI to automate the IFRS9 output
Part 1 of a series on how I use AI as a credit risk analyst.
It's no secret that AI is capable of a lot. But I must admit that the first things I used it for weren't complicated statistical models. They were the tasks I'd never had time to automate in Python myself. So the first skill I created as a credit risk analyst gets the monthly output from the IFRS 9 provisions and identifies the largest differences and the areas to focus on.
The important task on day one
Every month-end, the output needs to be extracted from the IFRS 9 model and checked:
- Is the data refreshed as of the last day of the month?
- Are all products present in the output?
- What has changed since last month in exposure and expected loss, in total and per stage?
Then you paste it into Excel, save it in the right folder, and write a few lines explaining the movements. It's focused work on a day full of other month-end deadlines. It's also easy to get wrong in a way nobody notices until the reconciliation. This simple task can take anything from 15 minutes to a few hours if the data needs extra checks or reloads.
The design principle: AI never touches the numbers
In this step, I needed to work out which parts actually need judgement and which parts just need automating. A lot of the work was copying SQL output into Excel and then going through the differences to see what needs attention this month.
| Step | Needs judgement? | Who does it |
|---|---|---|
| Extract exposure and ECL per product, currency and stage | No | Script (SQL) |
| Check freshness and missing products | No | Script |
| Compare with previous month-end and last delivered file | No | Script |
| Write and reconcile the Excel file | No | Script |
| Decide what's worth mentioning and say it clearly | Yes | AI agent |
| Decide whether to override a failed check | Yes | Human |
The script does all the calculations and writes the results to a file called summary.json. That file holds everything the AI is allowed to know about the month:
- Totals per product: exposure and ECL this month and last month, with the change in amount and in percent.
- Comparison per product, currency and stage: the same figures one level down, including rows that are new or have disappeared.
- Notable changes: the rows the script has already flagged as large, using fixed thresholds (at least 5 % change and a meaningful share of the currency total).
- Data checks: when the data was refreshed, how many rows there are for the month-end, and which products are missing or new.
- Restatements: values for last month-end that differ from the file we delivered last month.
The AI agent (GitHub Copilot, run as a scheduled automation) does four things:
- Runs the script.
- Reads the exit code and
summary.json. - Writes a 3–6 bullet comment based only on facts in
summary.json. - Sends the notification. The script combines the checks, the AI's comment and a table per product and stage into one message and posts it to Teams.
Because summary.json is saved, the notification can be rebuilt and resent later without rerunning anything. It also documents exactly what the comment was based on.
The AI never queries the database, never computes a total and never edits the file. If it got something wrong, the worst case would be a badly worded comment next to correct numbers.
A "skill" is just a very precise instruction sheet
Next, I needed to write very clear instructions for the AI, which means creating a skill. The instructions live in a SKILL.md file next to the script. It reads like a runbook for a new colleague:
- Exit code contract:
0= done, so write the comment and send the notification.2= data not ready, so report what's missing and don't force it.3= nothing to do.1= error, so report it and don't try to fix code or data. - Comment rules: use only fields from
summary.json. Never guess causes that aren't visible in the data. Judge changes relative to each product's own size, and never compare amounts in different currencies. If a product is missing, say so first. - Guardrails: don't run the build twice, never use
--forceor--overwriteunless a human asks, and never commit or change files during an automated run. - Installation guide: the skill also explains, step by step, how colleagues set up the process on their own computers: Python packages, database access, the output path and the Teams notification. Anyone in the team can install it and run it.
Writing these rules was the most valuable part of the project. Writing down what an analyst usually only knows from experience, like which checks come first and what is worth mentioning, improves the process whether or not an AI reads it.
The checks that actually matter
These are the checks that decide whether the month-end delivery is quick or turns into a long day:
- Freshness: the portfolio table must have been rebuilt after month-end and contain rows for the report date. If not, nothing is saved; I get a ⚠ notification and the scheduled job retries on business day 2 and 3.
- Missing products: a product can be missing from the output for many reasons. If it is, we are told right away: the file is still saved, and the notification shows which product is missing, last month's amounts and the last date it had data.
- Restatements: the script re-reads last month's delivered file and compares it with what the database says today. If history has changed, we need to investigate further.
- Excel output: the Excel file with the output and the comparisons is saved automatically to the given path. Before it's saved, it's read back and reconciled with the database.
What it looks like
Here's the Teams notification from the synthetic demo portfolio. The checks and the table are generated by the script; the comment is written by the AI:
✔ Provision basis 2026-10-31 saved – Product C missing
Checks
- Table rebuilt 2026-11-01T06:05:00 ✔
- 6 rows for 2026-10-31 ✔
- ⚠ Product C missing (last month 12.7 MEUR exposure, 0.2 MEUR ECL, last rows 2026-09-30)
- ⚠ 1 restated row(s) vs provision_basis_2026-09-30.xlsx
Comment
- Product C is missing for 2026-10-31 (last month 12.7 MEUR exposure, 0.2 MEUR ECL; last rows 2026-09-30). The file was saved without it.
- Product B ECL rose +8.6 % to 7.0 MUSD while exposure fell -0.9 %.
- The increase comes from stage 2: exposure +36.3 %, ECL +31.3 %.
- Product A ECL fell -2.7 % to 40.6 MEUR, exposure -2.0 %.
- Restatement: Product A stage 2 ECL at 2026-09-30 is 0.18 MEUR higher than delivered.
Note what the comment doesn't say. It doesn't claim that Product B's move into stage 2 was "driven by deteriorating macro conditions". That isn't in the data, so it isn't in the comment. The analyst adds the explanation, if one is needed.
What changed for me
- One hour of work saved on an important reporting day.
- Bugs and partial data loads are caught early. I can see exactly which product or data source didn't work as expected and dig into it directly.
- A smooth process that doesn't depend on one person. Anyone in the team can install the skill and run it.
- Robustness work took most of the effort. Most of the time went into documenting, explaining in detail and writing the instructions in the skill.
Lessons
- Split deterministic and judgement work. Put everything that has a right answer in code you can test. Give the AI the narrow job of turning a structured summary into readable text.
- Exit codes are an API for agents. A small, explicit status contract (
done/not_ready/skipped/error) made the agent's behaviour predictable. - Write the rules you'd give a new hire. "Use only these fields", "don't guess causes", "don't compare across currencies". These constraints matter more than the choice of model.
- Send the AI aggregates only. The model only sees totals per product, currency and stage, never customer-level data. That keeps the data-protection discussion short.
- Keep a human on the overrides. The agent may not
--forcepast a failed check. That decision stays with a person.
It's important to remember that you are still in charge of the data and the analysis. The AI doesn't replace your judgement, but it helps you focus on the right things.
If you're curious how the skill is written, I've shared it on GitHub with a synthetic demo portfolio: github.com/MariaKupa/ai_for_credit_analyst.