klipitkas/opik-php

Opik PHP SDK - LLM observability and evaluation platform

Installs: 1

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/klipitkas/opik-php

0.8.0 2025-12-16 16:49 UTC

This package is auto-updated.

Last update: 2025-12-16 16:52:01 UTC


README

PHP SDK for Opik - an LLM observability and evaluation platform.

NOTE: This is a community-maintained SDK, not an official Comet ML product. For official SDKs, see Python and TypeScript.

Table of Contents

Installation

Requirements: PHP 8.1+, Composer

composer require klipitkas/opik-php

Quick Start

<?php

use Opik\OpikClient;
use Opik\Tracer\SpanType;

$client = new OpikClient();

// Create a trace
$trace = $client->trace(
    name: 'chat-completion',
    input: ['messages' => [['role' => 'user', 'content' => 'Hello!']]],
);

// Create an LLM span within the trace
$span = $trace->span(name: 'openai-call', type: SpanType::LLM);
$span->update(
    output: ['response' => 'Hi there!'],
    model: 'gpt-4',
    provider: 'openai',
    usage: new \Opik\Tracer\Usage(promptTokens: 10, completionTokens: 5, totalTokens: 15),
);
$span->end();

// End trace and flush
$trace->update(output: ['response' => 'Hi there!']);
$trace->end();
$client->flush();

Configuration

Environment Variables

Variable Description Required Default
OPIK_API_KEY API key Yes (cloud) -
OPIK_WORKSPACE Workspace name Yes (cloud) -
OPIK_PROJECT_NAME Project name No Default Project
OPIK_URL_OVERRIDE Custom API URL No -
OPIK_DEBUG Enable debug mode No false
OPIK_ENABLE_COMPRESSION Enable gzip compression No true

Setup Methods

# Cloud (recommended)
export OPIK_API_KEY=your-api-key
export OPIK_WORKSPACE=your-workspace
export OPIK_PROJECT_NAME=your-project-name
// From environment (recommended)
$client = new OpikClient();

// Explicit parameters
$client = new OpikClient(
    apiKey: 'your-api-key',
    workspace: 'your-workspace',
    projectName: 'my-project',
);

// Local development
$client = new OpikClient(baseUrl: 'http://localhost:5173/api/');

// Verify credentials
if ($client->authCheck()) {
    echo "Connected!";
}

Features

Tracing

Basic Trace with Spans

$trace = $client->trace(name: 'my-trace', input: ['query' => 'Hello']);

$span = $trace->span(name: 'process', type: SpanType::LLM);
$span->update(output: ['result' => 'Done']);
$span->end();

$trace->end();
$client->flush();

Nested Spans

$trace = $client->trace(name: 'multi-step');
$parent = $trace->span(name: 'parent');

$child1 = $parent->span(name: 'step-1', type: SpanType::TOOL);
$child1->end();

$child2 = $parent->span(name: 'step-2', type: SpanType::LLM);
$child2->end();

$parent->end();
$trace->end();

Search Traces and Spans

// Search traces with OQL filter
$traces = $client->searchTraces(
    projectName: 'my-project',
    filter: 'name = "chat-completion"',
);

// Get specific trace/span
$trace = $client->getTraceContent('trace-id');
$span = $client->getSpanContent('span-id');

Span Types

Type Description
SpanType::GENERAL General purpose span
SpanType::LLM LLM API call
SpanType::TOOL Tool/function call
SpanType::GUARDRAIL Guardrail check

Feedback Scores

On Traces and Spans

$trace = $client->trace(name: 'scored-trace');

// Numeric score
$trace->logFeedbackScore(name: 'relevance', value: 0.95, reason: 'Good answer');

// Categorical score
$span = $trace->span(name: 'llm-call', type: SpanType::LLM);
$span->logFeedbackScore(name: 'sentiment', value: 1.0, categoryName: 'positive');

Batch Feedback Scores

use Opik\Feedback\FeedbackScore;

// For traces
$client->logTracesFeedbackScores([
    FeedbackScore::forTrace('trace-1', 'quality', value: 0.9),
    FeedbackScore::forTrace('trace-2', 'quality', value: 0.85, reason: 'Good'),
]);

// For spans
$client->logSpansFeedbackScores([
    FeedbackScore::forSpan('span-1', 'accuracy', value: 0.95),
    FeedbackScore::forSpan('span-2', 'accuracy', categoryName: 'high'),
]);

// Delete feedback scores
$client->deleteTraceFeedbackScore('trace-id', 'quality');
$client->deleteSpanFeedbackScore('span-id', 'accuracy');

Threads

Group related traces into conversations:

use Opik\Feedback\FeedbackScore;

// Create traces in a thread
$trace1 = $client->trace(name: 'user-msg-1', threadId: 'conversation-123');
$trace1->end();

$trace2 = $client->trace(name: 'user-msg-2', threadId: 'conversation-123');
$trace2->end();
$client->flush();

// Close thread before scoring
$client->closeThread('conversation-123');

// Score the thread
$client->logThreadsFeedbackScores([
    FeedbackScore::forThread('conversation-123', 'satisfaction', value: 0.95),
]);

Datasets

Create and Populate

use Opik\Dataset\DatasetItem;

$dataset = $client->getOrCreateDataset(
    name: 'eval-dataset',
    description: 'Test cases',
);

// Standard schema
$dataset->insert([
    new DatasetItem(
        input: ['question' => 'What is PHP?'],
        expectedOutput: ['answer' => 'A programming language'],
        metadata: ['difficulty' => 'easy'],
    ),
]);

// Flexible schema
$dataset->insert([
    new DatasetItem(data: [
        'prompt' => 'Translate: Hello',
        'expected' => 'Bonjour',
    ]),
]);

Read and Manage

// Get items
$items = $dataset->getItems(page: 1, size: 100);
foreach ($items as $item) {
    $input = $item->getInput();
    $output = $item->getExpectedOutput();
}

// Update/delete
$dataset->update($items);
$dataset->delete(['item-id-1', 'item-id-2']);
$dataset->clear(); // Delete all

// List/delete datasets
$datasets = $client->getDatasets();
$client->deleteDataset('dataset-name');

Experiments

use Opik\Experiment\ExperimentItem;

// Create experiment
$experiment = $client->createExperiment(
    name: 'gpt-4-eval',
    datasetName: 'eval-dataset',
);

// Log results
$experiment->logItems([
    new ExperimentItem(
        datasetItemId: 'item-1',
        traceId: 'trace-1',
        output: ['result' => 'Answer'],
        feedbackScores: [['name' => 'accuracy', 'value' => 0.9]],
    ),
]);

// Manage experiments
$experiment = $client->getExperimentById('experiment-id');
$client->updateExperiment(id: 'experiment-id', name: 'new-name');
$client->deleteExperiment('experiment-name');

Prompts

Opik supports two types of prompts: text prompts (simple string templates) and chat prompts (array of messages following OpenAI's chat format).

Text Prompts

// Create a text prompt
$prompt = $client->createPrompt(
    name: 'greeting',
    template: 'Hello {{name}}, you asked: {{question}}',
);

// Get and format
$prompt = $client->getPrompt('greeting');
$text = $prompt->format(['name' => 'John', 'question' => 'How are you?']);
// Returns: "Hello John, you asked: How are you?"

Chat Prompts

use Opik\Prompt\ChatMessage;

// Create a chat prompt with messages array
$prompt = $client->createPrompt(
    name: 'assistant-prompt',
    template: [
        ChatMessage::system('You are a helpful assistant specializing in {{domain}}.'),
        ChatMessage::user('{{question}}'),
    ],
);

// Format returns array of messages
$messages = $prompt->format(['domain' => 'physics', 'question' => 'What is gravity?']);
// Returns:
// [
//     ['role' => 'system', 'content' => 'You are a helpful assistant specializing in physics.'],
//     ['role' => 'user', 'content' => 'What is gravity?'],
// ]

ChatMessage Factory Methods

Method Description
ChatMessage::system($content) Create a system message
ChatMessage::user($content) Create a user message
ChatMessage::assistant($content) Create an assistant message
ChatMessage::tool($content) Create a tool message

Prompt Versions

// Get version history
$history = $client->getPromptHistory('greeting');

// Get specific version
$version = $prompt->getVersion('commit-hash');

// Check prompt type
if ($version->isChat()) {
    $messages = $version->format($variables);
} else {
    $text = $version->format($variables);
}

Delete Prompts

$client->deletePrompts(['prompt-id-1', 'prompt-id-2']);

Attachments

Upload files to traces or spans:

use Opik\Attachment\AttachmentEntityType;

$attachmentClient = $client->getAttachmentClient();

// Upload
$attachmentClient->uploadAttachment(
    projectName: 'my-project',
    entityType: AttachmentEntityType::TRACE,
    entityId: $trace->getId(),
    filePath: '/path/to/file.pdf',
);

// List
$attachments = $attachmentClient->getAttachmentList(
    projectName: 'my-project',
    entityType: AttachmentEntityType::TRACE,
    entityId: $trace->getId(),
);

// Download
$content = $attachmentClient->downloadAttachment(
    projectName: 'my-project',
    entityType: AttachmentEntityType::TRACE,
    entityId: $trace->getId(),
    fileName: 'file.pdf',
    mimeType: 'application/pdf',
);

API Reference

OpikClient Methods

Category Method Description
Tracing trace(...) Create a trace
span(...) Create a standalone span
searchTraces(...) Search traces with OQL
searchSpans(...) Search spans with OQL
getTraceContent(id) Get trace by ID
getSpanContent(id) Get span by ID
Feedback logTracesFeedbackScores(scores) Batch log trace scores
logSpansFeedbackScores(scores) Batch log span scores
logThreadsFeedbackScores(scores) Batch log thread scores
deleteTraceFeedbackScore(id, name) Delete trace score
deleteSpanFeedbackScore(id, name) Delete span score
Threads closeThread(id) Close a thread
closeThreads(ids) Close multiple threads
Datasets getDataset(name) Get dataset
getDatasets() List datasets
createDataset(name) Create dataset
getOrCreateDataset(name) Get or create dataset
deleteDataset(name) Delete dataset
Experiments createExperiment(name, datasetName) Create experiment
getExperiment(name) Get by name
getExperimentById(id) Get by ID
updateExperiment(id, ...) Update experiment
deleteExperiment(name) Delete experiment
Prompts createPrompt(name, template) Create text or chat prompt
getPrompt(name) Get prompt
getPrompts() List prompts
getPromptHistory(name) Get versions
deletePrompts(ids) Delete prompts
Attachments getAttachmentClient() Get attachment client
Utilities authCheck() Verify credentials
flush() Send pending data
getConfig() Get configuration
getProjectUrl() Get project URL

Trace Methods

Method Description
span(name, type?, ...) Create child span
update(output?, ...) Update trace data
end() End the trace
logFeedbackScore(name, value, ...) Log feedback score
getId() Get trace ID

Span Methods

Method Description
span(name, type?, ...) Create child span
update(output?, model?, usage?, ...) Update span data
end() End the span
logFeedbackScore(name, value, ...) Log feedback score
getId() Get span ID

Development

# Install dependencies
composer install

# Run tests
composer test

# Run with coverage (requires pcov/xdebug)
composer test:coverage

# Static analysis
composer analyse

# Code formatting
composer format
composer format:check

License

Apache-2.0

Trademarks

Opik and Comet ML are trademarks of Comet ML, Inc. This project is not affiliated with, endorsed by, or sponsored by Comet ML, Inc.