I built a lightweight research assistant that turns a pile of paper abstracts into a structured literature review with cited claims and a self-critique layer. It runs entirely against Oxlo.ai's OpenAI-compatible endpoints, so you can route different stages to different models without managing multiple providers. If you are an engineer or researcher automating literature reviews, this gives you predictable per-request pricing even when you feed the model lengthy medical or legal texts.
What you'll need
- Python 3.10 or newer.
- The OpenAI SDK:
pip install openai - An Oxlo.ai API key from https://portal.oxlo.ai
- A few sample abstracts to test with. I include hardcoded examples so you can run this immediately.
Step 1: Initialize the Oxlo.ai client
First, import the SDK and point it at Oxlo.ai. This client is a drop-in replacement, so the rest of the code looks exactly like the standard OpenAI pattern.
from openai import OpenAI
client = OpenAI(base_url="https://api.oxlo.ai/v1", api_key="YOUR_OXLO_API_KEY")
Step 2: Define the research system prompt
The system prompt locks the agent into an analytical voice and forces citations for every claim. I keep it in a constant so every stage shares the same grounding.
SYSTEM_PROMPT = """You are a research synthesis assistant. Your job is to help academics and R&D teams turn scattered paper abstracts into structured, actionable literature reviews.
Follow these rules:
1. Output findings as bullet points grouped by theme.
2. After each claim, cite the source paper by title in parentheses.
3. Flag conflicting results explicitly.
4. Suggest 2-3 concrete follow-up questions at the end.
5. Keep the tone analytical, not promotional."""
Step 3: Generate sub-questions
I split the topic into focused sub-questions before synthesis. This gives the later stages a roadmap and reduces rambling. I use Qwen 3 32B because it handles multilingual source material well if your corpus mixes English and Chinese papers.
def generate_sub_questions(topic):
user_message = (
f"Given the research topic '{topic}', generate 3 focused sub-questions "
"that would guide a literature review. Return them as a numbered list."
)
response = client.chat.completions.create(
model="qwen-3-32b",
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": user_message},
],
)
return response.choices[0].message.content
Step 4: Synthesize the literature
Next, I feed the raw abstracts into Llama 3.3 70B and ask for a grouped synthesis. Because Oxlo.ai charges per request, not per token, I can pass all three long abstracts in one shot without worrying about input length.
import json
def synthesize_papers(topic, papers):
context = json.dumps(papers, indent=2)
user_message = (
f"Topic: {topic}\n\n"
f"Papers:\n{context}\n\n"
"Synthesize these abstracts into a structured literature review. "
"Group findings by theme, cite each claim, and note any contradictions."
)
response = client.chat.completions.create(
model="llama-3.3-70b",
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": user_message},
],
)
return response.choices[0].message.content
Step 5: Critique the output
Generated text often misses methodological flaws. I add a critique stage that runs the review through DeepSeek V3.2 to surface gaps and weak causal claims before I present the results to stakeholders.
def critique_review(topic, review):
user_message = (
f"Review this literature synthesis on '{topic}':\n\n{review}\n\n"
"Identify 2-3 potential gaps, methodological biases, or areas where the conclusion "
"might be premature. Be specific."
)
response = client.chat.completions.create(
model="deepseek-v3.2",
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": user_message},
],
)
return response.choices[0].message.content
Step 6: Wire everything into a CLI
Finally, I wire the stages into a single script. The hardcoded list below stands in for whatever pipeline you use to collect abstracts, arXiv RSS, PubMed API, or Zotero export.
if __name__ == "__main__":
topic = "Transformer architectures for long-context medical records"
papers = [
{
"title": "LongFormer: The Long-Document Transformer",
"abstract": (
"We present LongFormer, a transformer model with a linear attention mechanism "
"that scales linearly with sequence length, making it efficient for long documents. "
"We evaluate on clinical note classification and achieve strong results."
),
},
{
"title": "Efficient Clinical Notes Encoding",
"abstract": (
"Electronic health records contain lengthy narrative notes. We propose a hierarchical "
"BERT architecture that segments notes and aggregates representations. "
"Our model outperforms flat baselines on mortality prediction."
),
},
{
"title": "Scaling Laws for Neural Language Models",
"abstract": (
"We study empirical scaling laws for language model performance on cross-entropy loss. "
"We find that loss scales as a power law with model size, dataset size, and training compute. "
"The results suggest larger models are sample-efficient."
),
},
]
print("=== Sub-Questions ===")
print(generate_sub_questions(topic))
print("\n=== Synthesis ===")
review = synthesize_papers(topic, papers)
print(review)
print("\n=== Critique ===")
print(critique_review(topic, review))
Run it
Save the script as research_agent.py, replace YOUR_OXLO_API_KEY, and run python research_agent.py. You should see output similar to this:
=== Sub-Questions ===
1. How do linear attention mechanisms in transformers reduce computational cost for clinical documents?
2. What hierarchical strategies exist for encoding long electronic health records?
3. How do scaling laws inform the design of clinical language models?
=== Synthesis ===
• Attention Efficiency
- Linear attention mechanisms (LongFormer) reduce complexity from quadratic to linear, enabling processing of full clinical notes without truncation (LongFormer: The Long-Document Transformer).
- Hierarchical BERT offers an alternative by segmenting notes and aggregating embeddings, which preserves local coherence (Efficient Clinical Notes Encoding).
• Predictive Performance
- Both approaches improve mortality prediction over flat baselines, though hierarchical BERT currently shows stronger empirical results on ICU benchmarks (Efficient Clinical Notes Encoding).
- Scaling laws suggest that simply increasing model size yields sample-efficiency gains, but the transfer to clinical downstream tasks remains under-explored (Scaling Laws for Neural Language Models).
• Conflicts
- LongFormer argues for global attention windows, while the hierarchical approach explicitly rejects global context in favor of segment-level encoding. The best strategy likely depends on document length and annotation density.
Follow-up questions:
1. Has anyone benchmarked LongFormer against hierarchical BERT on the same clinical corpus?
2. What is the optimal segment length for hierarchical encoding of discharge summaries?
3. Do scaling laws hold when pre-training data includes proprietary clinical text?
=== Critique ===
1. The synthesis conflates efficiency gains with predictive gains. LongFormer improves speed, but the abstract does not claim superior mortality prediction over hierarchical methods.
2. The scaling laws paper uses general-domain corpora; applying its conclusions to clinical models assumes transfer that is not demonstrated in the provided abstracts.
3. None of the papers report confidence intervals or statistical significance tests, so the claim that hierarchical BERT "outperforms" flat baselines may be overstated.
Next steps
Pipe the papers list directly from the PubMed API or Semantic Scholar instead of hardcoding JSON. You could also cache the synthesis in SQLite and run the critique layer as a nightly cron job so your team wakes up to a flagged list of weak claims in the latest literature.
Top comments (0)