[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6NT89BAEJFRXMP1HMPVCBQF":3,"skill-same:01M6NT89BAEJFRXMP1HMPVCBQF":82},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":22,"publishedAt":43,"linkOnly":44,"markdownContent":45,"markdownBody":46,"frontMatter":47,"refName":30,"commitSha":57,"skillDirectory":58,"forksCount":13,"repositoryHtmlUrl":59,"repositoryHomepageUrl":6,"ownerHtmlUrl":60,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":61,"install":62,"resources":75},"01M6NT89BAEJFRXMP1HMPVCBQF","agent-observability",null,"Instrument AI agents with tracing, token metrics, latency, and cost visibility. Use for reliability and debugging.","duc-duy-1612\u002FOnline-Delivery-Systems-Web","duc-duy-1612","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F192231384?v=4","01M6NSDKQQDKVTHZ8DZMZ1VYY6","01M6NSDKW8DDVTQHBT1HBDDJPT",0,"MIT","https:\u002F\u002Fgithub.com\u002Fduc-duy-1612\u002FOnline-Delivery-Systems-Web\u002Fblob\u002Fmain\u002F.agents\u002Fskills_archive\u002Fagent-observability\u002FSKILL.md",[17],{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42],"observability","agent observability","access","relevant","scripts","critical","token","main","community","only","reliability","ai agents","devops-security","kubectl","ci","tracing","metrics","git","debugging","security","2026-11-10 10:12:30",false,"---\nname: agent-observability\ndescription: Instrument AI agents with tracing, token metrics, latency, and cost visibility.\n  Use for reliability and debugging.\ncategory: devops\nrisk: critical\nsource: https:\u002F\u002Fgithub.com\u002FBagelHole\u002FDevOps-Security-Agent-Skills\nsource_repo: BagelHole\u002FDevOps-Security-Agent-Skills\nsource_type: community\ndate_added: '2026-09-20'\nlicense: MIT\nlicense_source: https:\u002F\u002Fgithub.com\u002FBagelHole\u002FDevOps-Security-Agent-Skills\u002Fblob\u002Fmain\u002FLICENSE\ncompatibility: Requires the relevant platform CLIs (kubectl, helm, terraform, git,\n  CI runners) and authorized access to the target environment. Docs-only; helper scripts\n  and templates not bundled.\nmetadata:\n  author: devops-skills\n  version: '2.0'\n---\n\n# Agent Observability\n\nMonitor AI agent behavior with logs, traces, metrics, and cost telemetry. This skill covers the full observability stack for LLM-powered applications: from raw Prometheus counters to Grafana dashboards, OpenTelemetry tracing, structured logging, cost tracking, SLO definition, and PII redaction.\n\n---\n\n## Core Metrics\n\nDefine these metrics at the application layer. All examples use the Prometheus client library naming conventions.\n\n### Latency\n\n```python\nfrom prometheus_client import Histogram\n\n# Total end-to-end latency for a full agent turn (user prompt -> final response)\nAGENT_LATENCY = Histogram(\n    \"agent_request_duration_seconds\",\n    \"End-to-end latency of an agent request\",\n    labelnames=[\"agent_name\", \"model\", \"status\"],\n    buckets=(0.25, 0.5, 1, 2, 5, 10, 30, 60, 120),\n)\n\n# Latency of a single LLM API call (one completion request)\nLLM_CALL_LATENCY = Histogram(\n    \"llm_call_duration_seconds\",\n    \"Latency of an individual LLM API call\",\n    labelnames=[\"model\", \"provider\", \"stream\"],\n    buckets=(0.1, 0.25, 0.5, 1, 2, 5, 10, 30),\n)\n\n# Latency of tool\u002Ffunction calls executed by the agent\nTOOL_CALL_LATENCY = Histogram(\n    \"agent_tool_call_duration_seconds\",\n    \"Latency of a tool call executed by the agent\",\n    labelnames=[\"tool_name\", \"agent_name\", \"status\"],\n    buckets=(0.05, 0.1, 0.25, 0.5, 1, 2, 5, 10),\n)\n```\n\n### Token Usage\n\n```python\nfrom prometheus_client import Counter, Histogram\n\nPROMPT_TOKENS = Counter(\n    \"llm_prompt_tokens_total\",\n    \"Total prompt tokens sent to the model\",\n    labelnames=[\"model\", \"agent_name\"],\n)\n\nCOMPLETION_TOKENS = Counter(\n    \"llm_completion_tokens_total\",\n    \"Total completion tokens received from the model\",\n    labelnames=[\"model\", \"agent_name\"],\n)\n\nCACHED_TOKENS = Counter(\n    \"llm_cached_tokens_total\",\n    \"Prompt tokens served from KV-cache (provider-reported)\",\n    labelnames=[\"model\", \"agent_name\"],\n)\n\nTOKENS_PER_REQUEST = Histogram(\n    \"llm_tokens_per_request\",\n    \"Total tokens (prompt + completion) per request\",\n    labelnames=[\"model\", \"agent_name\"],\n    buckets=(100, 500, 1000, 2000, 4000, 8000, 16000, 32000, 64000, 128000),\n)\n```\n\n### Cost\n\n```python\nfrom prometheus_client import Counter\n\nLLM_COST = Counter(\n    \"llm_cost_dollars_total\",\n    \"Estimated cost in USD for LLM usage\",\n    labelnames=[\"model\", \"agent_name\", \"cost_type\"],  # cost_type: prompt | completion\n)\n```\n\n### Tool Calls\n\n```python\nfrom prometheus_client import Counter\n\nTOOL_CALLS_TOTAL = Counter(\n    \"agent_tool_calls_total\",\n    \"Total tool calls made by agents\",\n    labelnames=[\"tool_name\", \"agent_name\", \"status\"],  # status: success | error | timeout\n)\n```\n\n### Errors and Retries\n\n```python\nfrom prometheus_client import Counter, Gauge\n\nLLM_ERRORS = Counter(\n    \"llm_errors_total\",\n    \"Errors returned by the LLM provider\",\n    labelnames=[\"model\", \"provider\", \"error_type\"],  # error_type: rate_limit | timeout | 5xx | auth\n)\n\nLLM_RETRIES = Counter(\n    \"llm_retries_total\",\n    \"Retried LLM API calls\",\n    labelnames=[\"model\", \"provider\", \"retry_reason\"],\n)\n\nAGENT_ACTIVE_REQUESTS = Gauge(\n    \"agent_active_requests\",\n    \"Number of agent requests currently in flight\",\n    labelnames=[\"agent_name\"],\n)\n```\n\n---\n\n## OpenTelemetry Integration\n\nUse the OpenTelemetry Python SDK to create traces that capture every step of an agent turn: the top-level request, each LLM call, each tool execution, and retrieval operations.\n\n### Setup\n\n```python\n# otel_setup.py\nfrom opentelemetry import trace\nfrom opentelemetry.sdk.trace import TracerProvider\nfrom opentelemetry.sdk.trace.export import BatchSpanProcessor\nfrom opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter\nfrom opentelemetry.sdk.resources import Resource\n\ndef init_tracing(service_name: str, otlp_endpoint: str = \"http:\u002F\u002Flocalhost:4317\"):\n    resource = Resource.create({\n        \"service.name\": service_name,\n        \"service.version\": \"1.0.0\",\n        \"deployment.environment\": \"production\",\n    })\n    provider = TracerProvider(resource=resource)\n    exporter = OTLPSpanExporter(endpoint=otlp_endpoint, insecure=True)\n    provider.add_span_processor(BatchSpanProcessor(exporter))\n    trace.set_tracer_provider(provider)\n    return trace.get_tracer(service_name)\n```\n\n### Tracing LLM Calls\n\n```python\n# llm_tracing.py\nimport time\nfrom opentelemetry import trace\nfrom opentelemetry.trace import StatusCode\n\ntracer = trace.get_tracer(\"agent.llm\")\n\ndef traced_llm_call(client, messages, model=\"gpt-4o\", **kwargs):\n    \"\"\"Wrap an LLM completion call with a full OpenTelemetry span.\"\"\"\n    with tracer.start_as_current_span(\"llm.chat_completion\") as span:\n        span.set_attribute(\"llm.model\", model)\n        span.set_attribute(\"llm.provider\", \"openai\")\n        span.set_attribute(\"llm.message_count\", len(messages))\n        span.set_attribute(\"llm.temperature\", kwargs.get(\"temperature\", 1.0))\n        span.set_attribute(\"llm.max_tokens\", kwargs.get(\"max_tokens\", 0))\n\n        start = time.perf_counter()\n        try:\n            response = client.chat.completions.create(\n                model=model, messages=messages, **kwargs\n            )\n            elapsed = time.perf_counter() - start\n\n            usage = response.usage\n            span.set_attribute(\"llm.prompt_tokens\", usage.prompt_tokens)\n            span.set_attribute(\"llm.completion_tokens\", usage.completion_tokens)\n            span.set_attribute(\"llm.total_tokens\", usage.total_tokens)\n            span.set_attribute(\"llm.duration_seconds\", elapsed)\n            span.set_attribute(\"llm.finish_reason\", response.choices[0].finish_reason)\n            span.set_status(StatusCode.OK)\n\n            # Update Prometheus counters\n            PROMPT_TOKENS.labels(model=model, agent_name=\"default\").inc(usage.prompt_tokens)\n            COMPLETION_TOKENS.labels(model=model, agent_name=\"default\").inc(usage.completion_tokens)\n            LLM_CALL_LATENCY.labels(model=model, provider=\"openai\", stream=\"false\").observe(elapsed)\n\n            return response\n\n        except Exception as exc:\n            elapsed = time.perf_counter() - start\n            span.set_status(StatusCode.ERROR, str(exc))\n            span.record_exception(exc)\n            LLM_ERRORS.labels(model=model, provider=\"openai\", error_type=type(exc).__name__).inc()\n            raise\n```\n\n### Tracing Tool Execution\n\n```python\n# tool_tracing.py\nimport functools\nfrom opentelemetry import trace\nfrom opentelemetry.trace import StatusCode\n\ntracer = trace.get_tracer(\"agent.tools\")\n\ndef traced_tool(tool_name: str):\n    \"\"\"Decorator that wraps a tool function with an OTel span and Prometheus metrics.\"\"\"\n    def decorator(func):\n        @functools.wraps(func)\n        def wrapper(*args, **kwargs):\n            with tracer.start_as_current_span(f\"tool.{tool_name}\") as span:\n                span.set_attribute(\"tool.name\", tool_name)\n                span.set_attribute(\"tool.args_count\", len(args) + len(kwargs))\n\n                import time\n                start = time.perf_counter()\n                try:\n                    result = func(*args, **kwargs)\n                    elapsed = time.perf_counter() - start\n                    span.set_attribute(\"tool.duration_seconds\", elapsed)\n                    span.set_status(StatusCode.OK)\n                    TOOL_CALLS_TOTAL.labels(\n                        tool_name=tool_name, agent_name=\"default\", status=\"success\"\n                    ).inc()\n                    TOOL_CALL_LATENCY.labels(\n                        tool_name=tool_name, agent_name=\"default\", status=\"success\"\n                    ).observe(elapsed)\n                    return result\n                except Exception as exc:\n                    elapsed = time.perf_counter() - start\n                    span.set_status(StatusCode.ERROR, str(exc))\n                    span.record_exception(exc)\n                    TOOL_CALLS_TOTAL.labels(\n                        tool_name=tool_name, agent_name=\"default\", status=\"error\"\n                    ).inc()\n                    TOOL_CALL_LATENCY.labels(\n                        tool_name=tool_name, agent_name=\"default\", status=\"error\"\n                    ).observe(elapsed)\n                    raise\n        return wrapper\n    return decorator\n\n# Usage\n@traced_tool(\"web_search\")\ndef web_search(query: str) -> str:\n    # ... tool implementation ...\n    pass\n\n@traced_tool(\"sql_query\")\ndef sql_query(statement: str) -> list:\n    # ... tool implementation ...\n    pass\n```\n\n### Propagating Trace Context Across Services\n\n```python\n# context_propagation.py\nfrom opentelemetry import context\nfrom opentelemetry.propagate import inject, extract\nimport httpx\n\ndef call_downstream_service(url: str, payload: dict) -> dict:\n    \"\"\"Propagate the current trace context to a downstream HTTP service.\"\"\"\n    headers = {}\n    inject(headers)  # injects traceparent + tracestate headers\n    response = httpx.post(url, json=payload, headers=headers)\n    response.raise_for_status()\n    return response.json()\n\ndef extract_context_from_request(request_headers: dict):\n    \"\"\"Extract trace context from incoming request headers (for the receiving service).\"\"\"\n    ctx = extract(request_headers)\n    token = context.attach(ctx)\n    return token  # call context.detach(token) when done\n```\n\n---\n\n\n## Contents\n\n- [Structured Logging](references\u002Fdetails.md)\n- [Grafana Dashboards](references\u002Fdetails.md)\n- [Cost Tracking](references\u002Fdetails.md)\n- [Langfuse \u002F Helicone Integration](references\u002Fdetails.md)\n- [SLO Definition](references\u002Fdetails.md)\n- [Debugging Workflows](references\u002Fdetails.md)\n- [PII Redaction in Traces](references\u002Fdetails.md)\n- [Best Practices](references\u002Fdetails.md)\n- [Related Skills](references\u002Fdetails.md)\n\n## When to Use\n\nApply this skill whenever you operate:\n\n- **Autonomous AI agents** that make multi-step tool calls (e.g., coding agents, support agents, data-pipeline agents).\n- **LLM-backed APIs** serving chat completions, summarisation, or classification behind a REST or gRPC gateway.\n- **RAG pipelines** where a retriever fetches context from a vector store before prompting a model.\n- **Multi-agent orchestrations** (crew-style or graph-based) where several agents collaborate on a single task.\n- **Batch inference jobs** that process thousands of prompts against a model endpoint.\n\nKey signals that you need this skill:\n\n1. You cannot answer \"what is p95 latency for agent responses this week?\"\n2. You have no per-request cost attribution.\n3. Debugging a bad agent response requires grepping raw application logs.\n4. You have no alerting on token-usage spikes or elevated error rates.\n\n---\n\n## Limitations\n\n- Guidance executes against real environments: confirm target, blast radius, and rollback plan before applying anything.\n- Never deploy to production without explicit approval. Docs-only import: upstream scripts and templates not bundled.\n\n### Example\n\n```bash\ngit status && git diff --stat\nkubectl diff -f manifest.yaml\n```\n\n> Adapted from [BagelHole\u002FDevOps-Security-Agent-Skills](https:\u002F\u002Fgithub.com\u002FBagelHole\u002FDevOps-Security-Agent-Skills) (MIT); frontmatter, When to Use\u002FLimitations, and safety boundaries added for upstream compliance. Docs-only import: helper scripts and templates not bundled.\n","# Agent Observability\n\nMonitor AI agent behavior with logs, traces, metrics, and cost telemetry. This skill covers the full observability stack for LLM-powered applications: from raw Prometheus counters to Grafana dashboards, OpenTelemetry tracing, structured logging, cost tracking, SLO definition, and PII redaction.\n\n---\n\n## Core Metrics\n\nDefine these metrics at the application layer. All examples use the Prometheus client library naming conventions.\n\n### Latency\n\n```python\nfrom prometheus_client import Histogram\n\n# Total end-to-end latency for a full agent turn (user prompt -> final response)\nAGENT_LATENCY = Histogram(\n    \"agent_request_duration_seconds\",\n    \"End-to-end latency of an agent request\",\n    labelnames=[\"agent_name\", \"model\", \"status\"],\n    buckets=(0.25, 0.5, 1, 2, 5, 10, 30, 60, 120),\n)\n\n# Latency of a single LLM API call (one completion request)\nLLM_CALL_LATENCY = Histogram(\n    \"llm_call_duration_seconds\",\n    \"Latency of an individual LLM API call\",\n    labelnames=[\"model\", \"provider\", \"stream\"],\n    buckets=(0.1, 0.25, 0.5, 1, 2, 5, 10, 30),\n)\n\n# Latency of tool\u002Ffunction calls executed by the agent\nTOOL_CALL_LATENCY = Histogram(\n    \"agent_tool_call_duration_seconds\",\n    \"Latency of a tool call executed by the agent\",\n    labelnames=[\"tool_name\", \"agent_name\", \"status\"],\n    buckets=(0.05, 0.1, 0.25, 0.5, 1, 2, 5, 10),\n)\n```\n\n### Token Usage\n\n```python\nfrom prometheus_client import Counter, Histogram\n\nPROMPT_TOKENS = Counter(\n    \"llm_prompt_tokens_total\",\n    \"Total prompt tokens sent to the model\",\n    labelnames=[\"model\", \"agent_name\"],\n)\n\nCOMPLETION_TOKENS = Counter(\n    \"llm_completion_tokens_total\",\n    \"Total completion tokens received from the model\",\n    labelnames=[\"model\", \"agent_name\"],\n)\n\nCACHED_TOKENS = Counter(\n    \"llm_cached_tokens_total\",\n    \"Prompt tokens served from KV-cache (provider-reported)\",\n    labelnames=[\"model\", \"agent_name\"],\n)\n\nTOKENS_PER_REQUEST = Histogram(\n    \"llm_tokens_per_request\",\n    \"Total tokens (prompt + completion) per request\",\n    labelnames=[\"model\", \"agent_name\"],\n    buckets=(100, 500, 1000, 2000, 4000, 8000, 16000, 32000, 64000, 128000),\n)\n```\n\n### Cost\n\n```python\nfrom prometheus_client import Counter\n\nLLM_COST = Counter(\n    \"llm_cost_dollars_total\",\n    \"Estimated cost in USD for LLM usage\",\n    labelnames=[\"model\", \"agent_name\", \"cost_type\"],  # cost_type: prompt | completion\n)\n```\n\n### Tool Calls\n\n```python\nfrom prometheus_client import Counter\n\nTOOL_CALLS_TOTAL = Counter(\n    \"agent_tool_calls_total\",\n    \"Total tool calls made by agents\",\n    labelnames=[\"tool_name\", \"agent_name\", \"status\"],  # status: success | error | timeout\n)\n```\n\n### Errors and Retries\n\n```python\nfrom prometheus_client import Counter, Gauge\n\nLLM_ERRORS = Counter(\n    \"llm_errors_total\",\n    \"Errors returned by the LLM provider\",\n    labelnames=[\"model\", \"provider\", \"error_type\"],  # error_type: rate_limit | timeout | 5xx | auth\n)\n\nLLM_RETRIES = Counter(\n    \"llm_retries_total\",\n    \"Retried LLM API calls\",\n    labelnames=[\"model\", \"provider\", \"retry_reason\"],\n)\n\nAGENT_ACTIVE_REQUESTS = Gauge(\n    \"agent_active_requests\",\n    \"Number of agent requests currently in flight\",\n    labelnames=[\"agent_name\"],\n)\n```\n\n---\n\n## OpenTelemetry Integration\n\nUse the OpenTelemetry Python SDK to create traces that capture every step of an agent turn: the top-level request, each LLM call, each tool execution, and retrieval operations.\n\n### Setup\n\n```python\n# otel_setup.py\nfrom opentelemetry import trace\nfrom opentelemetry.sdk.trace import TracerProvider\nfrom opentelemetry.sdk.trace.export import BatchSpanProcessor\nfrom opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter\nfrom opentelemetry.sdk.resources import Resource\n\ndef init_tracing(service_name: str, otlp_endpoint: str = \"http:\u002F\u002Flocalhost:4317\"):\n    resource = Resource.create({\n        \"service.name\": service_name,\n        \"service.version\": \"1.0.0\",\n        \"deployment.environment\": \"production\",\n    })\n    provider = TracerProvider(resource=resource)\n    exporter = OTLPSpanExporter(endpoint=otlp_endpoint, insecure=True)\n    provider.add_span_processor(BatchSpanProcessor(exporter))\n    trace.set_tracer_provider(provider)\n    return trace.get_tracer(service_name)\n```\n\n### Tracing LLM Calls\n\n```python\n# llm_tracing.py\nimport time\nfrom opentelemetry import trace\nfrom opentelemetry.trace import StatusCode\n\ntracer = trace.get_tracer(\"agent.llm\")\n\ndef traced_llm_call(client, messages, model=\"gpt-4o\", **kwargs):\n    \"\"\"Wrap an LLM completion call with a full OpenTelemetry span.\"\"\"\n    with tracer.start_as_current_span(\"llm.chat_completion\") as span:\n        span.set_attribute(\"llm.model\", model)\n        span.set_attribute(\"llm.provider\", \"openai\")\n        span.set_attribute(\"llm.message_count\", len(messages))\n        span.set_attribute(\"llm.temperature\", kwargs.get(\"temperature\", 1.0))\n        span.set_attribute(\"llm.max_tokens\", kwargs.get(\"max_tokens\", 0))\n\n        start = time.perf_counter()\n        try:\n            response = client.chat.completions.create(\n                model=model, messages=messages, **kwargs\n            )\n            elapsed = time.perf_counter() - start\n\n            usage = response.usage\n            span.set_attribute(\"llm.prompt_tokens\", usage.prompt_tokens)\n            span.set_attribute(\"llm.completion_tokens\", usage.completion_tokens)\n            span.set_attribute(\"llm.total_tokens\", usage.total_tokens)\n            span.set_attribute(\"llm.duration_seconds\", elapsed)\n            span.set_attribute(\"llm.finish_reason\", response.choices[0].finish_reason)\n            span.set_status(StatusCode.OK)\n\n            # Update Prometheus counters\n            PROMPT_TOKENS.labels(model=model, agent_name=\"default\").inc(usage.prompt_tokens)\n            COMPLETION_TOKENS.labels(model=model, agent_name=\"default\").inc(usage.completion_tokens)\n            LLM_CALL_LATENCY.labels(model=model, provider=\"openai\", stream=\"false\").observe(elapsed)\n\n            return response\n\n        except Exception as exc:\n            elapsed = time.perf_counter() - start\n            span.set_status(StatusCode.ERROR, str(exc))\n            span.record_exception(exc)\n            LLM_ERRORS.labels(model=model, provider=\"openai\", error_type=type(exc).__name__).inc()\n            raise\n```\n\n### Tracing Tool Execution\n\n```python\n# tool_tracing.py\nimport functools\nfrom opentelemetry import trace\nfrom opentelemetry.trace import StatusCode\n\ntracer = trace.get_tracer(\"agent.tools\")\n\ndef traced_tool(tool_name: str):\n    \"\"\"Decorator that wraps a tool function with an OTel span and Prometheus metrics.\"\"\"\n    def decorator(func):\n        @functools.wraps(func)\n        def wrapper(*args, **kwargs):\n            with tracer.start_as_current_span(f\"tool.{tool_name}\") as span:\n                span.set_attribute(\"tool.name\", tool_name)\n                span.set_attribute(\"tool.args_count\", len(args) + len(kwargs))\n\n                import time\n                start = time.perf_counter()\n                try:\n                    result = func(*args, **kwargs)\n                    elapsed = time.perf_counter() - start\n                    span.set_attribute(\"tool.duration_seconds\", elapsed)\n                    span.set_status(StatusCode.OK)\n                    TOOL_CALLS_TOTAL.labels(\n                        tool_name=tool_name, agent_name=\"default\", status=\"success\"\n                    ).inc()\n                    TOOL_CALL_LATENCY.labels(\n                        tool_name=tool_name, agent_name=\"default\", status=\"success\"\n                    ).observe(elapsed)\n                    return result\n                except Exception as exc:\n                    elapsed = time.perf_counter() - start\n                    span.set_status(StatusCode.ERROR, str(exc))\n                    span.record_exception(exc)\n                    TOOL_CALLS_TOTAL.labels(\n                        tool_name=tool_name, agent_name=\"default\", status=\"error\"\n                    ).inc()\n                    TOOL_CALL_LATENCY.labels(\n                        tool_name=tool_name, agent_name=\"default\", status=\"error\"\n                    ).observe(elapsed)\n                    raise\n        return wrapper\n    return decorator\n\n# Usage\n@traced_tool(\"web_search\")\ndef web_search(query: str) -> str:\n    # ... tool implementation ...\n    pass\n\n@traced_tool(\"sql_query\")\ndef sql_query(statement: str) -> list:\n    # ... tool implementation ...\n    pass\n```\n\n### Propagating Trace Context Across Services\n\n```python\n# context_propagation.py\nfrom opentelemetry import context\nfrom opentelemetry.propagate import inject, extract\nimport httpx\n\ndef call_downstream_service(url: str, payload: dict) -> dict:\n    \"\"\"Propagate the current trace context to a downstream HTTP service.\"\"\"\n    headers = {}\n    inject(headers)  # injects traceparent + tracestate headers\n    response = httpx.post(url, json=payload, headers=headers)\n    response.raise_for_status()\n    return response.json()\n\ndef extract_context_from_request(request_headers: dict):\n    \"\"\"Extract trace context from incoming request headers (for the receiving service).\"\"\"\n    ctx = extract(request_headers)\n    token = context.attach(ctx)\n    return token  # call context.detach(token) when done\n```\n\n---\n\n\n## Contents\n\n- [Structured Logging](references\u002Fdetails.md)\n- [Grafana Dashboards](references\u002Fdetails.md)\n- [Cost Tracking](references\u002Fdetails.md)\n- [Langfuse \u002F Helicone Integration](references\u002Fdetails.md)\n- [SLO Definition](references\u002Fdetails.md)\n- [Debugging Workflows](references\u002Fdetails.md)\n- [PII Redaction in Traces](references\u002Fdetails.md)\n- [Best Practices](references\u002Fdetails.md)\n- [Related Skills](references\u002Fdetails.md)\n\n## When to Use\n\nApply this skill whenever you operate:\n\n- **Autonomous AI agents** that make multi-step tool calls (e.g., coding agents, support agents, data-pipeline agents).\n- **LLM-backed APIs** serving chat completions, summarisation, or classification behind a REST or gRPC gateway.\n- **RAG pipelines** where a retriever fetches context from a vector store before prompting a model.\n- **Multi-agent orchestrations** (crew-style or graph-based) where several agents collaborate on a single task.\n- **Batch inference jobs** that process thousands of prompts against a model endpoint.\n\nKey signals that you need this skill:\n\n1. You cannot answer \"what is p95 latency for agent responses this week?\"\n2. You have no per-request cost attribution.\n3. Debugging a bad agent response requires grepping raw application logs.\n4. You have no alerting on token-usage spikes or elevated error rates.\n\n---\n\n## Limitations\n\n- Guidance executes against real environments: confirm target, blast radius, and rollback plan before applying anything.\n- Never deploy to production without explicit approval. Docs-only import: upstream scripts and templates not bundled.\n\n### Example\n\n```bash\ngit status && git diff --stat\nkubectl diff -f manifest.yaml\n```\n\n> Adapted from [BagelHole\u002FDevOps-Security-Agent-Skills](https:\u002F\u002Fgithub.com\u002FBagelHole\u002FDevOps-Security-Agent-Skills) (MIT); frontmatter, When to Use\u002FLimitations, and safety boundaries added for upstream compliance. Docs-only import: helper scripts and templates not bundled.\n",{"name":5,"risk":28,"source":48,"license":14,"category":49,"metadata":50,"date_added":53,"description":7,"source_repo":54,"source_type":31,"compatibility":55,"license_source":56},"https:\u002F\u002Fgithub.com\u002FBagelHole\u002FDevOps-Security-Agent-Skills","devops",{"author":51,"version":52},"devops-skills","2.0","2026-09-20","BagelHole\u002FDevOps-Security-Agent-Skills","Requires the relevant platform CLIs (kubectl, helm, terraform, git, CI runners) and authorized access to the target environment. Docs-only; helper scripts and templates not bundled.","https:\u002F\u002Fgithub.com\u002FBagelHole\u002FDevOps-Security-Agent-Skills\u002Fblob\u002Fmain\u002FLICENSE","f3312ba749561b6159f477dbfc9313c875d40a56",".agents\u002Fskills_archive\u002Fagent-observability","https:\u002F\u002Fgithub.com\u002Fduc-duy-1612\u002FOnline-Delivery-Systems-Web","https:\u002F\u002Fgithub.com\u002Fduc-duy-1612","2026-10-25 23:50:58",{"source":8,"skillName":5,"commands":63,"prompt":73,"zipAvailable":74},[64,67,70],{"tool":65,"command":66},"npx","npx skills add duc-duy-1612\u002FOnline-Delivery-Systems-Web --skill agent-observability",{"tool":68,"command":69},"bunx","bunx skills add duc-duy-1612\u002FOnline-Delivery-Systems-Web --skill agent-observability",{"tool":71,"command":72},"pnpm","pnpm dlx skills add duc-duy-1612\u002FOnline-Delivery-Systems-Web --skill agent-observability","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fduc-duy-1612\u002FOnline-Delivery-Systems-Web\u002Fblob\u002Fmain\u002F.agents\u002Fskills_archive\u002Fagent-observability\u002FSKILL.md",true,[76],{"path":77,"resourceType":78,"resourceTypeDesc":79,"sizeBytes":80,"sourceHtmlUrl":81},"references\u002Fdetails.md","REFERENCE","参考文档",25201,"https:\u002F\u002Fgithub.com\u002Fduc-duy-1612\u002FOnline-Delivery-Systems-Web\u002Fblob\u002Fmain\u002F.agents\u002Fskills_archive\u002Fagent-observability\u002Freferences\u002Fdetails.md",[83,104,128,153,181,205],{"skillNo":84,"name":85,"nameZh":6,"description":86,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":87,"categories":88,"keywords":92,"publishedAt":43},"01M6Q0FA5FZ410Z33Z3TFQ4DBA","zero-trust","Implement zero-trust network architecture. Configure identity-based access, micro-segmentation, and continuous verification. Use when implementing modern security architectures.","https:\u002F\u002Fgithub.com\u002Fduc-duy-1612\u002FOnline-Delivery-Systems-Web\u002Fblob\u002Fmain\u002F.agents\u002Fskills_archive\u002Fzero-trust\u002FSKILL.md",[89],{"categoryNo":90,"categoryName":91,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000011","运维与部署",[93,94,95,96,97,98,85,99,35,25,100,32,31,30,101,28,102,27,26,103],"ZeRO","trust","zero trust","architecture","assessment","verification","segmentation","configure","active","scope","implementing",{"skillNo":105,"name":106,"nameZh":6,"description":107,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":108,"categories":109,"keywords":110,"publishedAt":43},"01M6Q0F1YZJW3KX5FBKEVZ8CV4","zcode-delegate","Delegate coding tasks to the Z.AI ZCode CLI only when the user explicitly requests it, while the orchestrator retains review and landing responsibility.","https:\u002F\u002Fgithub.com\u002Fduc-duy-1612\u002FOnline-Delivery-Systems-Web\u002Fblob\u002Fmain\u002F.agents\u002Fskills_archive\u002Fzcode-delegate\u002FSKILL.md",[],[111,112,113,114,115,116,117,118,119,120,121,122,123,32,124,31,125,126,28,127],"delegate","zcode","zcode delegate","review","cli","orchestration","tasks","run","Bash","model","node","read","orchestrator","files","desktop app","app","agent-orchestration",{"skillNo":129,"name":130,"nameZh":6,"description":131,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":132,"categories":133,"keywords":134,"publishedAt":43},"01M6Q0ETK41VGNMYEXW0T00AJN","youtube-transcript","Fetch YouTube transcripts through DeepAPI or local fallback tooling and save clean text output.","https:\u002F\u002Fgithub.com\u002Fduc-duy-1612\u002FOnline-Delivery-Systems-Web\u002Fblob\u002Fmain\u002F.agents\u002Fskills_archive\u002Fyoutube-transcript\u002FSKILL.md",[],[135,136,137,138,139,140,141,142,143,144,145,146,147,31,30,148,149,150,151,152],"transcript","youtube transcript","youtube","safe","github","codex","research","license","https","text","fetch","tooling","clean","local","output","deepapi","youtube transcripts","blob",{"skillNo":154,"name":155,"nameZh":6,"description":156,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":157,"categories":158,"keywords":170,"publishedAt":43},"01M6Q0EPPH2PVMDW40017F8WX0","youtube-transcript-skills","Fetch YouTube video transcripts, search videos\u002Fchannels, browse channels, and extract playlists via the getyoutubetranscript.com API - free tier, no card required.","https:\u002F\u002Fgithub.com\u002Fduc-duy-1612\u002FOnline-Delivery-Systems-Web\u002Fblob\u002Fmain\u002F.agents\u002Fskills_archive\u002Fyoutube-transcript-skills\u002FSKILL.md",[159,162,165],{"categoryNo":160,"categoryName":161,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000010","后端与接口",{"categoryNo":163,"categoryName":164,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000016","图像与多媒体",{"categoryNo":166,"categoryName":167,"taxonomyType":168,"taxonomyTypeDesc":169},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[135,136,137,171,138,172,139,140,142,173,174,175,176,145,177,31,30,178,179,180],"youtube transcript skills","gemini","search","api","Video","browse","api-integration","free","card","channels",{"skillNo":182,"name":183,"nameZh":6,"description":184,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":185,"categories":186,"keywords":191,"publishedAt":43},"01M6Q0EAB96PX83W5PTE8A0R8D","youtube-notetaker","Turn YouTube talks into local study notes with slides, transcripts, editable annotations, and a markdown-backed viewer.","https:\u002F\u002Fgithub.com\u002Fduc-duy-1612\u002FOnline-Delivery-Systems-Web\u002Fblob\u002Fmain\u002F.agents\u002Fskills_archive\u002Fyoutube-notetaker\u002FSKILL.md",[187,190],{"categoryNo":188,"categoryName":189,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000003","演示文稿",{"categoryNo":163,"categoryName":164,"taxonomyType":20,"taxonomyTypeDesc":21},[137,192,193,115,138,194,195,196,197,142,175,198,199,200,201,30,202,148,203,204],"youtube notetaker","notetaker","workflow","official","notes","code","markdown","slides","annotations","README","study","dair-academy","viewer",{"skillNo":206,"name":207,"nameZh":6,"description":208,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":209,"categories":210,"keywords":212,"publishedAt":43},"01M6Q0E55F0GW5MX48V8HXS8B5","youtube-full","Fetch YouTube transcripts, search videos, browse channels, and extract playlists via TranscriptAPI — no yt-dlp, no Google API key, works from any cloud server.","https:\u002F\u002Fgithub.com\u002Fduc-duy-1612\u002FOnline-Delivery-Systems-Web\u002Fblob\u002Fmain\u002F.agents\u002Fskills_archive\u002Fyoutube-full\u002FSKILL.md",[211],{"categoryNo":160,"categoryName":161,"taxonomyType":20,"taxonomyTypeDesc":21},[213,137,214,215,138,172,173,216,217,174,175,176,145,218,177,31,30,178,219,151],"youtube full","full","google","server","dlp","credits","automatic"]