DEV Community

shashank ms
shashank ms

Posted on

Harnessing LLMs for Physics Research: A Practical Guide

We are building a Physics Research Assistant that ingests a raw problem statement or paper excerpt, extracts governing equations, checks dimensional consistency, and proposes a concrete follow-up question. It is aimed at graduate students and working physicists who want to sanity-check derivations or explore new formulations without getting stuck in algebraic loops.

What you'll need

Step 1: Connect to Oxlo.ai

First, we initialize the OpenAI SDK to point at Oxlo.ai and verify that our key is live. I use llama-3.3-70b here because it is a reliable general-purpose model for quick smoke tests.

from openai import OpenAI

client = OpenAI(base_url="https://api.oxlo.ai/v1", api_key="YOUR_OXLO_API_KEY")

response = client.chat.completions.create(
    model="llama-3.3-70b",
    messages=[
        {"role": "user", "content": "State the Schwarzschild radius of a black hole in LaTeX."}
    ]
)

print(response.choices[0].message.content)

Step 2: Write the system prompt

The system prompt is the only training the agent receives. I keep it strict so the model always returns the same sections, which makes downstream parsing trivial.

SYSTEM_PROMPT = """You are a physics research assistant. Analyze the user's problem or excerpt and return a JSON object with exactly these keys:

- domain: the physics subdomain, e.g., Fluid Dynamics or Quantum Mechanics.
- equations: a list of strings, each an equation in LaTeX with a short label.
- assumptions: a list of explicit physical or mathematical assumptions.
- dimensional_check: a sentence verifying SI base-unit consistency.
- follow_up: one concrete experimental or theoretical next step.

Be precise. If an equation is approximate, state its limiting condition."""

Step 3: Extract structured analysis with JSON mode

Oxlo.ai supports OpenAI-compatible JSON mode, so we can enforce valid output structure instead of parsing free text. I switch to kimi-k2.6 here because its reasoning capabilities handle multi-constraint physics problems cleanly.

import json

# client = OpenAI(base_url="https://api.oxlo.ai/v1", api_key="YOUR_OXLO_API_KEY")

def analyze_problem(problem_text: str) -> dict:
    response = client.chat.completions.create(
        model="kimi-k2.6",
        messages=[
            {"role": "system", "content": SYSTEM_PROMPT},
            {"role": "user", "content": problem_text},
        ],
        response_format={"type": "json_object"},
        temperature=0.2,
    )
    return json.loads(response.choices[0].message.content)

test_input = (
    "A charged particle with charge q and mass m moves at speed v perpendicular "
    "to a uniform magnetic field B. Derive the radius of its circular path."
)

result = analyze_problem(test_input)
print(json.dumps(result, indent=2))

Step 4: Verify dimensional consistency

Even capable models occasionally hallucinate units. We add a second pass that audits the equations explicitly. I use deepseek-v3.2 for this verifier because it is efficient at structured reasoning tasks.

import json

# client = OpenAI(base_url="https://api.oxlo.ai/v1", api_key="YOUR_OXLO_API_KEY")

VERIFIER_PROMPT = """You are a dimensional-analysis auditor.
Given a physics domain and a list of equations, verify that the left-hand and right-hand sides carry identical SI base dimensions.

Return a JSON object with:
- validity: boolean, true only if every equation is dimensionally consistent.
- notes: a list of strings, one per equation, stating either 'Consistent' or describing the mismatch."""

def verify_dimensions(analysis: dict) -> dict:
    payload = {
        "domain": analysis.get("domain"),
        "equations": analysis.get("equations"),
    }
    response = client.chat.completions.create(
        model="deepseek-v3.2",
        messages=[
            {"role": "system", "content": VERIFIER_PROMPT},
            {"role": "user", "content": json.dumps(payload)},
        ],
        response_format={"type": "json_object"},
        temperature=0.1,
    )
    return json.loads(response.choices[0].message.content)

audit = verify_dimensions(result)
print(json.dumps(audit, indent=2))

Step 5: Assemble the CLI agent

Now we wire the two stages into a single script that accepts a problem string, prints the analysis, and flags any dimensional errors.

from openai import OpenAI
import json

client = OpenAI(base_url="https://api.oxlo.ai/v1", api_key="YOUR_OXLO_API_KEY")

SYSTEM_PROMPT = """You are a physics research assistant. Analyze the user's problem or excerpt and return a JSON object with exactly these keys:

- domain: the physics subdomain, e.g., Fluid Dynamics or Quantum Mechanics.
- equations: a list of strings, each an equation in LaTeX with a short label.
- assumptions: a list of explicit physical or mathematical assumptions.
- dimensional_check: a sentence verifying SI base-unit consistency.
- follow_up: one concrete experimental or theoretical next step.

Be precise. If an equation is approximate, state its limiting condition."""

VERIFIER_PROMPT = """You are a dimensional-analysis auditor.
Given a physics domain and a list of equations, verify that the left-hand and right-hand sides carry identical SI base dimensions.

Return a JSON object with:
- validity: boolean, true only if every equation is dimensionally consistent.
- notes: a list of strings, one per equation, stating either 'Consistent' or describing the mismatch."""

def analyze_problem(problem_text: str) -> dict:
    response = client.chat.completions.create(
        model="kimi-k2.6",
        messages=[
            {"role": "system", "content": SYSTEM_PROMPT},
            {"role": "user", "content": problem_text},
        ],
        response_format={"type": "json_object"},
        temperature=0.2,
    )
    return json.loads(response.choices[0].message.content)

def verify_dimensions(analysis: dict) -> dict:
    payload = {
        "domain": analysis.get("domain"),
        "equations": analysis.get("equations"),
    }
    response = client.chat.completions.create(
        model="deepseek-v3.2",
        messages=[
            {"role": "system", "content": VERIFIER_PROMPT},
            {"role": "user", "content": json.dumps(payload)},
        ],
        response_format={"type": "json_object"},
        temperature=0.1,
    )
    return json.loads(response.choices[0].message.content)

def physics_research_agent(problem_text: str):
    print("=== Physics Research Assistant ===\n")
    
    analysis = analyze_problem(problem_text)
    
    print(f"Domain: {analysis['domain']}\n")
    
    print("Equations:")
    for eq in analysis["equations"]:
        print(f"  - {eq}")
    print()
    
    print("Assumptions:")
    for ass in analysis["assumptions"]:
        print(f"  - {ass}")
    print()
    
    audit = verify_dimensions(analysis)
    print(f"Dimensional audit valid: {audit['validity']}")
    for note in audit["notes"]:
        print(f"  - {note}")
    print()
    
    print(f"Follow-up: {analysis['follow_up']}")

if __name__ == "__main__":
    sample = (
        "A block of mass m slides down a frictionless incline at angle theta. "
        "Find its acceleration."
    )
    physics_research_agent(sample)

Run it

Save the complete script as physics_agent.py, set your API key, and run it.

export OXLO_API_KEY="sk-oxlo.ai-..."
python physics_agent.py

Example output:

=== Physics Research Assistant ===

Domain: Classical Mechanics

Equations:
  - $a = g \sin\theta$ (acceleration along incline)
  - $N = mg \cos\theta$ (normal force)

Assumptions:
  - Frictionless surface
  - Constant gravitational acceleration $g$
  - Point mass approximation

Dimensional audit valid: True
  - Consistent: LHS [m/s^2], RHS [m/s^2]
  - Consistent: LHS [kg m/s^2], RHS [kg m/s^2]

Follow-up: Measure the actual acceleration with a motion sensor and compare against theoretical prediction for varying angles.

Next steps

Because Oxlo.ai uses flat request-based pricing, adding extra verification loops or feeding in long paper excerpts does not inflate your cost the way token-based providers do. That makes this multi-pass agent architecture practical for daily research.

To extend the agent, wire in the arXiv API so the follow_up field cites real papers, or add a SymPy layer to solve the extracted equations symbolically instead of relying on the LLM alone.

Top comments (0)