LLM Integration#

discopt includes optional LLM-powered features for model explanation, natural language formulation, infeasibility diagnosis, conversational model building, and more. These features use litellm as a universal adapter supporting 100+ LLM providers.

Important

LLM features are purely advisory — they never affect solver correctness. The solver runs identically with or without LLM features enabled. All formulations generated by LLMs pass through model.validate() before use.

Installation#

pip install discopt[llm]

This installs litellm as an optional dependency. All LLM features degrade gracefully when litellm is not installed.

Configuration#

API Key Setup#

Set the API key for your chosen provider via environment variables:

Provider

Environment Variable

Model String Example

Anthropic

ANTHROPIC_API_KEY

anthropic/claude-sonnet-4-20250514

OpenAI

OPENAI_API_KEY

openai/gpt-4o

Google

GEMINI_API_KEY

gemini/gemini-pro

Ollama (local)

(none needed)

ollama/llama3

AWS Bedrock

AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY

bedrock/anthropic.claude-3-sonnet

Azure OpenAI

AZURE_API_KEY + AZURE_API_BASE

azure/gpt-4o

Model Selection#

Models are resolved in this priority order:

  1. Explicit model= parameter on the function call

  2. DISCOPT_LLM_MODEL environment variable

  3. Default: anthropic/claude-sonnet-4-20250514

# Set your preferred model globally
export DISCOPT_LLM_MODEL="ollama/llama3"
export ANTHROPIC_API_KEY="sk-ant-..."

Features Overview#

Result Explanation (explain())#

Get a rich, context-aware explanation of any solve result:

result = model.solve()
print(result.explain(llm=True))

The explanation is status-specific:

  • Optimal: which variables are active, which constraints are binding, solution interpretation

  • Infeasible: which constraints likely conflict, suggested relaxations

  • Iteration limit: convergence analysis, parameter tuning suggestions

  • Time/node limit: B&B progress assessment, relaxation quality analysis

Natural Language Formulation (from_description())#

Create models from natural language descriptions using structured tool calling (not code generation):

import discopt.modeling as dm

model = dm.from_description(
    "Minimize total shipping cost from 3 warehouses to 5 customers. "
    "Each warehouse has limited supply and each customer has a demand "
    "that must be met.",
    data={
        "supply": [100, 150, 200],
        "demand": [80, 60, 70, 40, 50],
        "costs": np.random.rand(3, 5) * 100,
    },
)

LLM-Enhanced Solving (llm=True)#

Pass llm=True to solve() for pre-solve analysis and automatic result explanation:

result = model.solve(llm=True)
# Pre-solve warnings are logged (advisory only, never blocks solving)
# Result explanation is automatically generated
print(result.explain())

Conversational Model Building (discopt.chat())#

Build models interactively through a conversation:

import discopt

session = discopt.chat()
session.send("I have a factory with 3 machines that can produce 2 products")
session.send("Machine capacities are [100, 150, 200] hours per week")
session.send("Product profits are [50, 80] per unit")
session.send("Solve it")
session.close()

Infeasibility Diagnosis#

When a model is infeasible, get actionable diagnosis:

from discopt.llm.diagnosis import diagnose_infeasibility

result = model.solve()
if result.status == "infeasible":
    print(diagnose_infeasibility(model, result))

Solver Strategy Advisor#

Get solver parameter recommendations based on model structure:

from discopt.llm.advisor import suggest_solver_params

params = suggest_solver_params(model)
print(params["reasoning"])
result = model.solve(**{k: v for k, v in params.items() if k != "reasoning"})

Auto-Reformulation Analysis#

Identify reformulation opportunities:

from discopt.llm.reformulation import analyze_reformulations

suggestions = analyze_reformulations(model, llm=True)
for s in suggestions:
    print(f"[{s.category}] {s.description}")
    print(f"  Impact: {s.impact}")

Claude Code Skill Files#

The following Claude Code slash commands are available for discopt users:

Command

Description

/formulate

Natural language to discopt model

/diagnose

Solve result diagnostics

/reformulate

Model improvement suggestions

/explain-model

Generate mathematical documentation

/convert

Cross-solver translation (Pyomo, GAMS, AMPL, JuMP)

/benchmark-report

Analyze benchmark JSON results

Safety Guarantees#

  1. LLM outputs never affect solver math — commentary is decorative; formulations go through validate() + solve()

  2. Structured output over free-form codefrom_description() uses tool calling mapped to Model methods, not arbitrary code generation

  3. Graceful degradation — if LLM is unavailable/slow/broken, the solver runs identically without LLM features

  4. Timeouts — 5s for explanation, 30s for formulation. LLM calls never block the B&B loop

  5. No secrets in prompts — model structure sent to LLM is the same info available via model.summary()