Resonance Lattice · Docs

Resonance Lattice on Microsoft Fabric

A team-shared knowledge model. One .rlat file in OneLake, exposed as a Fabric User Data Function (UDF) — a small published Python function anyone on the workspace can call. Query it from the CLI, from Claude Code, or from a Fabric notebook, with no per-user encoder install and no .rlat copies scattered across laptops.

What this gets you

A knowledge model is a single .rlat file: your corpus (docs, code, a knowledge base) packaged for semantic search. Hosted on Fabric, that file lives once in OneLake — Fabric's shared data lake — and a UDF wraps it so every workspace member queries the same copy.

Two example notebooks ship with the integration. The demo notebook (fabric_demo_udf.ipynb) queries the UDF and writes telemetry to two Delta tables. A second notebook (fabric_analytics.ipynb) reads those tables and deploys a Direct Lake semantic model you can point Power BI at.

The whole setup takes about fifteen minutes the first time.

For what this unlocks beyond search, read the write-up: a slicer that filters by meaning, not by value — type plain language, and a 96,000-row Power BI model recomputes over the listings that match.

00 — Before you start

What you'll need

The end-to-end path:

Files/<SRC>/  --fabric_build.ipynb-->  Files/rlat/<KM>.rlat --UDF.search-->  results
                                                              |
                                                              v
                                     fabric_demo_udf.ipynb --> udf_telemetry + udf_hits Delta
                                                                     |
                                                                     v
                                                    fabric_analytics.ipynb
                                                                     |
                                                                     v
                                                rlat-analytics semantic model
01 — Build

Build a .rlat

You have three options.

A. Build inside Fabric (recommended for ongoing rebuilds)

Drop source files into Files/<SOURCE_DIR>/ in your OneLake, then run the notebooks/examples/fabric_build.ipynb notebook. The first run builds; every run after refreshes incrementally — only changed files are re-encoded. Schedule it from a Fabric Pipeline if you want it on a cron.

B. Build locally and upload

If you'd rather build from your own machine:

rlat build ./your-docs -o team-docs.rlat
rlat fabric publish-rlat ./team-docs.rlat \
    --workspace <workspace-id> \
    --lakehouse <lakehouse-id>

C. Build on a GPU for big seed corpora

For a first-time build over roughly 10,000 passages, Fabric's CPU is slow. Build on Kaggle, Colab, or a local GPU machine, upload the seed .rlat to Files/rlat/, and let fabric_build.ipynb handle subsequent refreshes inside Fabric.

Either way, the .rlat ends up at Files/rlat/<KM_NAME>.rlat. Discovery is live: the UDF lists the Files/rlat/ directory in OneLake each time, so any upload — from a notebook, a helper, or a drag-drop — shows up on the next discovery call. (The mechanism: Fabric's wrapped lakehouse client has no directory-listing method, so the runtime calls the underlying OneLake List Paths REST endpoint directly. No manifest file to maintain.)

If your workspace uses a different folder convention (Files/knowledge/, Files/data/), set RLAT_FABRIC_KM_DIR=<dirname> on the UDF item later. The default is rlat.

02 — UDF item

Create a User Data Function item

In the Fabric portal: New → User Data Function. Pick a name (for example rlat-search).

Open the item, then Manage Connections → add Lakehouse. Pick the lakehouse from the previous step and set its alias to kmLakehouse — that's the alias the UDF code references.

03 — Library & code

Add the rlat library and publish the code

Still on the UDF item: Library Management → Public libraries → Add from PyPI, search for rlat, and install it at workspace scope. Pin whatever version is current (for example ==2.1.0a13) so the UDF doesn't drift unexpectedly when a new release lands.

Then publish the code from the repo's fabric/udf/ directory. The simplest path: open fabric/udf/ in VS Code with the Microsoft Fabric extension, sign in, map it to your UDF item, and Publish. The directory holds:

fabric/udf/
  function_app.py    # search + list_kms entry points
  requirements.txt   # local-emulator fallback
04 — Test

Test the UDF

In the UDF item, select search, set kmName=<your km>, fill in query, and hit Run. You should get back JSON like {band, cold, hits[]}. The first call may take a few seconds (cold load); subsequent calls are sub-second.

If it fails

could not stat Files/rlat/<km>.rlat means the upload path or the kmLakehouse alias isn't matching. Check the upload location and Manage Connections.

05 — Query

Query from your machine

pip install 'rlat[fabric]'
rlat fabric add team=https://<your-udf-endpoint-url>

The endpoint URL is on the UDF item under Properties → Endpoint URL. The add command writes the alias to ~/.config/rlat/fabric.toml. If you're using Claude Code, it also scaffolds a .claude/skills/rlat-fabric-search/ entry so the agent sees the hosted knowledge model as a tool.

rlat search fabric://team                          # list available KMs
rlat search fabric://team/team-docs "how do I deploy?"
rlat search fabric://team/team-docs "..." --format=context

The first call prompts an Entra device-code sign-in — a URL and code printed to stderr. Sign in once; the token caches to your OS keyring and subsequent calls are silent.

06 — Telemetry

Run the demo notebook

Upload notebooks/examples/fabric_demo_udf.ipynb into your Fabric workspace and open it. Set:

Run it. You'll see retrieval results inline, plus two Delta tables appear in the bound lakehouse:

Re-run any time you want a new batch of telemetry. Both tables are append-only.

07 — Semantic model

Run the analytics notebook

Upload notebooks/examples/fabric_analytics.ipynb. Set UDF_BASE_URL to the same endpoint, leave SM_NAME as rlat-analytics, and run.

The notebook reads udf_telemetry, udf_hits, and the per-build JSON files under Files/.rlat-builds/. It materialises udf_builds, rebuilds four conformed dimension tables (dim_query, dim_source_file, dim_km, dim_date), and deploys a Direct Lake semantic model named rlat-analytics to your workspace.

It is idempotent — re-run after every batch of demo runs or build invocations, or schedule it via a Fabric Pipeline. The dimension tables rebuild from the fact tables each time.

08 — Optional

Connect Power BI

Open Power BI Desktop → Get Data → Power BI semantic models → rlat-analytics. The semantic model ships with measures grouped under 01 Activity, 02 Quality, 03 Drift, 04 Latency, 05 Coverage, and 06 Maintenance, joined to dim_query, dim_source_file, dim_km, and dim_date. Drop the measures and dimensions on the canvas to build whatever views your team cares about — top queries, refusal rate, latency percentiles, build cadence.

That's the whole loop.

How it stays fresh

The UDF caches the triple (.rlat contents, store, encoder) keyed by (kmName, OneLake last_modified). Every search call stats the OneLake .rlat (cheap); when its last_modified changes, the cache evicts and rebuilds from the new bytes on the next call. Re-upload the .rlat after a rlat build or rlat refresh — or after the build notebook runs — and the next query sees fresh results, with no UDF redeploy.

Up to eight distinct (kmName, mtime) tuples are cached at once; older entries fall out, least-recently-used first.

Cold-start latency

The first call after a UDF container recycle pays for:

A few seconds cold, sub-second warm — the same figures you see when testing the UDF in section 04. The UDF returns a cold flag so callers can tell which they paid for.

Authentication

Two paths, in priority order:

  1. Service-principal env vars. If AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, and AZURE_TENANT_ID are all set, a ClientSecretCredential is used silently. This is the right choice for CI or shared machines.
  2. Device-code flow (default). rlat search prints a URL and a code to stderr. Open the URL, paste the code. The token caches to your OS keyring (libsecret, Keychain, or Credential Manager). It works inside Claude Code: the prompt comes back through the Bash tool's stdout, you complete the browser flow, and the agent's tool call resolves with the search results.

The token cache name is rlat-fabric. The scope is https://analysis.windows.net/powerbi/api/.default — the Power BI scope, used to invoke UDFs, not the Fabric API scope (which is for item CRUD).

Encoder distribution

Each .rlat records the encoder revision — a Hugging Face commit SHA — it was built with. At UDF cold-start, the runtime reads that revision from the .rlat metadata and downloads the matching ONNX cache from tenfingers/rlat-gte-modernbert-base-onnx, revision-pinned. No per-workspace encoder upload.

If your tenant blocks egress to huggingface.co, set RLAT_FABRIC_ENCODER_SOURCE=onelake on the UDF environment and stage the encoder cache to Files/rlat-encoders/<revision>.tar.zst instead.

What's server-side vs client-side

TaskServer (UDF)Client (notebook / CLI)
Single-shot retrievalyescalls into UDF
Discovery (list KMs)yescalls into UDF
Build / incremental refreshyes (fabric_build.ipynb in Fabric, or rlat build locally + rlat fabric publish-rlat)
Multi-hop deep-searchyes (drives the loop, calls the UDF for each hop)
Compare between hosted KMsnot yet — both KMs need to be local

Troubleshooting

See also

Three example notebooks ship in the repo's notebooks/examples/ directory: fabric_build.ipynb (runs the build/refresh against the OneLake filesystem mount, schedulable from a Fabric Pipeline), fabric_demo_udf.ipynb (queries the UDF and writes the two Delta tables), and fabric_analytics.ipynb (deploys the Direct Lake semantic model).

Where next