Why API Costs Easily Get Out of Control

The DeepSeek API is indeed very cheap—about ¥1/million tokens for input and ¥2/million tokens for output. A typical conversation might consume only a few hundred to a few thousand tokens, costing less than a cent. But cost issues often surface after scaling: 100,000 conversations per day × 2,000 tokens each = 200 million tokens per day ≈ ¥200-400/day ≈ ¥6,000-12,000/month. If you add RAG retrieval (extra tokens per retrieval), multi-turn conversations (increasingly long context), and using deepseek-reasoner (reasoning tokens billed separately), monthly bills can easily exceed tens of thousands of yuan.

More insidious is "hidden waste"—many token consumptions produce no value: repeated system prompts (sending the same system prompt with every request), overly long conversation history (user sending the full content of the first turn at turn 15), and ineffective retries (resending the full request after an API timeout). Identifying and eliminating this waste is the first step toward cost optimization.

Strategy 1: Prompt Compression

System prompts are the biggest source of hidden waste. If your system prompt has 500 Chinese characters (about 750 tokens), with 10,000 requests per day, the system prompt alone consumes 7.5 million tokens per day ≈ ¥7.5. Optimization strategies: streamline the system prompt (if 50 characters suffice, don't use 500), cache fixed system prompts (don't generate them dynamically each time), and move infrequently used rules to "on-demand loading" (only attach specific rules when relevant scenarios are detected).

from openai import OpenAI
import hashlib, json, time

client = OpenAI(api_key="your-deepseek-api-key", base_url="https://api.deepseek.com")

class CostOptimizer:
    def __init__(self):
        self.cache = {}  # semantic cache
        self.stats = {"total_tokens":0, "cached_hits":0, "saved_tokens":0}

    def semantic_cache_key(self, messages):
        """Generate semantic cache key"""
        last_user_msg = next((m["content"] for m in reversed(messages) if m["role"]=="user"), "")
        return hashlib.md5(last_user_msg.encode()).hexdigest()

    def call_with_cache(self, messages, model="deepseek-chat", ttl=3600, **kwargs):
        """API call with semantic cache"""
        cache_key = self.semantic_cache_key(messages)
        if cache_key in self.cache:
            entry = self.cache[cache_key]
            if time.time() - entry["timestamp"] < ttl:
                self.stats["cached_hits"] += 1
                self.stats["saved_tokens"] += entry["tokens"]
                print(f"Cache hit! Saved approximately {entry['tokens']} tokens")
                return entry["response"]

        response = client.chat.completions.create(
            model=model, messages=messages, **kwargs
        )
        result = response.choices[0].message.content
        tokens = response.usage.total_tokens
        self.stats["total_tokens"] += tokens
        self.cache[cache_key] = {"response":result, "tokens":tokens, "timestamp":time.time()}
        return result

    def compress_history(self, messages, max_turns=8):
        """Compress conversation history"""
        if len(messages) <= max_turns * 2 + 2:
            return messages
        # Keep system prompt + recent N turns + early summary
        system = [m for m in messages if m["role"]=="system"]
        recent = messages[-(max_turns*2):]
        old = messages[1:-(max_turns*2)]
        if old:
            old_text = "\n".join(f"{m['role']}: {m['content'][:100]}" for m in old)
            summary = client.chat.completions.create(
                model="deepseek-chat",
                messages=[{"role":"user","content":f"Compress into a 50-character summary: {old_text}"}],
                max_tokens=100
            ).choices[0].message.content
            system.append({"role":"system","content":f"[Conversation Summary] {summary}"})
        return system + recent

    def smart_route(self, messages):
        """Smart model routing: simple questions use V3, complex use R1"""
        last_msg = messages[-1]["content"] if messages else ""
        simple_signals = ["hello","thanks","bye","yes","correct","ok"]
        complex_signals = ["analyze","reason","prove","optimize","compare","design"]
        if any(s in last_msg for s in simple_signals) and not any(s in last_msg for s in complex_signals):
    return "deepseek-chat"  # Use V3 for simple questions
        if any(s in last_msg for s in complex_signals):
            return "deepseek-reasoner"  # Use R1 for complex questions
        return "deepseek-chat"  # Default to V3

    def batch_requests(self, requests_list):
        """Batch processing: merge multiple independent requests into one API call"""
        combined = "Please answer the following questions separately, separated by numbers:\n\n"
        for i, req in enumerate(requests_list):
            combined += f"Question {i+1}: {req}\n"
        response = client.chat.completions.create(
            model="deepseek-chat",
            messages=[{"role":"user","content":combined}]
        )
        return response.choices[0].message.content

optimizer = CostOptimizer()
msgs = [{"role":"system","content":"You are an AI assistant"},{"role":"user","content":"What is RAG?"}]
result = optimizer.call_with_cache(msgs)
compressed = optimizer.compress_history(msgs)
model = optimizer.smart_route(msgs)
print(f"Cache stats: {json.dumps(optimizer.stats, ensure_ascii=False)}")

Strategy 2: Multi-Level Cache System

Caching is the most effective way to reduce API costs. Build a three-level cache: exact match cache (same input → same output, suitable for fixed Q&A like FAQ), semantic similarity cache (similar input → reuse output, using embeddings to judge similarity, hit when threshold is above 0.95), and prefix cache (natively supported by DeepSeek API, requests with the same prefix automatically reuse KV Cache). Proper use of caching can reduce API calls by 30%-60%.

Strategy 3: Model Tiered Routing

Not all requests need the most powerful model. Build a router: simple greetings and FAQs → use the smallest model or cache to reply directly; medium complexity questions → use deepseek-chat (V3); high complexity reasoning → use deepseek-reasoner (R1). Tiered routing can keep R1 usage at 10%-20% of total, significantly reducing costs.

Strategy 4: Batch Processing and Asynchronization

Merging multiple independent requests into one API call (batch processing) reduces HTTP round-trip overhead and sometimes offers batch discounts. For non-real-time scenarios (e.g., nightly batch report generation), use asynchronous task queues (Celery/RQ) to accumulate requests and process them centrally during off-peak hours. Batch processing can reduce the cost per request by 20%-40%.

Cost Optimization Effect Tracking

Establish a cost dashboard to track in real-time: daily/weekly/monthly API costs, top consuming features/users, cache hit rate, model usage distribution (V3 vs R1 ratio), and average token consumption per conversation. Cost optimization without data-driven tracking is like feeling an elephant in the dark—you might save 10% in one area but overspend 50% in another.

Fine-Grained Management of Token Consumption

In addition to the optimization strategies mentioned earlier, there are some easily overlooked sources of token consumption that need management: "whitespace characters" in prompts—extra newlines, indentation, and spaces may seem harmless, but they can accumulate to 3-5% of total tokens in large-scale calls. It is recommended to "slim down" messages before sending—merge consecutive newlines and remove leading/trailing whitespace. Unnecessary fields—in Function Calling, the model returns the arguments of function_call; if your function definitions have many unnecessary parameter descriptions, it can significantly increase token consumption. It is recommended to streamline function definitions, keeping only necessary parameters and brief descriptions. Redundant context from RAG retrieval—among the top-k results returned, often only the first 3 are truly useful; the rest may be noise. It is recommended to use a reranker to re-rank and then truncate, keeping only truly relevant context.Cost Attribution and Internal Settlement: In scenarios where multiple teams share an API Key, it is necessary to attribute costs to specific teams or projects for cost control and internal settlement. Implementation: mark team_id and project_id in the metadata of each API call, and aggregate costs by team/project through log analysis. For teams or projects with particularly high costs, set up independent API Keys and budget limits. Large enterprises typically adopt a "central procurement, internal settlement" model—the AI platform team centrally purchases DeepSeek API quotas, and each business team settles internally based on actual usage.

Comprehensive Roadmap for Cost Reduction and Efficiency

If your monthly AI API bill exceeds ¥10,000, it is recommended to implement cost optimization step by step according to the following priorities: Step 1 (immediate effect, complete within 1 week): implement exact match cache + compress system prompts + set max_tokens limits, typically reducing costs by 20-30%. Step 2 (medium investment, complete within 1 month): implement semantic cache + conversation history compression + model tiered routing, can further reduce costs by 20-30%. Step 3 (long-term continuous): establish cost monitoring dashboard + regular cost reviews + batch processing optimization + regularly clean up inactive cache entries. After comprehensive implementation, monthly API costs can typically be reduced by 50%-70%.

Finally, it is important to emphasize that cost optimization is a continuous process, not a one-time project. It is recommended to establish a monthly cost review mechanism—analyze the previous month's cost data at the beginning of each month, identify new sources of waste, evaluate the effectiveness of existing optimization measures, and set optimization goals for the current month. Incorporate cost optimization into the team's OKRs, making cost awareness a shared culture. When everyone realizes that "every 100 meaningless tokens transmitted is wasting the team's budget," costs will naturally be effectively controlled.

Want to orchestrate this skill chain yourself?

Open in Skill Chain →