Back
maxim is an ai observability and evaluation platform — logging, tracing, evals, test runs, prompt management, and simulations for teams building on LLMs. i have worked across the whole stack — the main platform (next.js monorepo on Nx), and both Python and JS/TS SDKs.
maintains internal bifrost instance that powers maxim's ai layer. it allows us to do things like:
external human raters on log repositories, a variable catalog for evaluator suggestions, and the human-eval sheet/table UI (annotation forms, comparison views, xlsx export for human evaluations in test runs).
consolidated the logging surface into a single logging API, added a LogLine class in the JS SDK for manually pushing logs, and fixed a nasty bug where multiple Maxim SDK instances on the same API key stepped on each other.
added the LogLine apis to collect log lines and push them to the logging apis. this gives client ownership of the log export process.
kept both SDKs in lockstep — prompt id / prompt version passthrough, variable mapping, withLogger/with_logger for logging on prompt runs, streaming fixes for the agno integration (python), and making sure a broken log-repository connection doesn't block logger creation.
built out a big chunk of the public API surface — prompt tools, prompt versions v2, prompt deployment by version number, prompt partials, and model / evaluator management apis. Also shipped variable mapping for SDK test runs and prompt-version fallback logic when creating new versions.
i joined early, before stable v1 and i've stayed on the core team since, shipping across pretty much every layer — provider integrations, the compat plugin, observability and helm configs. this is what I've mostly worked on:
added elevenLabs (speech + transcription), groq STT/TTS, and most recently deepseek as a first-class provider.
this is the layer that makes "any client, any provider" actually work. it roughly does this:
cache_control handling for bedrock, conversion of role developer, flattening of namespaced tools for non-openai providers.reworked Ollama and SGLang from a single provider-level base URL to per-key URLs, so you can load-balance across multiple local instances serving different models.
Same idea later for OTEL: went from one collector to a profiles array so traces can fan out to multiple destinations (Jaeger + Datadog + whatever else) at once.
fixed streaming cost/usage attribution more than once (vLLM's --skip-pipeline output, image generation/edit streaming, virtual-key-scoped pricing overrides not propagating through the streaming accumulator context).
tightened helm schema
some of my prs:
--skip-pipelinethinking blocks that made Claude Code choke on Anthropicnetwork_config if per-key URL isn't setcachePoint/cache_control for models/providers that don't support prompt cachingdeveloper→system/user role handling across Anthropic, Bedrock, Geminifalse; now default truereasoning_effortreasoningConfig field naming + message sanitization for non-Anthropic Bedrock modelsreasoning when tools are present but the model doesn't support both togetherreasoning_content for Cerebras (unsupported field)tool_choice: required is setcontent_type forwarding + file_id references