We are building an autonomous research agent that ingests paper abstracts, identifies methodological gaps, and generates a runnable Python prototype to test a hypothesis. It is designed for ML engineers and research scientists who want to automate the literature-to-code pipeline. The entire stack runs against Oxlo.ai's OpenAI-compatible endpoints with flat per-request pricing, so long context windows do not inflate cost.
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
Step 1: Configure the Oxlo.ai client
I instantiate the client once and reuse it across all pipeline phases. I pull the API key from an environment variable so I never commit secrets to git.
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.oxlo.ai/v1",
api_key=os.getenv("OXLO_API_KEY", "YOUR_OXLO_API_KEY")
)
Step 2: Ingest and synthesize literature
I feed the agent three raw abstracts and ask it to extract methodological gaps. I use qwen-3-32b here because it handles dense reasoning over academic text reliably.
PAPER_ABSTRACTS = """
1. Attention Is All You Need (Vaswani et al., 2017): We propose the Transformer, dispensing with recurrence and instead relying entirely on an attention mechanism.
2. LoRA (Hu et al., 2021): We freeze pretrained model weights and inject trainable rank decomposition matrices into each layer, greatly reducing downstream trainable parameters.
3. Mamba (Gu & Dao, 2023): We introduce a selection mechanism to structured state space models, allowing them to focus on relevant context while scaling linearly in sequence length.
"""
LITERATURE_PROMPT = (
"You are a research analyst. Read the following paper abstracts and identify "
"the key methodological gaps and open problems. Return a concise bullet list."
)
response = client.chat.completions.create(
model="qwen-3-32b",
messages=[
{"role": "system", "content": LITERATURE_PROMPT},
{"role": "user", "content": PAPER_ABSTRACTS},
],
)
synthesis = response.choices[0].message.content
print(synthesis)
Step 3: Generate testable hypotheses
From the synthesis, the model generates three concrete, falsifiable hypotheses labeled H1, H2, and H3. I route this phase through llama-3.3-70b for structured, general-purpose reasoning.
HYPOTHESIS_PROMPT = (
"You are a principal scientist. Based on the research synthesis below, generate "
"three concrete, falsifiable hypotheses that could be tested with a Python prototype. "
"Label them H1, H2, H3."
)
response = client.chat.completions.create(
model="llama-3.3-70b",
messages=[
{"role": "system", "content": HYPOTHESIS_PROMPT},
{"role": "user", "content": synthesis},
],
)
hypotheses = response.choices[0].message.content
print(hypotheses)
Step 4: Draft a Python prototype
I take the first hypothesis and ask for a minimal Python script that could validate it. I choose deepseek-v3.2 because it is tuned for code generation.
CODE_PROMPT = (
"You are an ML engineer. Take the first hypothesis (H1) and implement a minimal, "
"runnable Python script to test it. Use only standard libraries plus NumPy. "
"Include comments explaining each step."
)
response = client.chat.completions.create(
model="deepseek-v3.2",
messages=[
{"role": "system", "content": CODE_PROMPT},
{"role": "user", "content": hypotheses},
],
)
prototype = response.choices[0].message.content
print(prototype)
Step 5: Assemble the research agent
Finally, I bundle the three phases into a single agent class governed by a persistent system prompt. The prompt enforces the workflow and discourages hallucinated citations.
SYSTEM_PROMPT = (
"You are an autonomous research assistant running on Oxlo.ai. "
"Your workflow has three strict phases: "
"1) Synthesize provided literature into methodological gaps. "
"2) Generate exactly three testable hypotheses labeled H1, H2, H3. "
"3) Implement H1 as a minimal Python prototype with comments. "
"Always cite sources implicitly by referring to the paper titles. "
"Never hallucinate external URLs."
)
class ResearchAgent:
def __init__(self, client):
self.client = client
def run(self, abstracts: str) -> dict:
# Phase 1: Synthesis
r1 = self.client.chat.completions.create(
model="qwen-3-32b",
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": f"Literature:\n{abstracts}"},
],
)
synthesis = r1.choices[0].message.content
# Phase 2: Hypotheses
r2 = self.client.chat.completions.create(
model="llama-3.3-70b",
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": f"Synthesis:\n{synthesis}"},
],
)
hypotheses = r2.choices[0].message.content
# Phase 3: Prototype
r3 = self.client.chat.completions.create(
model="deepseek-v3.2",
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": f"Hypotheses:\n{hypotheses}\n\nImplement H1."},
],
)
prototype = r3.choices[0].message.content
return {
"synthesis": synthesis,
"hypotheses": hypotheses,
"prototype": prototype,
}
Run it
Here is how I invoke the finished agent on a live topic, along with representative output.
if __name__ == "__main__":
agent = ResearchAgent(client)
abstracts = """
1. Attention Is All You Need: Proposes the Transformer relying solely on attention.
2. LoRA: Freezes weights and injects trainable low-rank matrices.
3. Mamba: Selective state spaces for linear-time sequence modeling.
"""
result = agent.run(abstracts)
print("=== SYNTHESIS ===")
print(result["synthesis"])
print("\n=== HYPOTHESES ===")
print(result["hypotheses"])
print("\n=== PROTOTYPE ===")
print(result["prototype"])
=== SYNTHESIS ===
- Transformers scale quadratically with sequence length, creating a bottleneck for long-document modeling.
- LoRA reduces trainable parameters but leaves the inference memory footprint unchanged.
- Mamba offers linear-time sequence modeling yet lacks the mature hardware optimization and ecosystem attention mechanisms enjoy.
=== HYPOTHESES ===
H1: A hybrid attention-SSM layer that sparsely applies self-attention only on top-k ranked tokens from a Mamba hidden state will reduce FLOPs while preserving perplexity on long sequences.
H2: Applying LoRA adapters to the Mamba projection matrices instead of full fine-tuning will match downstream task performance with 10x fewer trainable parameters.
H3: Pre-training a small Transformer-Mamba mixture-of-experts on 1B tokens will outperform a dense Transformer of equal parameter count on code completion.
=== PROTOTYPE ===
```python
import numpy as np
# Simulate token importance scores from a Mamba hidden state
np.random.seed(42)
seq_len = 1024
hidden_dim = 64
# Generate random hidden states and compute L2 norm as proxy importance
hidden = np.random.randn(seq_len, hidden_dim)
scores = np.linalg.norm(hidden, axis=1)
top_k_idx = np.argsort(scores)[-64:] # Select top-64 tokens
# Sparse attention mask: only attend to top-k tokens
mask = np.zeros((seq_len, seq_len))
mask[:, top_k_idx] = 1.0
print("Active attention indices:", top_k_idx[:5])
print("Mask density:", mask.sum() / mask.size)
```
Wrap-up and next steps
This agent is already useful for brainstorming, but it is still a prototype. Two concrete upgrades I plan to ship next:
- Live retrieval: Wire in the arXiv API and Oxlo.ai embeddings endpoint so the agent pulls fresh abstracts instead of hand-pasted text.
- Execution loop: Run the generated Python script, capture stdout, and feed errors back to the model for a self-correcting iteration cycle.
Both phases stay on Oxlo.ai, so the flat per-request pricing keeps costs predictable even as the context grows. For details, see https://oxlo.ai/pricing.
Top comments (0)