Match recall segments with story segments.
Project description
rMatch
Automated matching of recall segments to story segments.
rMatch matches each segment of a participant's recall to the corresponding segment(s) in the original story, using a large language model. Use Claude via API for best accuracy, or google/gemma-4-31B-it to run fully locally:
| Model | short text (N=21) | long text (N=19) | movie transcripts (N=138) |
|---|---|---|---|
| Claude Opus 4.6 | 0.87 | 0.8 | 0.7 |
| google/gemma-4-31B-it | 0.84 | ? | 0.67 |
Pearson r with human ratings.
Table of contents
- Table of contents
- Quickstart
- Installation
- Choosing a matcher
- Matcher options
- Output format
- API keys
- Prompts
- Batch matching from files directly
- Benchmarks
- CLI
Quickstart
from rmatch import MatcherAnthropic
matcher = MatcherAnthropic(api_key="your_api_key")
matches = matcher.match(
story_segments=["The cat sat on the mat.", "It purred softly."],
recall_segments=["A cat was on a mat."],
)
# [(0, [0])] — recall segment 0 matched story segment 0
You can also put your API key in a .env file instead of passing it directly (see API keys).
Installation
pip install rmatch # API matchers + huggingface fallback
pip install rmatch[cuda] # NVIDIA GPU (vLLM)
pip install rmatch[mac] # Apple Silicon (MLX)
Requires Python 3.12 or 3.13.
Choosing a matcher
| Matcher | When to use |
|---|---|
anthropic |
Best accuracy; needs an Anthropic API key (default model: claude-opus-4-6) |
openai |
Cloud alternative; needs an OpenAI API key (default: gpt-4.1) |
cuda |
Run locally on NVIDIA GPUs with vLLM (pip install rmatch[cuda]) |
mac |
Run locally on Apple Silicon (pip install rmatch[mac]) |
huggingface |
Portable local fallback; works on CPU, CUDA, or MPS |
matcher = get_matcher("anthropic") # or "openai", "mac", "cuda", "huggingface"
Matcher options
All keyword arguments are passed to get_matcher(name, **kwargs).
Shared across matchers
| Argument | Default | Notes |
|---|---|---|
model_name |
matcher-specific | Override the default model |
prompt |
"primary" |
See Prompts |
max_retries |
10 |
Retries when the model output cannot be parsed |
api_key |
from .env / env |
See API keys |
window_size |
5 |
Recall context window |
anthropic, openai
| Argument | Default | Notes |
|---|---|---|
dry_run |
False |
Estimate API cost without calling the API |
cuda
| Argument | Default | Notes |
|---|---|---|
max_new_tokens |
300 |
Max tokens generated per segment |
max_model_len |
90000 |
Max sequence length (prompt + generation); lower to save GPU memory |
tensor_parallel_size |
auto | Number of GPUs to use |
gpu_memory_utilization |
0.90 |
Fraction of GPU memory to use |
verbose_errors |
False |
Log raw output on parse failures |
mac
| Argument | Default | Notes |
|---|---|---|
window_size |
5 |
Recall context window |
max_new_tokens |
300 |
Max tokens generated per segment |
verbose_errors |
False |
Log raw output on parse failures |
huggingface
| Argument | Default | Notes |
|---|---|---|
window_size |
5 |
Recall context window |
quantization |
none | "4bit" or "8bit" to reduce memory |
batch_size |
64 |
Inference batch size |
max_new_tokens |
300 |
Max tokens generated per segment |
verbose_errors |
False |
Log raw output on parse failures |
matcher.match(story_segments, recall_segments)
story_segments— ordered list of story segment strings (ground truth).recall_segments— ordered list of one participant's recall segment strings.
Returns one entry per recall segment in the format of (recall_index, [story_indices]) tuples (0-based):
[
(0, [2, 5]), # recall segment 0 -> story segments 2 and 5
(1, []), # recall segment 1 -> no match
(2, [0]), # recall segment 2 -> story segment 0
]
Output format
From matcher.match, you get a list of (recall_index, [story_indices]) tuples (0-based).
API keys
Resolved in this order (first match wins):
api_keyargument in Python.envfile in the working directory- Environment variables in your shell
ANTHROPIC_API_KEY="your_api_key" # anthropic
OPENAI_API_KEY="your_api_key" # openai
HF_TOKEN="your_hf_token" # huggingface, mac, cuda (model download)
Prompts
All matchers share the same prompt templates. Pass prompt="primary_no_story" (etc.) to get_matcher. Default is primary.
| Prompt | Full story | Segmented story | Chain of thought | Notes |
|---|---|---|---|---|
primary |
yes | yes | yes | Default; most complete prompt |
primary_no_story |
no | yes | yes | For long stories that exceed the context window |
primary_no_cot |
yes | yes | no | Ablation: no chain-of-thought |
primary_no_story_no_cot |
no | yes | no | Minimal prompt |
secondary |
yes | yes | yes | Alternative wording with XML output |
Batch matching from files directly
If your story and recalls are already saved as .txt or .json files:
from pathlib import Path
from rmatch import match, MatcherCuda
matcher_gemma = MatcherCuda()
results = match(
matcher=matcher_gemma,
story_file=Path("story.txt"),
recall_file=Path("recalls/"), # file or directory of subject files
)
This loads all subjects, runs matching, and writes a JSON results file next to your recall data with the following format:
{
"matcher_name": "anthropic",
"story_name": "story",
"story_segmentation": "lines",
"recall_segmentation": "lines",
"matches": {
"sub-001": [[0, [3, 7]], [1, [12]]],
"sub-002": [[0, [1]], [1, [5, 6]]]
}
}
Each subject maps to a list of [recall_segment_id, [matched_story_segment_ids...]] pairs.
Benchmarks
Requires rBench:
git clone git@github.com:GabrielKP/rBench.git
Add to .env or environment:
BENCHMARK_ROOT="path/to/rBench"
Run:
uv run src/rmatch/evaluate.py {alice,monthiversary,memsearch}
CLI
If you prefer the command line over a Python script:
rmatch story.txt recalls/ --matcher anthropic
See rmatch --help for all options (model, prompt, window size, etc.).
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file rmatch-0.4.1.tar.gz.
File metadata
- Download URL: rmatch-0.4.1.tar.gz
- Upload date:
- Size: 278.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ca03760e2732ba5789fba465a3af668692f0d16628317f35f9014acf3eb7abf8
|
|
| MD5 |
93981e6e8f4e5253870ba3a9781fd517
|
|
| BLAKE2b-256 |
b31afd127320697a266853e4251d6670dc079023704a4e2412c1554efb605f24
|
Provenance
The following attestation bundles were made for rmatch-0.4.1.tar.gz:
Publisher:
publish.yml on GabrielKP/rMatch
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rmatch-0.4.1.tar.gz -
Subject digest:
ca03760e2732ba5789fba465a3af668692f0d16628317f35f9014acf3eb7abf8 - Sigstore transparency entry: 1573490929
- Sigstore integration time:
-
Permalink:
GabrielKP/rMatch@58ed5b18f47a3cb7c909ba26609b90f8d7923b2d -
Branch / Tag:
refs/heads/main - Owner: https://github.com/GabrielKP
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@58ed5b18f47a3cb7c909ba26609b90f8d7923b2d -
Trigger Event:
push
-
Statement type:
File details
Details for the file rmatch-0.4.1-py3-none-any.whl.
File metadata
- Download URL: rmatch-0.4.1-py3-none-any.whl
- Upload date:
- Size: 37.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
11c2bdda1164c704c79a485d5f6c5bd686f3b4052f00ebcb177a60099fbe106f
|
|
| MD5 |
e32dea3d28c8ce02d556b9e3c5bf8604
|
|
| BLAKE2b-256 |
c8b1304de7db8389e9d39b9693c728eb4053d9ebe32887341179e0b358e5992f
|
Provenance
The following attestation bundles were made for rmatch-0.4.1-py3-none-any.whl:
Publisher:
publish.yml on GabrielKP/rMatch
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rmatch-0.4.1-py3-none-any.whl -
Subject digest:
11c2bdda1164c704c79a485d5f6c5bd686f3b4052f00ebcb177a60099fbe106f - Sigstore transparency entry: 1573490944
- Sigstore integration time:
-
Permalink:
GabrielKP/rMatch@58ed5b18f47a3cb7c909ba26609b90f8d7923b2d -
Branch / Tag:
refs/heads/main - Owner: https://github.com/GabrielKP
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@58ed5b18f47a3cb7c909ba26609b90f8d7923b2d -
Trigger Event:
push
-
Statement type: