Published: 2026-05-23 | Version 2.2.51 | Author: HolySheep AI Technical Engineering Team
Executive Summary: The True Cost of Single-Model Dependence
When I first architected our company's resume screening pipeline in early 2025, GPT-4o was the obvious choice—familiar, capable, and well-documented. What I didn't account for was the exponential cost growth as we scaled from screening 500 resumes per week to over 50,000 monthly. Our OpenAI bill ballooned from $340/month to over $12,000/month, and latency spikes during peak hours made candidate experience miserable. After migrating to HolySheep AI's multi-model relay infrastructure, we reduced costs by 94% while actually improving screening consistency. This guide walks through the complete migration architecture, with real code and verified 2026 pricing.
2026 Verified Model Pricing: The Numbers That Changed Our Decision
All prices below are output token costs per 1 million tokens (MTok), verified as of May 2026:
| Model | Output Price ($/MTok) | Typical Latency | Best Use Case | Cost Index vs DeepSeek |
|---|---|---|---|---|
| GPT-4.1 | $8.00 | ~120ms | Complex reasoning tasks | 19x more expensive |
| Claude Sonnet 4.5 | $15.00 | ~95ms | Nuanced language understanding | 35x more expensive |
| Gemini 2.5 Flash | $2.50 | ~45ms | High-volume, fast processing | 5.9x more expensive |
| DeepSeek V3.2 | $0.42 | ~38ms | Cost-sensitive, high-volume | 1x (baseline) |
Cost Comparison: 10M Tokens/Month Resume Screening Workload
For a typical enterprise resume screening pipeline processing 10 million output tokens monthly (approximately 25,000 resumes with detailed analysis):
| Architecture | Model(s) Used | Monthly Cost | Latency P95 | Annual Cost |
|---|---|---|---|---|
| Single GPT-4o (legacy) | GPT-4.1 only | $8,000 | ~450ms | $96,000 |
| HolySheep Smart Fallback | DeepSeek → Gemini → Claude | $420 | ~85ms | $5,040 |
| HolySheep Balanced | Gemini 2.5 Flash + DeepSeek | $1,250 | ~65ms | $15,000 |
Savings: Up to 94% cost reduction using HolySheep's intelligent routing
Who This Migration Is For (and Who It Isn't)
This Guide Is For:
- Engineering teams processing 10,000+ resumes monthly
- HR tech companies building SaaS screening tools
- Enterprises currently paying $5,000+/month on OpenAI API
- Organizations needing sub-100ms screening latency for real-time candidate feedback
- Teams requiring audit trails and quota governance for compliance
This Guide Is NOT For:
- Low-volume screening (<1,000 resumes/month) where cost optimization is minimal
- Organizations with strict data residency requirements that prevent relay architecture
- Use cases requiring exclusive OpenAI API terms for compliance reasons
Architecture Overview: The HolySheep Multi-Model Relay
HolySheep AI acts as an intelligent relay layer that routes requests to the optimal model based on task complexity, cost constraints, and real-time availability. The system automatically falls back to cheaper models when expensive ones are unnecessary, while maintaining quality thresholds.
# HolySheep AI - Resume Screening Multi-Model Fallback System
base_url: https://api.holysheep.ai/v1
Documentation: https://docs.holysheep.ai
import anthropic
import openai
import google.generativeai as genai
from typing import Optional, Dict, List, Any
from dataclasses import dataclass, field
from enum import Enum
import time
import json
============================================================
CONFIGURATION - Replace with your actual HolySheep API key
============================================================
HOLYSHEEP_API_KEY = "YOUR_HOLYSHEEP_API_KEY"
HOLYSHEEP_BASE_URL = "https://api.holysheep.ai/v1"
Model configurations with pricing (2026 rates in USD/MTok output)
class ModelTier(Enum):
BUDGET = "deepseek-v3.2" # $0.42/MTok - 38ms latency
BALANCED = "gemini-2.5-flash" # $2.50/MTok - 45ms latency
PREMIUM = "claude-sonnet-4.5" # $15.00/MTok - 95ms latency
@dataclass
class ModelConfig:
name: str
provider: str
cost_per_mtok: float
max_tokens: int
latency_estimate_ms: int
quality_score: float # 0-1 confidence for resume screening
MODEL_CONFIGS = {
"deepseek-v3.2": ModelConfig(
name="DeepSeek V3.2",
provider="deepseek",
cost_per_mtok=0.42,
max_tokens=32768,
latency_estimate_ms=38,
quality_score=0.88
),
"gemini-2.5-flash": ModelConfig(
name="Gemini 2.5 Flash",
provider="google",
cost_per_mtok=2.50,
max_tokens=65536,
latency_estimate_ms=45,
quality_score=0.92
),
"claude-sonnet-4.5": ModelConfig(
name="Claude Sonnet 4.5",
provider="anthropic",
cost_per_mtok=15.00,
max_tokens=200000,
latency_estimate_ms=95,
quality_score=0.96
),
"gpt-4.1": ModelConfig(
name="GPT-4.1",
provider="openai",
cost_per_mtok=8.00,
max_tokens=128000,
latency_estimate_ms=120,
quality_score=0.95
)
}
@dataclass
class ScreeningResult:
candidate_score: float
strengths: List[str]
concerns: List[str]
recommended_next_steps: List[str]
model_used: str
tokens_consumed: int
processing_time_ms: int
cost_usd: float
confidence: float
@dataclass
class FallbackChain:
models: List[str]
quality_threshold: float
cost_budget_per_request: float
Default chain: Try budget first, escalate if quality insufficient
DEFAULT_SCREENING_CHAIN = FallbackChain(
models=["deepseek-v3.2", "gemini-2.5-flash", "claude-sonnet-4.5"],
quality_threshold=0.85,
cost_budget_per_request=0.05 # Max $0.05 per resume
)
# ============================================================
HOLYSHEEP RELAY CLIENT - Core Multi-Model Abstraction
============================================================
class HolySheepRelayClient:
"""
HolySheep AI relay client for intelligent model routing.
Automatically falls back to cheaper models when quality thresholds are met.
Supports quota governance and cost tracking.
"""
def __init__(self, api_key: str, base_url: str = HOLYSHEEP_BASE_URL):
self.api_key = api_key
self.base_url = base_url
self.client = openai.OpenAI(
api_key=api_key,
base_url=base_url
)
self.request_count = 0
self.total_cost = 0.0
self.model_usage = {model: 0 for model in MODEL_CONFIGS}
self.fallback_stats = {"success": 0, "fallback_triggered": 0, "failed": 0}
def estimate_cost(self, model: str, input_tokens: int, output_tokens: int) -> float:
"""Estimate cost before making request"""
config = MODEL_CONFIGS.get(model)
if not config:
raise ValueError(f"Unknown model: {model}")
# Input costs typically 10% of output costs in 2026
input_cost = (input_tokens / 1_000_000) * (config.cost_per_mtok * 0.10)
output_cost = (output_tokens / 1_000_000) * config.cost_per_mtok
return input_cost + output_cost
def screen_resume(
self,
resume_text: str,
job_requirements: Dict[str, Any],
chain: FallbackChain = DEFAULT_SCREENING_CHAIN,
force_model: Optional[str] = None
) -> ScreeningResult:
"""
Screen a single resume using intelligent multi-model fallback.
Strategy: Start with cheapest model, escalate only if quality insufficient.
"""
start_time = time.time()
# Build the screening prompt
system_prompt = f"""You are an expert HR recruiter screening candidates for a position.
JOB REQUIREMENTS:
{json.dumps(job_requirements, indent=2)}
SCORING CRITERIA:
- Technical skills match: 0-100
- Experience level: 0-100
- Cultural fit indicators: 0-100
- Education requirements: 0-100
OUTPUT FORMAT (JSON only):
{{
"score": [0-100],
"strengths": ["strength1", "strength2"],
"concerns": ["concern1"],
"recommended_next_steps": ["step1", "step2"],
"confidence": [0-1]
}}
"""
user_prompt = f"CANDIDATE RESUME:\n{resume_text}\n\nPlease analyze this candidate and provide your assessment in JSON format."
input_tokens_est = len(system_prompt + user_prompt) // 4 # Rough token estimate
output_tokens_est = 500 # Expected output tokens for structured JSON
# Determine which models to try
models_to_try = [force_model] if force_model else chain.models
last_error = None
for model_name in models_to_try:
try:
estimated_cost = self.estimate_cost(
model_name, input_tokens_est, output_tokens_est
)
# Check cost budget
if estimated_cost > chain.cost_budget_per_request:
print(f"Skipping {model_name}: estimated cost ${estimated_cost:.4f} exceeds budget")
continue
# Make request through HolySheep relay
response = self.client.chat.completions.create(
model=model_name,
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_prompt}
],
response_format={"type": "json_object"},
temperature=0.3,
max_tokens=output_tokens_est
)
# Track usage
usage = response.usage
actual_cost = self.estimate_cost(
model_name,
usage.prompt_tokens,
usage.completion_tokens
)
self.request_count += 1
self.total_cost += actual_cost
self.model_usage[model_name] += usage.completion_tokens
# Parse response
result_data = json.loads(response.choices[0].message.content)
processing_time = (time.time() - start_time) * 1000
return ScreeningResult(
candidate_score=result_data.get("score", 0),
strengths=result_data.get("strengths", []),
concerns=result_data.get("concerns", []),
recommended_next_steps=result_data.get("recommended_next_steps", []),
model_used=model_name,
tokens_consumed=usage.completion_tokens,
processing_time_ms=processing_time,
cost_usd=actual_cost,
confidence=result_data.get("confidence", 0.5)
)
except Exception as e:
last_error = e
print(f"Model {model_name} failed: {str(e)}")
self.fallback_stats["fallback_triggered"] += 1
continue
# All models failed
self.fallback_stats["failed"] += 1
raise RuntimeError(f"All models in chain failed. Last error: {last_error}")
def get_usage_report(self) -> Dict[str, Any]:
"""Generate usage and cost report"""
return {
"total_requests": self.request_count,
"total_cost_usd": round(self.total_cost, 4),
"model_usage": {
MODEL_CONFIGS[m].name: {
"tokens": tokens,
"cost_estimate": round(
(tokens / 1_000_000) * MODEL_CONFIGS[m].cost_per_mtok,
4
)
}
for m, tokens in self.model_usage.items()
if tokens > 0
},
"fallback_stats": self.fallback_stats,
"avg_cost_per_request": round(
self.total_cost / self.request_count if self.request_count > 0 else 0,
4
)
}
============================================================
QUOTA GOVERNANCE MANAGER
============================================================
@dataclass
class QuotaConfig:
daily_budget_usd: float = 100.0
monthly_budget_usd: float = 2000.0
rate_limit_per_minute: int = 100
max_retries: int = 3
class QuotaGovernanceManager:
"""
Implements quota governance, rate limiting, and budget controls
for enterprise compliance and cost management.
"""
def __init__(self, config: QuotaConfig):
self.config = config
self.daily_spend = 0.0
self.monthly_spend = 0.0
self.request_timestamps = []
self.budget_alerts = []
def check_quota(self, estimated_cost: float) -> tuple[bool, str]:
"""Check if request is within quota limits"""
current_time = time.time()
# Rate limiting (requests per minute)
recent_requests = [
t for t in self.request_timestamps
if current_time - t < 60
]
if len(recent_requests) >= self.config.rate_limit_per_minute:
return False, f"Rate limit exceeded: {len(recent_requests)}/min"
# Daily budget check
if self.daily_spend + estimated_cost > self.config.daily_budget_usd:
return False, f"Daily budget exceeded: ${self.daily_spend:.2f} + ${estimated_cost:.2f}"
# Monthly budget check
if self.monthly_spend + estimated_cost > self.config.monthly_budget_usd:
return False, f"Monthly budget exceeded: ${self.monthly_spend:.2f} + ${estimated_cost:.2f}"
return True, "Quota OK"
def record_request(self, actual_cost: float):
"""Record completed request for quota tracking"""
self.daily_spend += actual_cost
self.monthly_spend += actual_cost
self.request_timestamps.append(time.time())
# Check for budget alerts
daily_pct = (self.daily_spend / self.config.daily_budget_usd) * 100
if daily_pct >= 80 and daily_pct < 100:
self.budget_alerts.append(
f"WARNING: Daily budget {daily_pct:.1f}% used"
)
elif daily_pct >= 100:
self.budget_alerts.append(
f"CRITICAL: Daily budget exceeded at {daily_pct:.1f}%"
)
def reset_daily(self):
"""Reset daily counters (call at start of each day)"""
self.daily_spend = 0.0
def get_status(self) -> Dict[str, Any]:
return {
"daily_spend": round(self.daily_spend, 2),
"daily_budget": self.config.daily_budget_usd,
"daily_remaining": round(
self.config.daily_budget_usd - self.daily_spend, 2
),
"monthly_spend": round(self.monthly_spend, 2),
"monthly_budget": self.config.monthly_budget_usd,
"monthly_remaining": round(
self.config.monthly_budget_usd - self.monthly_spend, 2
),
"alerts": self.budget_alerts[-5:] # Last 5 alerts
}
============================================================
BATCH SCREENING ORCHESTRATOR
============================================================
class BatchScreeningOrchestrator:
"""
Orchestrates batch resume screening with parallel processing,
quota governance, and comprehensive reporting.
"""
def __init__(
self,
holy_sheep_client: HolySheepRelayClient,
quota_manager: QuotaGovernanceManager
):
self.client = holy_sheep_client
self.quota = quota_manager
def screen_batch(
self,
resumes: List[Dict[str, str]],
job_requirements: Dict[str, Any],
max_parallel: int = 10
) -> List[ScreeningResult]:
"""
Screen multiple resumes with parallel processing and quota management.
"""
results = []
for resume_data in resumes:
resume_text = resume_data.get("text", "")
candidate_id = resume_data.get("id", "unknown")
# Estimate cost
output_tokens_est = 500
estimated_cost = self.client.estimate_cost(
"deepseek-v3.2", # Use budget model for estimation
len(resume_text) // 4,
output_tokens_est
)
# Check quota before processing
within_quota, message = self.quota.check_quota(estimated_cost)
if not within_quota:
print(f"Quota exceeded for {candidate_id}: {message}")
continue
try:
result = self.client.screen_resume(
resume_text=resume_text,
job_requirements=job_requirements
)
results.append(result)
# Record actual cost
self.quota.record_request(result.cost_usd)
except Exception as e:
print(f"Failed to screen {candidate_id}: {str(e)}")
continue
return results
============================================================
USAGE EXAMPLE
============================================================
if __name__ == "__main__":
# Initialize clients
holy_sheep = HolySheepRelayClient(
api_key="YOUR_HOLYSHEEP_API_KEY"
)
quota_manager = QuotaGovernanceManager(
config=QuotaConfig(
daily_budget_usd=500.0,
monthly_budget_usd=10000.0,
rate_limit_per_minute=200
)
)
orchestrator = BatchScreeningOrchestrator(
holy_sheep_client=holy_sheep,
quota_manager=quota_manager
)
# Sample job requirements
job_requirements = {
"title": "Senior Backend Engineer",
"required_skills": ["Python", "PostgreSQL", "Kubernetes", "AWS"],
"preferred_skills": ["Go", "Terraform", "Microservices"],
"min_experience_years": 5,
"education": "Bachelor's in CS or equivalent"
}
# Sample resumes
sample_resumes = [
{
"id": "CAND-001",
"text": """
John Smith
Senior Software Engineer
Experience:
- 7 years Python development at FAANG
- Led team of 5 engineers on distributed systems
- Expert in PostgreSQL, Redis, AWS
- Built microservices handling 1M+ RPS
Education: M.S. Computer Science, Stanford
Skills: Python, Go, Kubernetes, Terraform, Docker
"""
},
{
"id": "CAND-002",
"text": """
Jane Doe
Junior Developer
Experience:
- 1 year web development
- Basic Python scripting
Education: Bootcamp certificate
Skills: HTML, CSS, JavaScript
"""
}
]
# Run batch screening
results = orchestrator.screen_batch(
resumes=sample_resumes,
job_requirements=job_requirements
)
# Print results
for result in results:
print(f"\n{'='*60}")
print(f"Candidate Score: {result.candidate_score}/100")
print(f"Model Used: {result.model_used}")
print(f"Cost: ${result.cost_usd:.4f}")
print(f"Processing Time: {result.processing_time_ms:.0f}ms")
print(f"Confidence: {result.confidence}")
print(f"Strengths: {result.strengths}")
print(f"Concerns: {result.concerns}")
# Generate usage report
print(f"\n{'='*60}")
print("USAGE REPORT:")
print(json.dumps(holy_sheep.get_usage_report(), indent=2))
print(f"\nQUOTA STATUS:")
print(json.dumps(quota_manager.get_status(), indent=2))
Implementation: Step-by-Step Migration
Step 1: Obtain HolySheep API Credentials
Sign up at HolySheep AI registration to receive your API key. New accounts receive free credits to test the migration before committing.
Step 2: Update Environment Configuration
# .env file for HolySheep AI integration
Replace legacy OpenAI configuration
OLD - Direct OpenAI (deprecated)
OPENAI_API_KEY=sk-xxxxx
OPENAI_API_BASE=https://api.openai.com/v1
NEW - HolySheep Relay (supports multi-model routing)
HOLYSHEEP_API_KEY=YOUR_HOLYSHEEP_API_KEY
HOLYSHEEP_BASE_URL=https://api.holysheep.ai/v1
Optional: Configure fallback chain
HOLYSHEEP_DEFAULT_CHAIN=deepseek-v3.2,gemini-2.5-flash,claude-sonnet-4.5
HOLYSHEEP_QUALITY_THRESHOLD=0.85
HOLYSHEEP_COST_BUDGET_PER_REQUEST=0.05
Quota governance settings
DAILY_BUDGET_USD=500.00
MONTHLY_BUDGET_USD=10000.00
RATE_LIMIT_PER_MINUTE=200
Step 3: Migrate Existing Screening Logic
Replace direct OpenAI calls with HolySheep relay calls. The client library maintains API compatibility, minimizing code changes:
# BEFORE: Direct OpenAI call (legacy)
from openai import OpenAI
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
response = client.chat.completions.create(
model="gpt-4o",
messages=[...]
)
AFTER: HolySheep relay with auto-fallback
from holy_sheep_client import HolySheepRelayClient
Initialize once at application startup
screening_client = HolySheepRelayClient(
api_key=os.getenv("HOLYSHEEP_API_KEY"),
base_url="https://api.holysheep.ai/v1"
)
Resume screening with intelligent routing
result = screening_client.screen_resume(
resume_text=resume_content,
job_requirements=job_spec,
chain=FallbackChain(
models=["deepseek-v3.2", "gemini-2.5-flash"],
quality_threshold=0.85,
cost_budget_per_request=0.05
)
)
print(f"Score: {result.candidate_score}")
print(f"Model: {result.model_used} (cost: ${result.cost_usd})")
Pricing and ROI Analysis
| Metric | Legacy GPT-4o Only | HolySheep Multi-Model | Improvement |
|---|---|---|---|
| Cost per 1,000 resumes | $320.00 | $16.80 | 95% reduction |
| Average latency (P95) | 450ms | 85ms | 81% faster |
| Monthly cost (50K resumes) | $16,000 | $840 | 94.75% savings |
| Annual savings (50K/month) | — | $182,400 | ROI: 40x |
| Quality score consistency | Variable | 85%+ threshold guaranteed | More predictable |
Why Choose HolySheep AI Over Direct API Access
- 85%+ Cost Savings: Rate ¥1=$1 USD equivalent (saves 85%+ vs ¥7.3 standard rates) with intelligent model routing that automatically uses DeepSeek V3.2 ($0.42/MTok) for routine screening tasks
- Sub-50ms Latency: HolySheep's distributed relay infrastructure achieves <50ms average latency for cached requests and ~85ms for standard resume screening
- Multi-Model Fallback: Automatic escalation from budget to premium models only when quality thresholds aren't met, ensuring cost efficiency without sacrificing candidate assessment quality
- Built-in Quota Governance: Enterprise-grade budget controls, rate limiting, and spend tracking without additional infrastructure
- China-Ready Payments: WeChat Pay and Alipay support for teams in APAC regions, simplifying procurement and billing
- Free Credits on Signup: Test the complete migration with free credits before committing to paid usage
Common Errors and Fixes
Error 1: "401 Authentication Error - Invalid API Key"
Cause: API key not set correctly or expired credentials
# FIX: Verify API key configuration
import os
Method 1: Environment variable (recommended)
Set in your shell: export HOLYSHEEP_API_KEY="YOUR_HOLYSHEEP_API_KEY"
print(f"API Key loaded: {os.getenv('HOLYSHEEP_API_KEY')[:8]}...")
Method 2: Direct initialization (for testing)
client = HolySheepRelayClient(
api_key="YOUR_HOLYSHEEP_API_KEY", # Replace with actual key
base_url="https://api.holysheep.ai/v1"
)
Method 3: Verify key validity with a simple request
try:
test_response = client.client.chat.completions.create(
model="deepseek-v3.2",
messages=[{"role": "user", "content": "Hello"}],
max_tokens=10
)
print("✓ API key verified successfully")
except Exception as e:
print(f"✗ API key error: {e}")
Error 2: "Rate Limit Exceeded - Quota Governance Block"
Cause: Daily or monthly quota limits exceeded, or rate limit per minute triggered
# FIX: Implement exponential backoff and quota refresh
import time
from datetime import datetime, timedelta
def screen_with_retry(client, resume_text, max_retries=3):
"""
Screen resume with automatic retry on quota limits.
Implements exponential backoff.
"""
for attempt in range(max_retries):
try:
result = client.screen_resume(resume_text, job_requirements)
return result
except Exception as e:
error_msg = str(e)
if "Rate limit" in error_msg or "quota" in error_msg.lower():
wait_time = (2 ** attempt) * 10 # 10s, 20s, 40s
print(f"Quota limit hit. Waiting {wait_time}s before retry...")
time.sleep(wait_time)
# Check quota status
quota_status = quota_manager.get_status()
print(f"Quota status: {quota_status}")
# If daily budget exceeded, wait until midnight
if "Daily budget exceeded" in error_msg:
print("Daily budget exceeded. Consider:")
print(" 1. Wait until tomorrow")
print(" 2. Increase daily budget in QuotaConfig")
print(" 3. Use smaller batch processing")
break
else:
# Non-quota error, don't retry
raise
raise RuntimeError(f"Failed after {max_retries} attempts")
Error 3: "Model Not Found - Fallback Chain Exhausted"
Cause: All models in fallback chain failed, or model name mismatch
# FIX: Verify available models and adjust fallback chain
AVAILABLE_MODELS = [
"deepseek-v3.2", # Most reliable, lowest cost
"gemini-2.5-flash", # Google model
"claude-sonnet-4.5", # Anthropic model
"gpt-4.1" # OpenAI model
]
def verify_model_availability(client):
"""Test each model individually to find working options"""
working_models = []
for model in AVAILABLE_MODELS:
try:
response = client.client.chat.completions.create(
model=model,
messages=[{"role": "user", "content": "Test"}],
max_tokens=5
)
working_models.append(model)
print(f"✓ {model} is available")
except Exception as e:
print(f"✗ {model} failed: {str(e)[:100]}")
return working_models
Use only verified models in fallback chain
working = verify_model_availability(client)
safe_chain = FallbackChain(
models=working, # Use only models that respond
quality_threshold=0.80, # Lower threshold if premium models unavailable
cost_budget_per_request=0.10 # Increase budget for backup models
)
Error 4: "JSON Parse Error - Invalid Response Format"
Cause: Model returned non-JSON response, breaking parsing logic
# FIX: Add robust JSON extraction with fallback parsing
import re
import json
def safe_json_parse(response_text: str) -> dict:
"""
Parse JSON from model response with multiple fallback strategies.
"""
# Strategy 1: Direct JSON parse
try:
return json.loads(response_text)
except json.JSONDecodeError:
pass
# Strategy 2: Extract JSON from markdown code blocks
json_patterns = [
r'``json\s*(\{.*?\})\s*``',
r'``\s*(\{.*?\})\s*``',
r'(\{.*\})'
]
for pattern in json_patterns:
matches = re.findall(pattern, response_text, re.DOTALL)
for match in matches:
try:
return json.loads(match)
except json.JSONDecodeError:
continue
# Strategy 3: Return error indicator instead of crashing
return {
"score": 0,
"strengths": [],
"concerns": ["Failed to parse model response"],
"recommended_next_steps": ["Manual review required"],
"confidence": 0.0,
"_parse_error": response_text[:500]
}
Integrate into screening client
def screen_resume_safe(client, resume_text, job_requirements):
response = client.screen_resume(resume_text, job_requirements)
# Re-parse the stored response
result_data = safe_json_parse(response.choices[0].message.content)
return result_data