lmnr

lmnr-aiApache-2.0活跃维护

专为 AI Agent 打造的开源可观测性平台,提供链路追踪、评估和数据分析,帮开发者定位 Agent 运行中的问题并持续优化效果。

Laminar - open-source observability platform purpose-built for AI agents. YC S24.

v0.3.4发布于 2026-11-10 08:54 UTC3,480star +3 / 7 天262fork同步于 2026-11-10 23:41 UTC

怎么上手

由 README 提炼,执行前请确认
git clone https://github.com/lmnr-ai/lmnr
cd lmnr
docker compose up -d
硬件要求按 README 说明

README 未说明具体硬件要求;自托管通过 docker compose 启动整套服务,未提及 GPU 或显存需求。

有 Docker 镜像
下载:源码 zip·GitHub Releases(安装包)本站不镜像安装包

项目说明

由 README 自动翻译提炼

面向 AI Agent 的开源可观测平台,用一行代码接入追踪、信号告警与评测

专为 AI Agent 打造的开源可观测性平台,提供链路追踪、评估和数据分析,帮开发者定位 Agent 运行中的问题并持续优化效果。

核心能力

  • 一行代码自动追踪 Vercel AI SDK、LangChain、OpenAI 等调用
  • 用自然语言描述 Agent 异常行为,命中后推送 Slack 告警
  • 提供可扩展的评测 SDK 与 CLI,支持本地或 CI/CD 运行
  • 支持用 SQL 查询 trace、span、指标与事件,并可接入编码 Agent
  • Rust 实现,20x trace 压缩与实时 trace 查看引擎

容易踩的坑

自托管后需在 SDK 中正确配置 baseUrl 和端口,UI 默认在 http://localhost:5667;前端 AI 功能(chat-with-trace、SQL-with-AI)需在 .env 中额外配置 LLM provider;自托管默认收集匿名遥测,需设 LAMINAR_TELEMETRY_DISABLED=true 关闭

内容由模型根据 README 生成,可能不完整或不准确,以官方文档为准。看原文 README

最近发版

5 个版本v0.3.4
  1. v0.3.4最新正式版2026-11-10 · 2026-11-10 08:54 UTC

    What's Changed

  2. v0.3.32026-11-02 · 2026-11-02 10:30 UTC
    查看更新说明

    What's Changed

  3. v0.3.22026-10-16 · 2026-10-16 15:30 UTC
    查看更新说明

    What's Changed

    New Contributors

    Full Changelog: https://github.com/lmnr-ai/lmnr/compare/v0.3.1...v0.3.2

  4. v0.3.12026-10-13 · 2026-10-13 08:18 UTC
    查看更新说明

    What's Changed

    Full Changelog: https://github.com/lmnr-ai/lmnr/compare/v0.3.0...v0.3.1

  5. v0.3.02026-10-11 · 2026-10-11 22:01 UTC
    查看更新说明

    Breaking changes

    The primary breaking changes are:

    • Default Docker compose files now include Valkey
    • Quickwit is now bumped to 0.9. ⚠️ Migration of the postgres schema is irreversible. If you wish to rollback, make a backup ⚠️ For more info see #2528 . See also: https://quickwit.io/docs/main-branch/operating/upgrades#migration-from-08-to-09
    • Quickwit now force commits on every doc batch write. This behaviour matches releases < 0.2.5. There are now ways to opt-out / configure. For more info see #2528
    • RMCP is bumped to version 3.x and now can communicate in newer MCP versions. This shouldn't break any behaviour, but list_tools responses slightly changed their shape. See more in #2488

    What's Changed

用户点评

登录用户的真实使用记录,可按版本和硬件筛选
共 0 条

    还没有人点评。第一个说出真实体验的人最有价值。

    README 原文

    未翻译

    Static Badge X (formerly Twitter) Follow LinkedIn Static Badge

    Laminar banner

    Laminar

    Laminar is an open-source observability platform purpose-built for AI agents.

    • Tracing. Docs
      • OpenTelemetry-native powerful tracing SDK - 1 line of code to automatically trace Vercel AI SDK, Browser Use, Stagehand, LangChain, OpenAI, Anthropic, Gemini, and more.
    • Signals. Docs
      • Describe any behavior of your agent that you want to track in plain English (e.g. "agent is stuck in a loop")
      • Laminar reads every agent run and pings you in Slack when it happens.
    • Evals. Docs
      • Unopinionated, extensible SDK and CLI for running evals locally or in CI/CD pipeline.
      • UI for visualizing evals and comparing results.
    • MCP / CLI access for your coding agent
      • Query traces, spans, metrics, and events with SQL
      • Let your coding agent investigate and debug issues based on your traces
    • Dashboards. Docs
      • Powerful dashboard builder for traces, metrics, and events with support of custom SQL queries.
    • Data annotation & Datasets. Docs
      • Custom data rendering UI for fast data annotation and dataset creation for evals.
    • Extremely high performance.
      • Written in Rust 🦀
      • 20x trace compression for efficient ingestion and storage. Read more about it here.
      • Custom realtime engine for viewing traces as they happen.
      • Ultra-fast full-text search over span data.
      • gRPC exporter for tracing data.

    Traces

    Documentation

    Check out the full documentation here laminar.sh/docs.

    Getting started

    The fastest and easiest way to get started is with our managed platform -> laminar.sh

    Self-hosting with Docker compose

    Laminar is very easy to self-host locally. For a quick start, clone the repo and start the services with docker compose:

    git clone https://github.com/lmnr-ai/lmnr
    cd lmnr
    docker compose up -d
    

    This will spin up a lightweight but full-featured version of the stack. This is good for a quickstart or for lightweight usage. You can access the UI at http://localhost:5667 in your browser.

    You will also need to properly configure the SDK, with baseUrl and correct ports. See guide on self-hosting.

    For production environment, we recommend using our managed platform or docker compose -f docker-compose-full.yml up -d.

    Upgrading existing self-hosted installations

    The ClickHouse configuration disables internal telemetry logs that are not useful for a single-node installation and retains query and error logs for three days. After pulling this change, recreate the ClickHouse container to apply the configuration. The examples below use docker-compose.yml; pass -f with the Compose file used by your deployment when it differs:

    docker compose up -d --force-recreate clickhouse
    

    Disabling a system log stops new writes but does not clear an existing table. To reclaim its disk space while preserving the table structure, truncate the disabled log tables after ClickHouse restarts:

    docker compose exec -T clickhouse clickhouse-client --multiquery <<'SQL'
    TRUNCATE TABLE IF EXISTS system.trace_log;
    TRUNCATE TABLE IF EXISTS system.text_log;
    TRUNCATE TABLE IF EXISTS system.part_log;
    TRUNCATE TABLE IF EXISTS system.metric_log;
    TRUNCATE TABLE IF EXISTS system.asynchronous_metric_log;
    TRUNCATE TABLE IF EXISTS system.background_schedule_pool_log;
    TRUNCATE TABLE IF EXISTS system.query_metric_log;
    TRUNCATE TABLE IF EXISTS system.query_thread_log;
    TRUNCATE TABLE IF EXISTS system.query_views_log;
    TRUNCATE TABLE IF EXISTS system.session_log;
    TRUNCATE TABLE IF EXISTS system.crash_log;
    TRUNCATE TABLE IF EXISTS system.opentelemetry_span_log;
    TRUNCATE TABLE IF EXISTS system.zookeeper_log;
    TRUNCATE TABLE IF EXISTS system.blob_storage_log;
    TRUNCATE TABLE IF EXISTS system.processors_profile_log;
    TRUNCATE TABLE IF EXISTS system.asynchronous_insert_log;
    SQL
    

    When ClickHouse applies the new TTL to an existing query_log or error_log, it may rename the previous table with a numeric suffix such as query_log_0. Inspect any suffixed tables before dropping them if you also want to reclaim their historical data.

    Configuring LLM provider (optional)

    Frontend AI features (chat-with-trace, SQL-with-AI) and server-side AI workers require an LLM provider. Configure one in your .env file at the repo root.

    Pick one of the following provider setups. LLM_MODEL_SMALL|MEDIUM|LARGE are optional — per-provider defaults apply when unset. LLM_DEFAULT_HEADERS_JSON is optional for any provider or gateway that requires static headers.

    # Optional for any provider/gateway that requires static headers
    # LLM_DEFAULT_HEADERS_JSON='{"X-Gateway-Tenant":"tenant"}'
    
    # Option A: Gemini
    LLM_PROVIDER=gemini
    LLM_API_KEY=your_gemini_key
    
    # Option B: OpenAI (or any OpenAI-compatible gateway such as LiteLLM, OpenRouter, vLLM)
    LLM_PROVIDER=openai
    # LLM_BASE_URL=http://localhost:4000   # optional, for OpenAI-compatible gateways
    LLM_API_KEY=your_openai_key
    
    # Option C: AWS Bedrock (Anthropic Claude). Uses AWS credentials instead of LLM_API_KEY.
    LLM_PROVIDER=bedrock
    AWS_ACCESS_KEY_ID=...
    AWS_SECRET_ACCESS_KEY=...
    AWS_REGION=us-east-1
    
    # Option D: Azure AI Foundry. One resource serves three API shapes; pick the one
    # matching your deployment. Model ids are deployment names, so set LLM_MODEL_*
    # unless your deployments are named after the models.
    #   azure_chat_completions -> <resource>.services.ai.azure.com/openai/v1/chat/completions
    #   azure_responses        -> <resource>.services.ai.azure.com/openai/v1/responses
    #   azure_anthropic        -> <resource>.services.ai.azure.com/anthropic/v1/messages (Claude)
    LLM_PROVIDER=azure_chat_completions
    LLM_API_KEY=your_azure_key
    AZURE_RESOURCE_ID=your_resource_name   # or AZURE_BASE_URL for private endpoints
    # AZURE_API_VERSION=preview            # optional; only for resources that require it
    

    Custom Postgres schema (optional)

    By default Laminar uses the public schema. To target a different schema (e.g. when deploying alongside other services in a shared Postgres instance), set the same value for both the frontend and the app-server:

    POSTGRES_SCHEMA=laminar
    # Set to false if the schema is pre-provisioned or the DB role lacks CREATE.
    # POSTGRES_CREATE_SCHEMA=true
    

    The schema is applied as the connection search_path, so all tables, foreign keys, and migrations target it. When a non-public schema is set, the frontend also tracks migrations inside that schema (<schema>.__drizzle_migrations) rather than the shared drizzle schema. Note that running Laminar alongside another Drizzle-managed service in the same database may still require manual intervention, since Drizzle's migration journal is versioned per-schema.

    SQL access to Postgres entities (optional)

    Some SQL tables are read live from Postgres: signals, evaluations and datasets, plus the signal, evaluation and dataset names on signal_events, evaluation_datapoints and dataset_datapoints. ClickHouse reads them through a dedicated read-only role, which is off until you set both of these in your .env:

    CLICKHOUSE_POSTGRES_USER=clickhouse_ro
    CLICKHOUSE_POSTGRES_PASSWORD=<choose a strong password>
    

    On boot the frontend creates that role if absent and grants SELECT on only the columns it needs. Use a dedicated role: the frontend refuses to use the app's own Postgres user or a privileged role. Without them, those tables and columns return an error. If Postgres is not the compose postgres service, also set CLICKHOUSE_POSTGRES_HOST / CLICKHOUSE_POSTGRES_PORT as the ClickHouse server reaches it.

    Externally managed Postgres role

    The frontend checks whether CLICKHOUSE_POSTGRES_USER already exists. For an existing dedicated role, it skips role creation, password changes, role settings, and database CONNECT grants. It still applies schema USAGE, column-level SELECT grants, and SELECT RLS policies after migrations, and configures ClickHouse's pg database with the supplied credentials. No additional environment variable is needed. If the role is absent, the frontend provisions it as before.

    To manage the login through Terraform or a database administrator, provision it before starting the frontend, with LOGIN, CONNECT on the target database, statement_timeout (normally 15s), and CONNECTION LIMIT (normally 10). The frontend does not apply CLICKHOUSE_POSTGRES_STATEMENT_TIMEOUT or CLICKHOUSE_POSTGRES_CONNECTION_LIMIT to existing roles. Do not reuse the app's login or a role with SUPERUSER, BYPASSRLS, or CREATEROLE. The frontend's migration login must own, or inherit ownership of, the schema and exposed tables to apply the schema/table grants and RLS policies.

    Verify the credentials, required reads, and connectivity from the ClickHouse server before enabling the feature, and test a ClickHouse restart in staging. The PostgreSQL database engine remains a startup dependency of ClickHouse. After rotating the external password, update CLICKHOUSE_POSTGRES_PASSWORD and restart the frontend so it recreates pg with the new credentials. For existing roles, changing this variable does not change the password in Postgres; rotate it through the system that owns the login. Unset credentials still drop pg.

    Anonymous usage telemetry

    Self-hosted deployments collect anonymized usage telemetry. To opt out, set LAMINAR_TELEMETRY_DISABLED=true in your .env.

    For shipped Docker Compose stacks, set the variable in the repository-root .env and recreate the frontend container. For a manually run frontend or Helm deployment, set it in the frontend process or pod environment.

    Contributing

    For running and building Laminar locally, or to learn more about docker compose files, follow the guide in Contributing.

    TS quickstart

    First, create a project and generate a project API key. Then,

    npm add @lmnr-ai/lmnr
    

    It will install Laminar TS SDK and all instrumentation packages (OpenAI, Anthropic, LangChain ...)

    To start tracing LLM calls just add

    import { Laminar } from '@lmnr-ai/lmnr';
    Laminar.initialize({ projectApiKey: process.env.LMNR_PROJECT_API_KEY });
    

    To trace inputs / outputs of functions use observe wrapper.

    import { OpenAI } from 'openai';
    import { observe } from '@lmnr-ai/lmnr';
    
    const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
    
    const poemWriter = observe({name: 'poemWriter'}, async (topic) => {
      const response = await client.chat.completions.create({
        model: "gpt-4o-mini",
        messages: [{ role: "user", content: `write a poem about ${topic}` }],
      });
      return response.choices[0].message.content;
    });
    
    await poemWriter();
    

    Python quickstart

    First, create a project and generate a project API key. Then,

    pip install --upgrade 'lmnr[all]'
    

    It will install Laminar Python SDK and all instrumentation packages. See list of all instruments here

    To start tracing LLM calls just add

    from lmnr import Laminar
    Laminar.initialize(project_api_key="<LMNR_PROJECT_API_KEY>")
    

    To trace inputs / outputs of functions use @observe() decorator.

    import os
    from openai import OpenAI
    
    from lmnr import observe, Laminar
    Laminar.initialize(project_api_key="<LMNR_PROJECT_API_KEY>")
    
    client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
    
    @observe()  # annotate all functions you want to trace
    def poem_writer(topic):
        response = client.chat.completions.create(
            model="gpt-4o",
            messages=[
                {"role": "user", "content": f"write a poem about {topic}"},
            ],
        )
        poem = response.choices[0].message.content
        return poem
    
    if __name__ == "__main__":
        print(poem_writer(topic="laminar flow"))
    

    Client libraries

    To learn more about instrumenting your code, check out our client libraries:

    NPM Version PyPI - Version