Use Sciverse for Citation Grounding in Scientific Q&A
RAGAgentAdvanced
Use Sciverse for Citation Grounding in Scientific Q&A
Find verifiable literature sources for each LLM statement and reduce hallucinations
Scenario
Developers building high-trust scientific Q&A systems need to fact-check each generated claim by retrieving and verifying supporting literature.
Estimated calls
~10-25 API calls
Tools
agentic-searchcontentPipeline
LLM 生成草稿→ 拆句→ agentic-search(逐句)→ content(验证原文)→ 标注引用
Input example
Draft answer: "Protein language models can predict variant effects and support structure prediction." Need: verify each claim with literature evidence.
Output example
Grounded answer: Claim 1: supported by doc_id=..., quote=... Claim 2: supported by doc_id=..., quote=... Unsupported claims are marked as "not verified".
Agent Prompt example
You are a citation grounding assistant. Split draft answers into claims, retrieve evidence for each claim, verify against source text, and output a final answer with citations.Implementation steps
Step 1: Set up the environment
Configure token and HTTP client
!pip install httpx
import os
os.environ["SCIVERSE_API_TOKEN"] = "sv-your-token-here" # 替换为你的真实值Step 2: Split the draft and search per sentence
Break the answer into atomic claims and search for each claim
import os
import httpx
BASE = "https://api.sciverse.space"
TOKEN = os.environ["SCIVERSE_API_TOKEN"]
HEADERS = {"Authorization": f"Bearer {TOKEN}"}
def split_claims(draft: str) -> list:
"""将草稿拆分为独立论点句子"""
sentences = [s.strip() for s in draft.split("。") if s.strip()]
return [s for s in sentences if len(s) > 10]
async def search_evidence(claim: str):
"""对单个论点检索支持证据"""
async with httpx.AsyncClient(timeout=30) as client:
resp = await client.post(
f"{BASE}/agentic-search",
headers=HEADERS,
json={"query": claim, "top_k": 5}
)
resp.raise_for_status()
return (resp.json().get("hits") or [])
draft = "mRNA 疫苗使用可电离脂质纳米颗粒(iLNP)包裹 mRNA。其中 MC3 是最广泛使用的可电离脂质。LNP 的粒径通常在 80-100nm。"
claims = split_claims(draft)
print(f"Split into {len(claims)} claims")
Step 3: Verify source text with content
Read original context to verify whether evidence supports the claim
async def verify_with_content(hit: dict, claim: str) -> dict:
"""读取原文验证证据是否真正支持论点"""
async with httpx.AsyncClient(timeout=30) as client:
resp = await client.get(
f"{BASE}/content",
headers=HEADERS,
params={"doc_id": hit["doc_id"], "offset": hit.get("offset", 0), "limit": 1000}
)
resp.raise_for_status()
data = resp.json()
# 检查原文中是否包含与论点相关的关键词
text = data["text"].lower()
claim_keywords = [w for w in claim.lower().split() if len(w) > 3]
match_count = sum(1 for kw in claim_keywords if kw in text)
match_ratio = match_count / max(len(claim_keywords), 1)
return {
"doc_id": hit["doc_id"],
"offset": hit.get("offset", 0),
"quote": data["text"][:150],
"match_ratio": match_ratio,
"verified": match_ratio >= 0.3 and hit["score"] >= 0.7
}
async def ground_claims(claims: list):
results = []
for claim in claims:
hits = await search_evidence(claim)
if hits and hits[0]["score"] >= 0.6:
verification = await verify_with_content(hits[0], claim)
results.append({"claim": claim, **verification})
else:
results.append({"claim": claim, "verified": False, "doc_id": None})
status = "\\u2713" if results[-1]["verified"] else "\\u2717"
print(f" {status} {claim[:50]}...")
return results
results = await ground_claims(claims)
Step 4: Generate the final cited answer
Return only verified claims with citations and mark unsupported ones
def build_grounded_answer(results: list) -> dict:
citations = []
grounded_parts = []
unverified = []
for r in results:
if r["verified"]:
cite_id = len(citations) + 1
citations.append({
"id": cite_id,
"doc_id": r["doc_id"],
"offset": r.get("offset", 0),
"quote": r.get("quote", ""),
"verified": True
})
grounded_parts.append(f"{r['claim']} [{cite_id}]")
else:
grounded_parts.append(f"{r['claim']} [unverified]")
unverified.append(r["claim"])
return {
"grounded_answer": "\\u3002".join(grounded_parts) + "\\u3002",
"citations": citations,
"unverified_claims": unverified
}
final = build_grounded_answer(results)
print(f"\
Grounded answer:\
{final['grounded_answer']}")
print(f"\
Citations: {len(final['citations'])}")
print(f"Unverified: {len(final['unverified_claims'])}")
for c in final["citations"]:
print(f" [{c['id']}] {c['doc_id']} (offset: {c['offset']})")
Notes
- Use atomic claims; broad sentences are harder to verify.
- Citation grounding is stricter than ordinary RAG.
- A retrieved paper is not enough; verify the exact source text.
- Mark unsupported or weakly supported claims explicitly.
- Keep quotes short and traceable.
- Avoid merging evidence from unrelated papers into one citation.
FAQ
这个案例解决什么问题?
为 AI 生成的科学回答补充论文证据,降低无来源结论。
如何判断证据是否支持回答?
需要读取 content 上下文,并保留原文 quote 供人工或模型复核。
是否可以自动给每句话加引用?
可以辅助生成,但引用是否充分仍需根据原文上下文判断。
不支持的 claim 怎么处理?
应标记为未找到充分证据,而不是强行附会引用。
Next steps
Need an API key?
Create one in Console > Tokens.The same API key works for enabled Sciverse, DianShi, and Skills capabilities, with starter quota available according to account permissions.