Repository navigation
Propose evaluating with Langfuse - #100
Conversation
Add ADR 0039 and amend ADR 0003, ADR 0011 and ADR 0024 with the rules it needs, in sections marked not built. Add GLOSSARY.md
2a5b5b5 to
9517869
Compare
|
@nlundee kan du komme med feedback her? |
nlundee
left a comment
There was a problem hiding this comment.
It fits well with ADR 0003 and keeps the gates in genki, which is what we want. Thumbs up for the part that only changes genki (deferred judges, one runner, calibration, judge identity with version and model, expected.criteria), so Nathalie can start on that. The part where an organisation brings its own Langfuse judge needs a few things before we accept it:
- Spend and models. Langfuse judges run on Langfuse's own model connection, so their cost skips the tenant quota and their models aren't checked against the catalog (candidate models included).
- Tenant in judge identity and labels. Two organisations with a judge of the same name would share a calibration pool, so one tenant's labels could decide whether another's judge may block publishing.
- Residency. Nothing ties the Langfuse connection or the judge model to the service's residency. The instance's judges answered from Sweden Central, so a
norwayservice could be judged there. - Access on Digdir's instance. Who creates organisations and users there, how that maps to Altinn rights, and whether a tenant connection carries live traces or only eval traces.
Two practical things: the number 0039 collides with #109 and #125, and 0040 with #117 and #125. I'd suggest 0039 for this one and that it merges before #125 (they conflict on GLOSSARY.md and the ADR index). And #116 changes the criteria judge, so it should go in first.
Would it work to mark the Langfuse part as proposed and accept the rest now?
…ng-with-langfuse # Conflicts: # docs/adr/README.md
Langfuse judges are advisory, and judges that block are proposed separately. Connections get a residency, a Langfuse judge's identity names its tenant and connection, operators create organisations on Digdir's instance, tenant connections carry eval runs only, and judge cost is reported as Langfuse prices it. The score wait runs in the eval run's lease and sink deletes are pending rows the nightly purge works through, so no durable jobs are needed.
|
Thanks, this was useful. I've taken the split with one change: instead of keeping the whole Langfuse part proposed, Langfuse judges are now advisory, and only judges that block stay proposed, in their own section of the ADR. Their scores can show in genki without deciding anything. The four points:
One more change: the score wait and the trace deletes no longer need durable jobs. The wait runs inside the eval run's background lease, as the cases do, and deletes are pending rows the nightly purge retries. So #97 and #98 no longer wait for #155 or #125. Numbering: #109 merged as 0039 shortly after your review, so this is now 0040, with main merged in. Agreed that it goes before #125, which moves to 0041 and 0042, and #117 needs a new number too. Fine with #116 going first. One overlap you didn't list: #106 also edits ADR 0024. With the judges advisory, would you accept ADR 0040 now, leaving only "Langfuse judges that block" proposed? That keeps #94 and #96 going as you suggested and lets #97 and #98 start. |
nlundee
left a comment
There was a problem hiding this comment.
Advisory first works for me, and the four points are answered: the tenant and connection in the judge identity, residency per connection starting at global, operators creating organisations, and eval runs only on a tenant's connection. Yes to accepting 0040 now with "Langfuse judges that block" left proposed. Three things before merge:
- Erasure when a connection goes away. A delete that keeps failing because the connection was removed or its secret rotated is only reported to operators, and the traces with content stay in Langfuse. A connection with pending deletes shouldn't be removable, or removing it should need the tenant's confirmation that the traces are gone, recorded in the audit log.
- The erasure check rests on unverified internals. Finding judge traces uses the undocumented
sha256(job_execution_id)rule, and the check that nothing is left filters ontarget_trace_id, which the record says isn't verified yet. Please add verifying that filter to "Before agency data goes to Digdir's instance", so a content-receiving connection isn't opened before we can show the deletes are complete. - Status line. Once accepted, the status should say it's accepted and not built, except the section on blocking judges, which stays proposed. The same goes for the README row, so nobody reads the blocking part as decided.
Smaller: the blocking section still points at #125 for durable jobs. That's now ADR 0041 in #179. #117 still uses 0040 too, so it needs a new number before either merges.
- A connection with pending deletes cannot be removed, so removing one never leaves text in the sink (ADR 0040 and ADR 0011). - Before agency data goes to Digdir's instance, the judge trace id rule and filtering by target_trace_id are verified; until then no connection there receives content. - Status lines and the index say accepted and not built, and the amended ADR 0003, 0011 and 0024 say the amendment is accepted. - The blocking section points at ADR 0041 (PR 179) for durable jobs.
|
Thanks. All three are in (status, removal blocked while deletes are pending, |
What and why
Teams already judge answers in Langfuse and want those judges' scores in genki, while genki keeps the run record and the publishing decision. This PR proposes how, as ADR 0040, and amends the three records it touches. Part of #93.
norwayservice cannot use a connection outside Norway.langfuse:<tenant>/<connection>/<name>@v<version>+<model>.evaluator@2replacesevaluator@1, so a judge may answer later.platform.judge.labelaccepts them. A Langfuse dataset can be imported once as a reviewed test set, never into holdout.expected.criteria; holdout never leaves genki.docs/adr/README.md: a row for 0040, and 0003, 0011 and 0024 marked "amendment proposed in 0040".GLOSSARY.md(new): eval run, experiment, split, holdout, judge, calibration label, advisory and feedback..gitignore: ignores.scratch/, where local planning notes live.Open before agency data goes to langfuse.digdir.cloud: whose model key the agencies' judges use, and so who pays; where the instance stores data; and the items in #93 (the 7-day lifecycle rule, the judge model deployments and a data-protection assessment).
Not in this PR: building it, in #94 to #99.
How it was tested
Read Langfuse 4.4.0's source (Prisma schema, ClickHouse migrations,
fern/API definitions, the worker's evaluation and ingestion code) and compared API changes up to 4.67.0.Read-only calls to langfuse.digdir.cloud: version 4.4.0, one organisation, two projects, 17 judges, no enterprise licence. In one project the last 100 judge traces all carry tokens and a Langfuse list-price cost (
claude-sonnet-5, about USD 0.008 per call), and each judge trace's metadata namestarget_trace_idandjob_configuration_id.A throwaway round trip against a local Langfuse 4.4.0 with genki's eval runner on six made-up cases: genki's own scores were unchanged, the judge's scores came back in 3 to 9 seconds with its identity, labels were traced back to the case and run, and nothing was sent with content off.
The same round trip showed what deleting misses: deleting a case's trace leaves the judge's trace and the raw files. Deleting the judge's trace, found from
job_execution_idon its score, removed every ClickHouse row with the text within 5 seconds.One call to each of five judge models on the judges' Azure resource answered from Sweden Central.
Filtering traces by
target_trace_idthrough Langfuse's API is still unverified, as ADR 0040 says.npx prettier --check docs/adr GLOSSARY.md.npm run checkpasses (docs only; with main merged, 4900 tests pass, 12 skipped)Checklist
packages/providers-*docs/architecture/modulesare updated if a contract, boundary or module changedNothing is built, so no rule has a test yet; ADR 0040's Consequences require one per rule when it is built, and modules change with the code.