هوش.یارمستندات

گزارش مصرف خود

برچسب‌هایی را بفرستید که گزارش‌ها و ردگیری‌ها (trace) ابزار، نشست‌ها و کاربران شما را نشان دهند. اگر عامل (agent) شما مستقیم با ارائه‌دهندهٔ مدل کار می‌کند، معیارهای OpenTelemetry آن را به درگاه بفرستید.

آنچه درگاه ثبت می‌کند

  • برای هر درخواست: مسیر، مدل، تأخیر، شمار توکن‌ها، هزینه، شناسهٔ کلید و برچسب‌های این صفحه.
  • هرگز متن پرامپت، متن پاسخ یا کلید شما ثبت نمی‌شود. مدیر سیستم می‌تواند ضبط بدنه را برای یک مسیر روشن کند. بپرسید کدام مسیرها آن را دارند.
  • برچسبی که بلندتر از حد باشد به‌طور کامل حذف می‌شود. درگاه هرگز برچسبی را کوتاه نمی‌کند، چون برچسب کوتاه‌شده دو چیز متفاوت را یکی می‌کند.

۱. درخواست را شناسایی کنید

کلید کلاینت خود را در یکی از این سرآیندها بفرستید. گزارش‌ها درخواست را به مالک کلید نسبت می‌دهند. کلیدی که مالک ندارد به‌عنوان حساب سرویس گزارش می‌شود.

فیلدمحلمعنامحدودیتدر گزارش‌ها
Authorizationسرآیندکلید کلاینت شما، به شکل Bearer <key>. شیوهٔ OpenAI.—کلید و مالک آن
x-api-keyسرآیندکلید کلاینت شما. شیوهٔ Anthropic، که Claude Code و SDK آنتروپیک به کار می‌برند.—کلید و مالک آن
x-hooshyar-keyسرآیندکلید کلاینت شما، فقط در خط اشتراک (subscription lane) و در ارسال OpenTelemetry، جایی که دو سرآیند دیگر اعتبارنامهٔ دیگری حمل می‌کنند یا هیچ اعتبارنامه‌ای ندارند.—کلید و مالک آن

۲. مسیر را انتخاب کنید

مسیر مدل را تعیین می‌کند. صفحهٔ Connect a client روش انتخاب آن را می‌گوید. /v1/classify بدون فراخوانی مدل می‌گوید یک متن به کدام مسیر می‌رود و چرا.

فیلدمحلمعنامحدودیتدر گزارش‌ها
modelبدنهauto یا نام یک مسیر.—مسیر، مدل
x-task-typeسرآیندنام یک مسیر. بر model و بر route مقدم است.—مسیر، و source = hint
routeبدنهنام یک مسیر. درگاه این فیلد را پیش از ارسال درخواست حذف می‌کند.—مسیر، و source = hint

۳. درخواست را برچسب بزنید

این برچسب‌ها اختیاری‌اند. هر کدام یک بُعد به گزارش‌ها اضافه می‌کند. درگاه سرآیندهای x- را پیش از ارسال درخواست به ارائه‌دهنده حذف می‌کند.

فیلدمحلمعنامحدودیتدر گزارش‌ها
x-clientسرآیندنام ابزار یا برنامهٔ شما. بر user agent مقدم است. برای هر ابزار یک نام کوتاه و همیشه همان را به کار ببرید.32 نویسه. مقدار بلندتر نادیده گرفته می‌شود و user agent تصمیم می‌گیرد.بُعد Client: هزینه و کاربران به ازای هر ابزار
x-session-idسرآیندیک شناسه برای هر اجرا یا هر گفتگو. همان شناسه را در همهٔ درخواست‌های آن اجرا، در هر تلاش دوباره و در /mcp بفرستید.64 نویسه. مقدار بلندتر ثبت نمی‌شود.بُعد Session: نشست‌ها، ساعت‌های نشست، هزینهٔ هر نشست، مُهر PR
x-tagsسرآیندبرچسب‌ها، جداشده با کاما: یک تیم، یک آزمایش، یک قابلیت. برچسب تکراری یک بار ذخیره می‌شود.—بُعد Tag. یک قاعدهٔ گاردریل می‌تواند یک برچسب را انتخاب کند.
userبدنهشخصی که برنامه از طرف او کار می‌کند. فیلد OpenAI.—بُعد User، در کنار مالک کلید
metadata.user_idبدنههمان، در API پیام‌های Anthropic. Claude Code آن را همراه شناسهٔ نشست خود می‌فرستد.—بُعد User، و نشست وقتی x-session-id فرستاده نشود
  • برچسب یک نام است. هرگز یک راز یا متن پرامپت نیست. درگاه آن را ذخیره می‌کند.
  • در شناسهٔ نشست فقط حروف، ارقام و ._:- به کار ببرید. مُهر PR فقط این‌ها را می‌پذیرد.
  • Claude Code خودش شناسهٔ نشست می‌فرستد. برای Claude Code به x-session-id نیاز ندارید.

نمونه‌ها

curl (همهٔ برچسب‌ها)

محل: یک ترمینال

bash
# x-client: which tool (max 32 characters)
# x-session-id: one id per run or conversation (max 64)
# x-tags: labels, comma separated
# user (in the body): the person the application acts for
curl https://gateway.example.com/v1/chat/completions \
  -H "Authorization: Bearer ${HOOSHYAR_API_KEY}" \
  -H "Content-Type: application/json" \
  -H "x-client: research-agent" \
  -H "x-session-id: run-2026-10-14-0042" \
  -H "x-tags: team-data,experiment-7" \
  -d '{"model":"auto","user":"alice@example.com","messages":[{"role":"user","content":"ping"}]}'

x-client نام ابزار است، x-session-id نام اجرا، x-tags برچسب‌ها؛ user در بدنه نام شخص است. مقدارهای نمونه را با مقدارهای خود جایگزین کنید.

OpenAI SDK (Python)

محل: هر جا که کلاینت را می‌سازید

python
import os
from openai import OpenAI

client = OpenAI(
    base_url="https://gateway.example.com/v1",
    api_key=os.environ["HOOSHYAR_API_KEY"],
    default_headers={
        "x-client": "research-agent",        # which tool, max 32 characters
        "x-tags": "team-data,experiment-7",  # labels, comma separated
    },
)


def ask(messages, session_id: str, user_email: str):
    return client.chat.completions.create(
        model="auto",
        messages=messages,
        user=user_email,  # the person the application acts for
        extra_headers={"x-session-id": session_id},  # one id per run, max 64 characters
    )

default_headers برچسب‌هایی را حمل می‌کند که تغییر نمی‌کنند. شناسهٔ نشست و کاربر در هر اجرا تغییر می‌کنند، پس روی هر فراخوانی می‌روند.

OpenAI SDK (TypeScript)

محل: هر جا که کلاینت را می‌سازید

typescript
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://gateway.example.com/v1",
  apiKey: process.env.HOOSHYAR_API_KEY,
  defaultHeaders: {
    "x-client": "research-agent",        // which tool, max 32 characters
    "x-tags": "team-data,experiment-7",  // labels, comma separated
  },
});

export function ask(messages: OpenAI.ChatCompletionMessageParam[], sessionId: string, userEmail: string) {
  return client.chat.completions.create(
    { model: "auto", messages, user: userEmail }, // the person the application acts for
    { headers: { "x-session-id": sessionId } },   // one id per run, max 64 characters
  );
}

defaultHeaders برچسب‌هایی را حمل می‌کند که تغییر نمی‌کنند. شناسهٔ نشست و کاربر در هر اجرا تغییر می‌کنند، پس روی هر فراخوانی می‌روند.

۴. پاسخ را بخوانید

درگاه این سرآیندهای پاسخ را از ارائه‌دهنده به کلاینت شما می‌رساند و یکی را خودش اضافه می‌کند.

سرآیندمعنا
x-request-idشناسهٔ فراخوانی نزد ارائه‌دهنده (request-id در سطح Anthropic). هنگام گزارش یک مشکل آن را به مدیر سیستم بدهید.
retry-afterدر 429 یا 503: شمار ثانیه‌هایی که پیش از ارسال دوباره باید صبر کنید.
x-ratelimit-*شمارنده‌های محدودیت نرخ ارائه‌دهنده: x-ratelimit-*، ratelimit-* و anthropic-ratelimit-*.
x-hooshyar-guardrail: soft-denyپاسخ یک ردِ ساخته‌شده توسط درگاه است، به شکل یک پاسخ عادی، با مصرف صفر. این مسیر پیکربندی شده که به جای 403 این‌طور رد کند.
  • درخواست مسدودشده معمولاً 403 با error.type = guardrail_blocked می‌گیرد. این خودِ پاسخ است. آن را دوباره نفرستید.
  • فقط اتصالِ ردشده یا قطع‌شده و 502، 503 و 504 را دوباره بفرستید. حداکثر 3 تلاش، با همان x-session-id.

۵. OpenTelemetry بفرستید

وقتی عامل شما مستقیم با ارائه‌دهندهٔ مدل کار می‌کند، نه از راه درگاه، از این بخش استفاده کنید. مصرف آن در کنسول کنار ارقام خود درگاه نشان داده می‌شود. این دو هرگز با هم جمع نمی‌شوند.

  • گیرنده فقط سیگنال معیارها (metrics) را می‌پذیرد، به شکل OTLP/JSON روی HTTP. Protobuf پاسخ 415 می‌گیرد. Span و log پاسخ 404 می‌گیرند، چون می‌توانند متن پرامپت حمل کنند.
  • با temporality از نوع delta بفرستید. نقطهٔ تجمعی (cumulative) رد می‌شود، چون جمع نقطه‌های تجمعی یک توکن را چند بار می‌شمارد.
  • کلید کلاینت خود را در سرآیند x-hooshyar-key بفرستید. مصرف به مالک آن کلید تعلق دارد.
  • درگاه دو معیار را ذخیره می‌کند: gen_ai.client.token.usage و gen_ai.client.operation.duration. هر نام معیار دیگری رد می‌شود و در پاسخ نام برده می‌شود.
  • SDKای که فقط protobuf می‌فرستد (SDK پایتون) به یک OpenTelemetry Collector می‌فرستد و collector به شکل JSON به درگاه می‌فرستد. نمونهٔ دوم collector را نشان می‌دهد.

ارسال OpenTelemetry (متغیرهای exporter)

محل: محیط عامل شما

bash
export OTEL_METRICS_EXPORTER=otlp
export OTEL_EXPORTER_OTLP_PROTOCOL=http/json                   # JSON only; protobuf is refused
export OTEL_EXPORTER_OTLP_ENDPOINT="https://gateway.example.com/otel"   # the exporter adds /v1/metrics
export OTEL_EXPORTER_OTLP_HEADERS="x-hooshyar-key=${HOOSHYAR_API_KEY}"  # your client key
export OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE=delta  # cumulative points are refused
export OTEL_TRACES_EXPORTER=none                                # spans are refused
export OTEL_LOGS_EXPORTER=none                                  # logs are refused
export OTEL_RESOURCE_ATTRIBUTES="service.name=research-agent"   # which tool, max 32 characters

برای SDKای که OTEL_EXPORTER_OTLP_PROTOCOL=http/json را رعایت می‌کند (SDK جاوااسکریپت، Claude Code). برای Claude Code، CLAUDE_CODE_ENABLE_TELEMETRY=1 را اضافه کنید. OTEL_RESOURCE_ATTRIBUTES مقدار service.name را تعیین می‌کند؛ enduser.id و session.id را در کد خود، برای هر اجرا، تنظیم کنید.

OpenTelemetry Collector (برای SDKای که فقط protobuf می‌فرستد)

محل: otel-collector-config.yaml، کنار عامل شما

yaml
receivers:
  otlp:
    protocols:
      http:
        endpoint: 127.0.0.1:4318
exporters:
  otlphttp/hooshyar:
    endpoint: https://gateway.example.com/otel
    encoding: json
    headers:
      x-hooshyar-key: ${env:HOOSHYAR_API_KEY}
service:
  pipelines:
    metrics:
      receivers: [otlp]
      exporters: [otlphttp/hooshyar]

SDK پایتون فقط protobuf می‌فرستد. آن را به collector (درگاه 4318) وصل کنید، OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE=delta را در عامل نگه دارید، و collector به شکل JSON به درگاه می‌فرستد. فقط خط لولهٔ معیارها تعریف شده است، پس span و log فرستاده نمی‌شوند.

ویژگی‌ها (attributes)

این‌ها را روی resource یا روی هر نقطهٔ داده بگذارید.

ویژگیمعنانمونه
service.nameنام ابزار شما. کنسول آن را به‌عنوان کلاینت نشان می‌دهد. حداکثر 32 نویسه.research-agent
gen_ai.request.modelمدلی که عملیات درخواست کرده است.<MODEL_ID>
gen_ai.token.typeinput یا output، روی هر نقطهٔ مصرف توکن.input
enduser.idکاربری که عامل از طرف او کار می‌کند (user.id هم پذیرفته می‌شود). در کنار مالک کلید ثبت می‌شود، نه به جای او.alice@example.com
session.idیک شناسه برای هر اجرا یا گفتگو. کنسول نشست‌ها را از روی آن می‌شمارد.run-42

چه چیز دیگری ذخیره می‌شود

این برچسب‌ها، اگر باشند: gen_ai.system, gen_ai.provider.name, gen_ai.operation.name, gen_ai.response.model, gen_ai.agent.name, server.address, server.port, error.type, telemetry.sdk.name, telemetry.sdk.language, telemetry.sdk.version. هر ویژگی دیگری حذف می‌شود و نام آن ثبت می‌شود. مقدار بلندتر از 128 نویسه به‌طور کامل حذف می‌شود. متن پرامپت و متن پاسخ هرگز ذخیره نمی‌شوند.

پاسخ‌ها

وضعیتمعناچه کنید
200ذخیره شد. partialSuccess.rejectedDataPoints شمار نقطه‌های ردشده است و errorMessage دلیل را می‌گوید.errorMessage را در لاگ exporter خود بخوانید. نقطه‌های ردشده را دوباره نفرستید.
400بدنه یک ارسال معیارهای OTLP نیست.exporter را درست کنید. دوباره نفرستید.
401کلید کلاینت معتبری در x-hooshyar-key نیست.کلید را درست کنید. دوباره نفرستید.
404گیرنده خاموش است، یا سیگنال log یا trace فرستاده‌اید.از مدیر سیستم بپرسید، یا exporter مربوط به trace و log را روی none بگذارید.
413ارسال از حد JSON درگاه بزرگ‌تر است.بیشتر و با نقطه‌های کمتر بفرستید.
415بدنه protobuf است.OTEL_EXPORTER_OTLP_PROTOCOL=http/json را تنظیم کنید، یا از راه collector بفرستید.
502درگاه نتوانست کلید را بررسی کند.بعداً دوباره بفرستید.
503درگاه نتوانست ارسال را ذخیره کند.بعداً دوباره بفرستید. exporter این کار را خودش می‌کند.

Claude Code می‌تواند معیارهای خودش (claude_code.*) را به همین روش بفرستد. همان متغیرها را به‌علاوهٔ CLAUDE_CODE_ENABLE_TELEMETRY=1 تنظیم کنید. شاید مدیر سیستم این را از قبل در فایل تنظیمات مدیریت‌شده نصب کرده باشد.

۶. درخواست ادغام (PR) را مُهر بزنید

وقتی عامل شما درخواست ادغام باز می‌کند، از این بخش استفاده کنید. گزارش‌ها آن‌گاه نشان می‌دهند یک PR ادغام‌شده چقدر هزینه داشته است. مدیر سیستم ابتدا این قابلیت را روشن می‌کند.

برای هر کار یک x-session-id در همهٔ درخواست‌ها بفرستید. همان شناسه را به شکل یک خط در بدنهٔ PR بنویسید: Hooshyar-Session: <the session id>. همان خط را در بدنهٔ یک بازبینی (review) بنویسید تا بازبینی شمرده شود.

PR بدون این خط، یا با دو شناسهٔ متفاوت، به‌عنوان ادغامِ بدون هزینه شمرده می‌شود. درگاه هرگز نشست را از روی زمان حدس نمی‌زند.

برای عامل شما نیست

  • /otel/v1/logs و /otel/v1/traces: رد می‌شوند، چون متن پرامپت حمل می‌کنند.
  • /hooks/v1/events: تصمیم‌های hookهای مدیریت‌شدهٔ Claude Code را دریافت می‌کند که مدیر سیستم نصب می‌کند. یک برنامه آن را فراخوانی نمی‌کند.

بررسی کنید

یک درخواست با برچسب‌های خود بفرستید. در کنسول Reporting را باز کنید و نمای Client یا Session را انتخاب کنید. ارسال OpenTelemetry پس از نخستین بازهٔ exporter زیر Reported by the agent ظاهر می‌شود.