Overview
This workflow implements a LangGraph-based generator-critic loop where the generator produces content and the critic agent verifies factual claims by searching Scavio for current data. When the critic finds claims that contradict live search results, it sends the content back to the generator with correction instructions. The loop continues until all factual claims pass verification or the maximum iteration count is reached.
Trigger
On each content generation request
Schedule
On-demand per content generation request
Workflow Steps
Generator produces initial content
The generator agent creates content based on the user's prompt and initial context.
Critic extracts factual claims
The critic agent identifies specific factual claims in the generated content (prices, dates, features, etc.).
Verify claims via Scavio search
For each factual claim, query Scavio to find current data and compare against the claim.
Score and return feedback
Score each claim as verified, contradicted, or unverifiable. Return feedback to generator if contradictions found.
Generator revises or finalize
If contradictions exist, generator revises. If all claims pass, output the verified content.
Python Implementation
import requests
from datetime import datetime
API_KEY = "your_scavio_api_key"
def verify_claim(claim: str, search_query: str) -> dict:
"""Critic tool: verify a factual claim against live data."""
res = requests.post(
"https://api.scavio.dev/api/v1/search",
headers={"x-api-key": API_KEY},
json={"platform": "google", "query": search_query, "ai_overview": True},
timeout=15,
)
res.raise_for_status()
data = res.json()
evidence = []
if data.get("ai_overview"):
evidence.append({"source": "ai_overview", "text": data["ai_overview"]["text"][:300]})
for r in data.get("organic", [])[:3]:
evidence.append({"source": r.get("link", ""), "text": r.get("snippet", "")})
return {"claim": claim, "query": search_query, "evidence": evidence}
def critic_loop(claims: list[dict], max_iterations: int = 3) -> dict:
"""Run critic verification loop on a list of claims."""
results = []
for claim in claims:
verification = verify_claim(claim["text"], claim["search_query"])
results.append(verification)
return {
"verified_at": datetime.utcnow().isoformat(),
"claims_checked": len(claims),
"results": results,
}
def run():
claims = [
{"text": "SerpAPI costs $50/month for 5,000 searches", "search_query": "SerpAPI pricing 2026"},
{"text": "Tavily offers 1,000 free searches per month", "search_query": "Tavily free tier 2026"},
{"text": "Scavio API costs $0.005 per query", "search_query": "Scavio API pricing 2026"},
]
result = critic_loop(claims)
print(f"Critic loop: {result['claims_checked']} claims checked")
for r in result["results"]:
print(f" Claim: {r['claim'][:60]}...")
print(f" Evidence: {len(r['evidence'])} sources found")
if __name__ == "__main__":
run()JavaScript Implementation
const API_KEY = "your_scavio_api_key";
async function verifyClaim(claim, searchQuery) {
const res = await fetch("https://api.scavio.dev/api/v1/search", {
method: "POST",
headers: { "x-api-key": API_KEY, "content-type": "application/json" },
body: JSON.stringify({ platform: "google", query: searchQuery, ai_overview: true }),
});
const data = await res.json();
const evidence = [];
if (data.ai_overview) evidence.push({ source: "ai_overview", text: data.ai_overview.text.slice(0, 300) });
for (const r of (data.organic ?? []).slice(0, 3)) evidence.push({ source: r.link ?? "", text: r.snippet ?? "" });
return { claim, evidence };
}
const claims = [
{ text: "SerpAPI costs $50/month", query: "SerpAPI pricing 2026" },
{ text: "Tavily offers 1,000 free searches", query: "Tavily free tier 2026" },
];
for (const c of claims) {
const r = await verifyClaim(c.text, c.query);
console.log(`Claim: ${r.claim} -> ${r.evidence.length} evidence sources`);
}Platforms Used
Web search with knowledge graph, PAA, and AI overviews