cookbook · Decider 1 · RAG passage filtering
Drop retrieved passages that do not help
Retrieved passages often include content that does not answer the question, and sending all of it to your LLM wastes context and can mislead the model. This recipe filters passages before retrieval results reach the LLM by asking one noul per passage whether it helps answer the question. Passages scoring low are dropped; the rest proceed.
The retrieved passages
- Refunds are issued to the original payment method. Card refunds usually appear within 5-10 business days, depending on your bank.
- You can change your billing address from Settings > Billing at any time.
- Our refund policy covers annual plans cancelled within 30 days of purchase.
- Invoices are emailed on the first day of each billing cycle.
Request
POST /v1/systemone, documented in the Decider 1 reference.
curl https://meragpt.com/v1/systemone \
-H "Authorization: Bearer $MERAGPT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "sd-1",
"state": {
"question": "How long do refunds take to reach my card?",
"passage": "Refunds are issued to the original payment method. Card refunds usually appear within 5-10 business days, depending on your bank."
},
"questions": {
"relevant": {
"type": "noul",
"instructions": "Does this passage help answer the question?"
}
}
}'What came back
The real output from running this recipe, unedited.
{
"Refunds are issued to the original payment method. Card refunds usually appear within 5-10 business days, depending on your bank.": {
"type": "noul",
"noul": 0.9004
},
"You can change your billing address from Settings > Billing at any time.": {
"type": "noul",
"noul": 0.0318
},
"Our refund policy covers annual plans cancelled within 30 days of purchase.": {
"type": "noul",
"noul": 0.1431
},
"Invoices are emailed on the first day of each billing cycle.": {
"type": "noul",
"noul": 0.0755
}
}Python
import os, requests
API = "https://meragpt.com/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['MERAGPT_API_KEY']}"}
from concurrent.futures import ThreadPoolExecutor
QUESTION = "How long do refunds take to reach my card?"
passages = [
"Refunds are issued to the original payment method. Card refunds usually appear within 5-10 business days, depending on your bank.",
"You can change your billing address from Settings > Billing at any time.",
"Our refund policy covers annual plans cancelled within 30 days of purchase.",
"Invoices are emailed on the first day of each billing cycle."
]
def relevance(passage: str) -> float:
body = {
"model": "sd-1",
"state": {"question": QUESTION, "passage": passage},
"questions": {"relevant": {"type": "noul", "instructions": "Does this passage help answer the question?"}},
}
r = requests.post(f"{API}/systemone", headers=HEADERS, json=body).json()
return r["answers"]["relevant"]["noul"]
# one call per passage, run in parallel
with ThreadPoolExecutor(8) as pool:
scores = list(pool.map(relevance, passages))
keep = [p for p, s in zip(passages, scores) if s >= 0.5]
TypeScript
const API = "https://meragpt.com/v1";
const headers = {
Authorization: `Bearer ${process.env.MERAGPT_API_KEY}`,
"Content-Type": "application/json",
};
const QUESTION = "How long do refunds take to reach my card?";
const passages: string[] = [
"Refunds are issued to the original payment method. Card refunds usually appear within 5-10 business days, depending on your bank.",
"You can change your billing address from Settings > Billing at any time.",
"Our refund policy covers annual plans cancelled within 30 days of purchase.",
"Invoices are emailed on the first day of each billing cycle."
];
async function relevance(passage: string): Promise<number> {
const body = {
model: "sd-1",
state: { question: QUESTION, passage },
questions: { relevant: { type: "noul", instructions: "Does this passage help answer the question?" } },
};
const r = await fetch(`${API}/systemone`, { method: "POST", headers, body: JSON.stringify(body) }).then((res) => res.json());
return r.answers.relevant.noul;
}
// one call per passage, run in parallel
const scores = await Promise.all(passages.map(relevance));
const keep = passages.filter((_, i) => scores[i] >= 0.5);
When to trust it
Trust the scores as a relevance filter, not a measure of passage quality. For example, a passage stating card refunds take 5-10 business days scores 0.90 for that question, while billing address, refund policy window, and invoice timing passages score 0.03, 0.14, and 0.08. Send one call per passage, not all passages in one state, because answers about several items in one state can influence each other.
Try it without code in the playground, or see more Decider 1 recipes: route a support email in one call, act only when the model is sure, flag a phishing email, hold a reply that promises money, pick an agent's first tool, ask many questions in one call.