The Problem

Training AI agents with reinforcement learning normally means rewriting agent code to fit a training harness, and coupling yourself to one framework. This repo's pitch is the opposite: keep your existing agent (LangChain, OpenAI SDK, AutoGen, CrewAI, or plain Python), wrap it with minimal changes, and run RL, prompt optimization, or SFT against it. The fork here tracks Microsoft's agent-lightning project.

What This Does

The core is the Python package agentlightning/, which handles the full training loop: algorithms (agentlightning/algorithm/apo/apo.py), rollout storage (agentlightning/store/), execution strategies (client/server and in-process), LLM proxying (agentlightning/llm_proxy.py), and an OpenTelemetry-based tracing layer (agentlightning/utils/otel.py, agentlightning/types/tracer.py). A React/TypeScript dashboard (dashboard/src/App.tsx) visualizes training runs.

This is a collection of five projects, not one codebase: the agentlightning package (93 code files), the dashboard (80), examples (66, covering frameworks like Azure, Tinker, RAG, APO), scripts (9), and contrib (5). The README documents a vLLM integration for returning token IDs, which matters for agent RL.

How It Is Wired

Execution starts in agentlightning/algorithm/apo/apo.py at run (reaches 402 functions) or agentlightning/execution/base.py at execute (reaches 380). The traced paths show how quickly control leaves the process: dispatch in llm_proxy.py reaches requests.get in one hop; execute reaches openai.OpenAI directly. run reaches finetune via os.unlink (filesystem). Storage is database-backed through agentlightning/store/collection/base.py.

The blast radius is concentrated: enqueue_rollout is called from 118 places, start_rollout from 82, query_spans from 56. The hub modules are agentlightning/types/__init__.py (84 dependents), agentlightning/__init__.py (46), and agentlightning/store/base.py (39). All three sit inside circular import cycles — 66 modules total are in cycles. Changing store/base.py (665 lines) or llm_proxy.py (deep nesting at depth 9) ripples widely. client_server.py owns the network effects (OTLP traces endpoint, outbound calls); store/collection/base.py owns database access; llm_proxy.py owns file I/O and model calls.

How To Use It

Installation is documented in the README:

pip install agentlightning

examples/ contains per-framework setups, each with .env.example files (e.g. examples/azure/.env.example) for credentials. The agentlightning/verl/__main__.py entry point suggests a CLI for the verl backend. The dashboard builds via npm (dashboard/package.json, vite.config.mjs). The README links a full documentation site.

Real-World Use

The README's own case studies are the best evidence: training an agent to write and self-correct SQL with RL, and the DeepWerewolf multi-agent game case. A typical workflow: define your agent in any framework, instrument it with the lightning tracer, configure a rollout store, and run the APO or RL algorithm from agentlightning/algorithm/ against a vLLM or OpenAI-compatible endpoint.

Code Health & Issues

Static analysis found 216 findings (86 high, 128 medium, 2 low). The high-severity items: 31 import-cycle members (notably types/__init__.py, __init__.py, store/base.py), 4 hub modules with 39–84 dependents, 6 oversized files (665 lines in store/base.py), and 10 cases of deep nesting (depth 9 in llm_proxy.py). Medium: 9 cases of broad except clauses in llm_proxy.py, tracer/base.py, and store/client_server.py.

Three SDLC gaps, all medium: no Dependabot/Renovate configured despite two manifests; docker/Dockerfile.dev uses an unpinned base image (ghcr.io/astral-sh/uv:python3.12-bookworm); uv.lock is 12.3MB and should move to LFS. Tests and CI are present and clean of committed secrets.

The Bottom Line

A serious, well-tested agent-training framework with real production integrations (vLLM, Azure, OpenTelemetry) and a healthy test/CI baseline. The cost is architectural: hub modules in circular imports make core changes high-risk, and the package is broad enough that onboarding requires the docs. Use it if you need framework-agnostic agent RL and can tolerate the coupling in store/ and types/.