定制 witness-sdk/php-sdk 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

witness-sdk/php-sdk

Composer 安装命令:

composer require witness-sdk/php-sdk

包简介

The PHP SDK for the Witness Application.

README 文档

README

Witness PHP SDK

The PHP SDK for the Witness Application.

Repository: github.com/witness-sdk/php-sdk

Witness captures inference telemetry on a side channel: events are buffered in-process and delivered to witness.sh as a single batch at the end of the request. Your inference hot path is never blocked, and delivery failures never throw into your application — if ingestion is down, your models still answer.

Install

composer require witness-sdk/php-sdk

Requires PHP 8.1+ with ext-curl and ext-json. No other dependencies.

Quickstart

use Witness\Witness;

Witness::init(['api_key' => 'w_live_...', 'project' => 'prod-chat']);

$client = Witness::watch(
    OpenAI::factory()
        ->withApiKey('gsk_...')
        ->withBaseUri('https://api.groq.com/openai/v1')
        ->make(),
    ['provider' => 'groq'],
);

$response = $client->chat()->create([
    'model' => 'llama-3.3-70b-versatile',
    'messages' => [['role' => 'user', 'content' => 'Hello']],
]);

// inference → your provider, direct
// telemetry → witness.sh, at request end

Witness::watch() wraps an OpenAI-compatible client instance in a transparent proxy — use the returned object in place of the original. Every chat()->create(), embeddings()->create(), messages->create() (Anthropic-style), and streaming call is traced automatically. Both method style ($client->chat()->create()) and property style ($client->chat->completions->create()) clients work.

PHP cannot patch classes at runtime, so unlike the Python and Node SDKs (which patch the client class once), watch() wraps each instance. Provider is inferred from the client's base URL when it is exposed publicly; most PHP clients keep it private, so passing ['provider' => ...] explicitly is recommended.

Prefer explicit control? Use Witness::log() instead:

$chat = Witness::log(
    fn (array $messages) => $client->chat()->create([
        'model' => 'llama-3.3-70b-versatile',
        'messages' => $messages,
    ]),
    ['provider' => 'groq'],
);

$response = $chat([['role' => 'user', 'content' => 'Hello']]);

Witness::log() wraps any callable that performs an inference call. It times the call, extracts model and token usage from the response by duck-typing (any OpenAI-compatible response shape works — objects, arrays, or ArrayAccess), and buffers an event. The wrapped callable's return value and exceptions pass through untouched — failed calls are recorded with status: "error" and re-thrown.

Provider and model are read from the response when possible; the options (provider, model, operation, metadata) fill in whatever the response cannot answer.

Opting out of telemetry

Skip reporting for specific calls:

// Callback scope — works with watch() and Witness::log()
Witness::ignore(fn () => $client->chat()->create([...]));

// Single call — watch() strips it before the provider sees it
$client->chat()->create(['model' => '...', 'messages' => [...], 'witness_ignore' => true]);

To keep only a fraction of events on high-volume paths, set a sample rate:

Witness::init(['api_key' => '...', 'project' => '...', 'sample_rate' => 0.1]); // keep ~10%

Configuration

Witness::init() accepts an options array:

Key Default Notes
api_key WITNESS_API_KEY env var Required (option or env)
project WITNESS_PROJECT env var Required (option or env)
base_url https://witness.sh/api/v1 Override for staging / self-hosted
queue_size 10000 Bounded in-memory event buffer
sample_rate 1.0 Fraction of calls to record (per-call decision)

If no API key or project is configured, init() logs a warning and the SDK stays disabled: instrumented code runs normally and nothing is sent. Your observability layer never crashes your app over a missing env var.

Witness::flush(timeout: 5.0) delivers buffered events now and keeps running — useful in long-running workers (queue consumers, Octane, Swoole) where the request never "ends". Witness::shutdown() flushes and stops; a shutdown function is registered automatically by init(), so in classic request-per-process PHP you never need to call either one.

Delivery model

PHP is request-scoped with no background threads, so this SDK buffers events in memory (enqueueing is a plain array append) and posts them as one {"events": [...]} batch envelope when flush() or shutdown() runs — normally at the very end of the request, after your response is built. Failed deliveries are retried with backoff (bounded by the flush timeout), then dropped with a warning. Telemetry is never worth an exception.

Long-running workers should call Witness::flush() periodically (e.g. after each job) so events do not sit in memory for hours.

Privacy

Witness sends metadata only: provider, model, latency, token counts, and status. Prompt and completion text are never transmitted.

Wire contract

The SDK posts {"events": [...]} batch envelopes to POST {base_url}/events with a Bearer API key. The full contract lives in schema/v1/event.json and is versioned via the schema_version field on every event.

Roadmap

  • Non-blocking delivery via curl_multi fire-and-forget
  • Provider inference for clients that expose their base URL via config objects
  • Time-to-last-token on streamed responses

Development

composer install
composer test

License

MIT

统计信息

  • 总下载量: 0
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 4
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-06-14

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固