Anthropic Service Client

Source: examples/clients/anthropic_service_client.py

Introduction

Anthropic hosted inference is useful when teams want strong instruction-following and tool-use support from one managed API while keeping application code on provider-neutral LLM contracts. This example exercises the Anthropic service client path with trace capture and deterministic output support for CI.

Technical Implementation

  1. Configure Tracer with JSONL + console sinks so each run emits machine-readable traces.

  2. Build runtime inputs through public package APIs and invoke AnthropicServiceLLMClient.generate(...).

  3. Construct LLMRequest payload fields and execute one representative remote-style call.

  4. Print a compact JSON payload that includes trace metadata for docs and deterministic tests.

        flowchart LR
    A["Prompt input"] --> B["main(): tracing setup"]
    B --> C["AnthropicServiceLLMClient.generate(...)"]
    C --> D["LLMRequest and LLMResponse contracts"]
    C --> E["Tracer JSONL + console events"]
    D --> F["Output payload"]
    E --> F
    F --> G["Printed JSON result"]
    
 1from __future__ import annotations
 2
 3import json
 4from pathlib import Path
 5
 6from design_research_agents import AnthropicServiceLLMClient, Tracer
 7from design_research_agents.llm import LLMMessage, LLMRequest
 8
 9
10def _build_payload() -> dict[str, object]:
11    # Build the hosted Anthropic client using public runtime APIs, then execute one representative request.
12    client = AnthropicServiceLLMClient(
13        name="anthropic-prod",
14        default_model="claude-3-5-haiku-latest",
15        api_key_env="ANTHROPIC_API_KEY",
16        api_key="example-key-for-config-demo",
17        base_url="https://api.anthropic.com",
18        max_retries=3,
19        model_patterns=("claude-3-5-haiku-latest", "claude-3-5-*"),
20    )
21    description = client.describe()
22    prompt = "In one sentence, when should teams run architecture red-team reviews?"
23    response = client.generate(
24        LLMRequest(
25            messages=(
26                LLMMessage(role="system", content="You are a concise engineering design assistant."),
27                LLMMessage(role="user", content=prompt),
28            ),
29            model=client.default_model(),
30            temperature=0.0,
31            max_tokens=120,
32        )
33    )
34    llm_call = {
35        "prompt": prompt,
36        "response_text": response.text,
37        "response_model": response.model,
38        "response_provider": response.provider,
39        "response_has_text": bool(response.text.strip()),
40    }
41    return {
42        "client_class": description["client_class"],
43        "default_model": description["default_model"],
44        "llm_call": llm_call,
45        "backend": description["backend"],
46        "capabilities": description["capabilities"],
47        "server": description["server"],
48    }
49
50
51def main() -> None:
52    """Run traced Anthropic service client call payload."""
53    # Fixed request id keeps traces and docs output deterministic across runs.
54    request_id = "example-clients-anthropic-service-call-001"
55    tracer = Tracer(
56        enabled=True,
57        trace_dir=Path("artifacts/examples/traces"),
58        enable_jsonl=True,
59        enable_console=True,
60    )
61    payload = tracer.run_callable(
62        agent_name="ExamplesAnthropicServiceClientCall",
63        request_id=request_id,
64        input_payload={"scenario": "anthropic-service-client-call"},
65        function=_build_payload,
66    )
67    assert isinstance(payload, dict)
68    payload["example"] = "clients/anthropic_service_client.py"
69    payload["trace"] = tracer.trace_info(request_id)
70    # Print the results
71    print(json.dumps(payload, ensure_ascii=True, indent=2, sort_keys=True))
72
73
74if __name__ == "__main__":
75    main()

Expected Results

Run Command

PYTHONPATH=src python3 examples/clients/anthropic_service_client.py

Example output captured with DRA_EXAMPLE_LLM_MODE=deterministic (timestamps, durations, and trace filenames vary by run):

{
  "backend": {
    "api_key_env": "ANTHROPIC_API_KEY",
    "base_url": "https://api.anthropic.com",
    "default_model": "claude-3-5-haiku-latest",
    "kind": "anthropic_service",
    "max_retries": 3,
    "model_patterns": [
      "claude-3-5-haiku-latest",
      "claude-3-5-*"
    ],
    "name": "anthropic-prod"
  },
  "capabilities": {
    "json_mode": "native",
    "max_context_tokens": null,
    "streaming": true,
    "tool_calling": "native",
    "vision": false
  },
  "client_class": "AnthropicServiceLLMClient",
  "default_model": "claude-3-5-haiku-latest",
  "example": "clients/anthropic_service_client.py",
  "llm_call": {
    "prompt": "In one sentence, when should teams run architecture red-team reviews?",
    "response_has_text": true,
    "response_model": "claude-3-5-haiku-latest",
    "response_provider": "example-test-monkeypatch",
    "response_text": "Run architecture red-team reviews before committing high-impact changes with uncertain failure modes."
  },
  "server": null,
  "trace": {
    "request_id": "example-clients-anthropic-service-call-001",
    "trace_dir": "artifacts/examples/traces",
    "trace_path": "artifacts/examples/traces/run_20260222T162206Z_example-clients-anthropic-service-call-001.jsonl"
  }
}

References