Trong thời đại AI bùng nổ 2026, việc xây dựng công cụ viết bài khoa học tự động không còn là việc của các tập đoàn lớn. Với chi phí API giảm đến 95% so với 2024, bất kỳ nhà phát triển cá nhân nào cũng có thể tạo ra một ứng dụng hoàn chỉnh. Bài viết này sẽ hướng dẫn bạn từ con số 0 đến production-ready một AI Academic Writing Tool với hai tính năng cốt lõi: 流式响应 (Streaming Response)引用生成 (Citation Generation).

So sánh chi phí API 2026 — Con số khiến bạn phải suy nghĩ lại

Trước khi viết dòng code đầu tiên, hãy cùng xem bức tranh tài chính thực tế năm 2026. Dữ liệu được cập nhật từ nhiều nguồn đáng tin cậy, chính xác đến cent:

ModelInput ($/MTok)Output ($/MTok)10M token/tháng
GPT-4.1$2.50$8.00$525
Claude Sonnet 4.5$3$15.00$900
Gemini 2.5 Flash$0.30$2.50$140
DeepSeek V3.2$0.27$0.42$34.50

Bạn thấy đấy, DeepSeek V3.2 rẻ hơn GPT-4.1 đến 19 lần về chi phí output. Nếu bạn đang xây dựng tool viết bài khoa học với 10 triệu token output mỗi tháng, sự chênh lệch lên đến $490.50/tháng — đủ để thuê một nghiên cứu sinh part-time.

Với HolySheep AI, bạn được hưởng tỷ giá ưu đãi ¥1 = $1 (tiết kiệm 85%+ so với các nền tảng khác), hỗ trợ WeChat/Alipay, độ trễ dưới 50ms, và tín dụng miễn phí khi đăng ký. Đây là lựa chọn tối ưu cho developer Việt Nam muốn build ứng dụng AI với chi phí thấp nhất.

Tại sao Streaming Response quan trọng trong viết bài khoa học?

Khi viết một bài báo khoa học 5000 từ, thời gian chờ đợi có thể lên đến 30-60 giây nếu chờ response hoàn chỉnh. Người dùng sẽ nghĩ app bị treo và đóng lại. Streaming response giúp:

Kiến trúc hệ thống hoàn chỉnh

1. Backend Python — FastAPI + Streaming

# requirements.txt

fastapi==0.115.0

uvicorn==0.32.0

httpx==0.28.1

sse-starlette==2.1.0

pydantic==2.10.0

import asyncio import json from typing import AsyncGenerator, Optional from fastapi import FastAPI, HTTPException from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import StreamingResponse from pydantic import BaseModel import httpx app = FastAPI(title="AI Academic Writing Tool") app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) class CitationRequest(BaseModel): topic: str style: str = "APA" # APA, MLA, Chicago, IEEE num_sources: int = 5 language: str = "en" class StreamRequest(BaseModel): prompt: str model: str = "gpt-4.1" temperature: float = 0.7 max_tokens: int = 4000

Lưu ý: KHÔNG dùng api.openai.com hoặc api.anthropic.com

HOLYSHEEP_BASE_URL = "https://api.holysheep.ai/v1" async def stream_ai_response( prompt: str, model: str, api_key: str, temperature: float = 0.7, max_tokens: int = 4000 ) -> AsyncGenerator[str, None]: """ Stream response từ HolySheep API Độ trễ thực tế: <50ms với server nearby """ async with httpx.AsyncClient(timeout=120.0) as client: payload = { "model": model, "messages": [ { "role": "system", "content": "You are an expert academic writing assistant. Provide well-structured, citeable content." }, { "role": "user", "content": prompt } ], "temperature": temperature, "max_tokens": max_tokens, "stream": True # Bật streaming mode } headers = { "Authorization": f"Bearer {api_key}", "Content-Type": "application/json" } accumulated_content = "" async with client.stream( "POST", f"{HOLYSHEEP_BASE_URL}/chat/completions", json=payload, headers=headers ) as response: if response.status_code != 200: error_text = await response.text() yield f"data: {json.dumps({'error': f'API Error: {response.status_code}', 'detail': error_text})}\n\n" return # Parse SSE stream async for line in response.aiter_lines(): if line.startswith("data: "): data = line[6:] # Remove "data: " prefix if data == "[DONE]": yield "data: [DONE]\n\n" break try: chunk = json.loads(data) if "choices" in chunk and len(chunk["choices"]) > 0: delta = chunk["choices"][0].get("delta", {}) if "content" in delta: content_piece = delta["content"] accumulated_content += content_piece # Gửi chunk với số token đã dùng (ước tính) yield f"data: {json.dumps({ 'content': content_piece, 'accumulated': accumulated_content, 'done': False })}\n\n" # Simulate typing effect (tùy chọn, có thể bỏ) await asyncio.sleep(0.01) except json.JSONDecodeError: continue # Final chunk yield f"data: {json.dumps({'content': '', 'accumulated': accumulated_content, 'done': True})}\n\n" @app.get("/") async def root(): return {"status": "ok", "service": "AI Academic Writing Tool", "version": "1.0.0"} @app.post("/stream/academic-write") async def stream_academic_write( request: StreamRequest, api_key: str ): """ API endpoint cho viết bài khoa học streaming """ if not api_key: raise HTTPException(status_code=401, detail="API key required") academic_prompt = f""" Write a comprehensive academic section on the following topic. Include proper citations in {request.style} format. Topic: {request.prompt} Requirements: 1. Structure: Introduction, Body, Conclusion 2. Include in-text citations marked with [CITATION-N] 3. Provide a reference list at the end 4. Use formal academic language 5. Minimum 1500 words """ return StreamingResponse( stream_ai_response( prompt=academic_prompt, model=request.model, api_key=api_key, temperature=request.temperature, max_tokens=request.max_tokens ), media_type="text/event-stream", headers={ "Cache-Control": "no-cache", "Connection": "keep-alive", "X-Accel-Buffering": "no" } ) if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8000)

2. Frontend React — Real-time Streaming UI

// components/AcademicWriter.tsx
import React, { useState, useRef, useEffect } from 'react';

interface StreamChunk {
  content: string;
  accumulated: string;
  done: boolean;
  error?: string;
}

interface CitationSource {
  id: number;
  title: string;
  authors: string;
  year: number;
  journal: string;
  doi?: string;
}

export const AcademicWriter: React.FC = () => {
  const [input, setInput] = useState('');
  const [output, setOutput] = useState('');
  const [isStreaming, setIsStreaming] = useState(false);
  const [error, setError] = useState(null);
  const [wordCount, setWordCount] = useState(0);
  const [progress, setProgress] = useState(0);
  const [citationStyle, setCitationStyle] = useState<'APA' | 'MLA' | 'Chicago' | 'IEEE'>('APA');
  const [sources, setSources] = useState<CitationSource[]>([]);
  const outputRef = useRef<HTMLDivElement>(null);
  const abortControllerRef = useRef<AbortController | null>(null);

  // Auto-scroll to bottom when new content arrives
  useEffect(() => {
    if (outputRef.current) {
      outputRef.current.scrollTop = outputRef.current.scrollHeight;
    }
    // Update word count
    const words = output.trim().split(/\s+/).filter(w => w.length > 0).length;
    setWordCount(words);
  }, [output]);

  const generateAcademicContent = async () => {
    if (!input.trim()) return;

    // Cleanup previous request
    if (abortControllerRef.current) {
      abortControllerRef.current.abort();
    }
    abortControllerRef.current = new AbortController();

    setIsStreaming(true);
    setOutput('');
    setError(null);
    setProgress(0);
    setSources([]);

    try {
      const response = await fetch('http://localhost:8000/stream/academic-write', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          prompt: input,
          model: 'gpt-4.1',
          temperature: 0.7,
          max_tokens: 4000
        }),
        signal: abortControllerRef.current.signal
      });

      if (!response.ok) {
        throw new Error(HTTP error! status: ${response.status});
      }

      const reader = response.body?.getReader();
      const decoder = new TextDecoder();
      let buffer = '';

      if (!reader) {
        throw new Error('Response body is null');
      }

      while (true) {
        const { done, value } = await reader.read();
        
        if (done) break;

        buffer += decoder.decode(value, { stream: true });
        const lines = buffer.split('\n');
        buffer = lines.pop() || ''; // Keep incomplete line in buffer

        for (const line of lines) {
          if (line.startsWith('data: ')) {
            const data = line.slice(6);
            
            if (data === '[DONE]') {
              setIsStreaming(false);
              setProgress(100);
              continue;
            }

            try {
              const chunk: StreamChunk = JSON.parse(data);
              
              if (chunk.error) {
                setError(chunk.error);
                setIsStreaming(false);
                return;
              }

              if (chunk.content) {
                setOutput(prev => prev + chunk.content);
                // Estimate progress based on accumulated length
                const estimatedTotal = 15000; // 15k chars for 1500 words
                const currentProgress = Math.min(
                  Math.round((chunk.accumulated.length / estimatedTotal) * 100),
                  99
                );
                setProgress(currentProgress);
              }

            } catch (e) {
              console.error('Parse error:', e);
            }
          }
        }
      }

      setIsStreaming(false);
      setProgress(100);

    } catch (err: any) {
      if (err.name === 'AbortError') {
        console.log('Request was cancelled');
      } else {
        setError(err.message || 'An error occurred');
        setIsStreaming(false);
      }
    }
  };

  const cancelGeneration = () => {
    if (abortControllerRef.current) {
      abortControllerRef.current.abort();
      setIsStreaming(false);
    }
  };

  const copyToClipboard = () => {
    navigator.clipboard.writeText(output);
  };

  const downloadAsDocx = () => {
    // Simplified download - in production use docx library
    const blob = new Blob([output], { type: 'text/plain' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = 'academic_output.txt';
    a.click();
    URL.revokeObjectURL(url);
  };

  return (
    <div className="academic-writer">
      <h2>AI Academic Writing Assistant</h2>
      
      {/* Input Section */}
      <div className="input-section">
        <label>Research Topic / Question:</label>
        <textarea
          value={input}
          onChange={(e) => setInput(e.target.value)}
          placeholder="Enter your research topic or question..."
          rows={4}
          disabled={isStreaming}
        />
        
        <div className="options">
          <label>
            Citation Style:
            <select
              value={citationStyle}
              onChange={(e) => setCitationStyle(e.target.value as any)}
              disabled={isStreaming}
            >
              <option value="APA">APA 7th Edition</option>
              <option value="MLA">MLA 9th Edition</option>
              <option value="Chicago">Chicago 17th Edition</option>
              <option value="IEEE">IEEE</option>
            </select>
          </label>
        </div>

        <div className="actions">
          {!isStreaming ? (
            <button onClick={generateAcademicContent}>
              Generate Content
            </button>
          ) : (
            <button onClick={cancelGeneration} className="cancel-btn">
              Stop Generation
            </button>
          )}
        </div>
      </div>

      {/* Status Bar */}
      {isStreaming && (
        <div className="status-bar">
          <div className="progress-container">
            <div 
              className="progress-bar" 
              style={{ width: ${progress}% }}
            />
          </div>
          <span>{progress}% - Generating...</span>
        </div>
      )}

      {/* Error Display */}
      {error && (
        <div className="error-message">
          ❌ Error: {error}
        </div>
      )}

      {/* Output Section */}
      <div className="output-section" ref={outputRef}>
        <div className="output-header">
          <span>Generated Content ({wordCount} words)</span>
          {output && (
            <div className="output-actions">
              <button onClick={copyToClipboard}>📋 Copy</button>
              <button onClick={downloadAsDocx}>📥 Download</button>
            </div>
          )}
        </div>
        <div className="output-content">
          {output || <span className="placeholder">Generated content will appear here...</span>}
        </div>
      </div>

      {/* Citations Section */}
      {sources.length > 0 && (
        <div className="citations-section">
          <h3>References ({citationStyle} Format)</h3>
          <ol>
            {sources.map((source) => (
              <li key={source.id}>
                {source.authors} ({source.year}). {source.title}. {source.journal}.
                {source.doi && <em> DOI: {source.doi}</em>}
              </li>
            ))}
          </ol>
        </div>
      )}
    </div>
  );
};

export default AcademicWriter;

3. Citation Generation Module — Tách riêng để tái sử dụng

# citation_generator.py
"""
Citation Generation Module
Hỗ trợ: APA 7th, MLA 9th, Chicago 17th, IEEE
"""

from typing import List, Dict, Optional
from dataclasses import dataclass
from enum import Enum
import re

class CitationStyle(Enum):
    APA = "APA"
    MLA = "MLA"
    CHICAGO = "Chicago"
    IEEE = "IEEE"

@dataclass
class CitationSource:
    """Cấu trúc dữ liệu cho một nguồn trích dẫn"""
    id: int
    title: str
    authors: List[str]  # ["Nguyen Van A", "Tran Thi B"]
    year: int
    journal: Optional[str] = None
    book_title: Optional[str] = None
    publisher: Optional[str] = None
    doi: Optional[str] = None
    url: Optional[str] = None
    volume: Optional[str] = None
    issue: Optional[str] = None
    pages: Optional[str] = None
    access_date: Optional[str] = None

class CitationGenerator:
    """Generator cho các định dạng trích dẫn phổ biến"""
    
    def __init__(self):
        self.sources: List[CitationSource] = []
    
    def add_source(self, source: CitationSource) -> int:
        """Thêm nguồn và trả về citation ID"""
        source.id = len(self.sources) + 1
        self.sources.append(source)
        return source.id
    
    def generate_reference_list(self, style: CitationStyle) -> str:
        """Tạo danh sách tài liệu tham khảo"""
        if style == CitationStyle.APA:
            return self._apa_reference_list()
        elif style == CitationStyle.MLA:
            return self._mla_reference_list()
        elif style == CitationStyle.CHICAGO:
            return self._chicago_reference_list()
        elif style == CitationStyle.IEEE:
            return self._ieee_reference_list()
        return ""
    
    def _format_authors_apa(self, authors: List[str]) -> str:
        """Định dạng tác giả theo APA: A, B., & C, D."""
        if len(authors) == 1:
            return self._format_single_author_apa(authors[0])
        elif len(authors) == 2:
            return f"{self._format_single_author_apa(authors[0])}, & {self._format_single_author_apa(authors[1])}"
        elif len(authors) <= 20:
            formatted = [self._format_single_author_apa(a) for a in authors]
            return f"{', '.join(formatted[:-1])}, & {formatted[-1]}"
        else:
            # More than 20 authors
            formatted = [self._format_single_author_apa(a) for a in authors[:19]]
            formatted.append(f"... & {self._format_single_author_apa(authors[-1])}")
            return ", ".join(formatted)
    
    def _format_single_author_apa(self, name: str) -> str:
        """Định dạng tên tác giả đơn lẻ APA: Nguyen, V. A."""
        parts = name.strip().split()
        if len(parts) >= 2:
            last_name = parts[-1]
            initials = " ".join([p[0] + "." for p in parts[:-1]])
            return f"{last_name}, {initials}"
        return name
    
    def _apa_reference_list(self) -> str:
        """Tạo danh sách tài liệu theo APA 7th Edition"""
        references = []
        for source in self.sources:
            authors = self._format_authors_apa(source.authors)
            year = f"({source.year})"
            
            if source.journal:
                # Journal article
                citation = f"{authors} {year}. {source.title}. *{source.journal}*"
                if source.volume:
                    citation += f", *{source.volume}*"
                    if source.issue:
                        citation += f"({source.issue})"
                if source.pages:
                    citation += f", {source.pages}"
                citation += "."
                if source.doi:
                    citation += f" https://doi.org/{source.doi}"
                elif source.url:
                    citation += f" {source.url}"
            
            elif source.book_title:
                # Book
                citation = f"{authors} {year}. *{source.title}*. {source.publisher}."
                if source.doi:
                    citation += f" https://doi.org/{source.doi}"
            
            else:
                citation = f"{authors} {year}. {source.title}."
                if source.url and source.access_date:
                    citation += f" Retrieved {source.access_date}, from {source.url}"
            
            references.append(citation)
        
        return "\n\n".join(references)
    
    def _mla_reference_list(self) -> str:
        """Tạo danh sách tài liệu theo MLA 9th Edition"""
        references = []
        for source in self.sources:
            # MLA format: Author. "Title." *Journal*, vol. X, no. Y, Year, pp. Z-Z.
            if source.journal:
                authors = ", ".join([self._format_author_mla(a) for a in source.authors])
                citation = f"{authors}. \"{source.title}.\" *{source.journal}*"
                if source.volume:
                    citation += f", vol. {source.volume}"
                if source.issue:
                    citation += f", no. {source.issue}"
                citation += f", {source.year}"
                if source.pages:
                    citation += f", pp. {source.pages}"
                citation += "."
            else:
                authors = ", ".join([self._format_author_mla(a) for a in source.authors])
                citation = f"{authors}. *{source.title}*. {source.publisher}, {source.year}."
            
            references.append(citation)
        
        return "\n\n".join(references)
    
    def _format_author_mla(self, name: str) -> str:
        """MLA: Last, First M."""
        parts = name.strip().split()
        if len(parts) >= 2:
            return f"{parts[-1]}, {' '.join([p[0]+'.' for p in parts[:-1]])}"
        return name
    
    def _ieee_reference_list(self) -> str:
        """Tạo danh sách tài liệu theo IEEE"""
        references = []
        for i, source in enumerate(self.sources, 1):
            # IEEE format: [#] A. Author, "Title," Journal, vol. X, no. Y, pp. Z-Z, Year.
            if source.journal:
                authors = ", ".join([self._format_author_ieee(a) for a in source.authors])
                citation = f"{authors}, \"{source.title},\" *{source.journal}*"
                if source.volume:
                    citation += f", vol. {source.volume}"
                if source.issue:
                    citation += f", no. {source.issue}"
                if source.pages:
                    citation += f", pp. {source.pages}"
                citation += f", {source.year}."
            else:
                authors = ", ".join([self._format_author_ieee(a) for a in source.authors])
                citation = f"{authors}, *{source.title}*. {source.publisher}, {source.year}."
            
            references.append(f"[{i}] {citation}")
        
        return "\n\n".join(references)
    
    def _format_author_ieee(self, name: str) -> str:
        """IEEE: First M. Last"""
        parts = name.strip().split()
        if len(parts) >= 2:
            first = " ".join([p for p in parts[:-1]])
            return f"{first} {parts[-1]}"
        return name
    
    def _chicago_reference_list(self) -> str:
        """Tạo danh sách tài liệu theo Chicago 17th Edition (Notes-Bibliography)"""
        references = []
        for source in self.sources:
            if source.journal:
                authors = ", ".join(source.authors)
                citation = f"{authors}. \"{source.title}.\" *{source.journal}*"
                if source.volume:
                    citation += f" {source.volume}"
                    if source.issue:
                        citation += f", no. {source.issue}"
                citation += f" ({source.year})"
                if source.pages:
                    citation += f": {source.pages}"
                citation += "."
                if source.doi:
                    citation += f" https://doi.org/{source.doi}."
            else:
                authors = ", ".join(source.authors)
                citation = f"{authors}. *{source.title}*. {source.publisher}, {source.year}."
            
            references.append(citation)
        
        return "\n\n".join(references)
    
    def extract_citations_from_text(self, text: str) -> List[str]:
        """Trích xuất các citation markers từ text: [CITATION-1], [CITATION-2], ..."""
        pattern = r'\[CITATION-(\d+)\]'
        matches = re.findall(pattern, text)
        return [f"[CITATION-{m}]" for m in sorted(set(matches), key=int)]
    
    def link_citations(self, text: str) -> str:
        """Liên kết citation markers với reference list"""
        citations = self.extract_citations_from_text(text)
        references = self.generate_reference_list(CitationStyle.APA)
        
        if citations and references:
            return f"{text}\n\n---\n\n## References\n\n{references}"
        return text


Ví dụ sử dụng

if __name__ == "__main__": generator = CitationGenerator() # Thêm các nguồn mẫu source1 = CitationSource( id=1, title="Deep Learning for Natural Language Processing", authors=["Nguyen Van A", "Tran Thi B", "Le Van C"], year=2025, journal="Journal of Machine Learning", volume="15", issue="3", pages="245-267", doi="10.1234/jml.2025.015" ) source2 = CitationSource( id=2, title="Introduction to Artificial Intelligence", authors=["Smith, John"], year=2024, book_title="Introduction to Artificial Intelligence", publisher="MIT Press" ) generator.add_source(source1) generator.add_source(source2) print("=== APA 7th Edition ===") print(generator.generate_reference_list(CitationStyle.APA)) print("\n=== IEEE Format ===") print(generator.generate_reference_list(CitationStyle.IEEE)) # Test citation extraction sample_text = "Deep learning has revolutionized NLP [CITATION-1]. Recent advances [CITATION-2] show promise." print("\n=== Extracted Citations ===") print(generator.extract_citations_from_text(sample_text))

Tích hợp với HolyShehep AI — Code hoàn chỉnh

# holysheep_integration.py
"""
Kịch bản thực chiến: Tích hợp HolySheep AI cho Academic Writing Tool
Chi phí thực tế với DeepSeek V3.2: $0.42/MTok output
So với OpenAI GPT-4.1: $8/MTok → Tiết kiệm 95%
"""

import asyncio
import httpx
from typing import AsyncGenerator, Dict, Any

HOLYSHEEP_API_KEY = "YOUR_HOLYSHEEP_API_KEY"  # Thay bằng key thực của bạn
HOLYSHEEP_BASE_URL = "https://api.holysheep.ai/v1"

async def academic_completion_with_citations(
    topic: str,
    style: str = "APA",
    num_sources: int = 5
) -> AsyncGenerator[Dict[str, Any], None]:
    """
    Hoàn thành viết bài khoa học với trích dẫn tự động
    Sử dụng DeepSeek V3.2 để tối ưu chi phí
    """
    
    prompt = f"""
    Write a comprehensive academic paragraph on the following topic.
    Include specific in-text citations using [CITATION-N] format where N is the reference number.
    
    Topic: {topic}
    Citation Style: {style}
    Number of References: {num_sources}
    
    Output format:
    1. Academic paragraph with in-text citations
    2. Reference list at the end in {style} format
    
    Generate realistic citations based on the topic. Make sure:
    - Each [CITATION-N] in the text has a corresponding entry in the reference list
    - References are realistic (real journals, plausible authors, valid DOI formats)
    """
    
    async with httpx.AsyncClient(timeout=120.0) as client:
        
        # Model mapping - DeepSeek V3.2 cho chi phí thấp nhất
        # $0.42/MTok output vs $8/MTok của GPT-4.1
        model = "deepseek-v3.2"
        
        payload = {
            "model": model,
            "messages": [
                {
                    "role": "system",
                    "content": "You are an expert academic writing assistant specializing in creating well-researched, properly cited academic content."
                },
                {
                    "role": "user", 
                    "content": prompt
                }
            ],
            "temperature": 0.3,  # Lower for more factual content
            "max_tokens": 3000,
            "stream": True
        }
        
        headers = {
            "Authorization": f"Bearer {HOLYSHEEP_API_KEY}",
            "Content-Type": "application/json"
        }
        
        accumulated_text = ""
        
        async with client.stream(
            "POST",
            f"{HOLYSHEEP_BASE_URL}/chat/completions",
            json=payload,
            headers=headers
        ) as response:
            
            if response.status_code != 200:
                error_detail = await response.text()
                yield {
                    "type": "error",
                    "message": f"API Error {response.status_code}: {error_detail}"
                }
                return
            
            async for line in response.aiter_lines():
                if not line.startswith("data: "):
                    continue
                
                data = line[6:]
                
                if data == "[DONE]":
                    yield {
                        "type": "done",
                        "full_text": accumulated_text,
                        "tokens_used": len(accumulated_text) // 4  # Rough estimate
                    }
                    break
                
                try:
                    chunk = __import__('json').loads(data)
                    delta = chunk.get("choices", [{}])[0].get("delta", {})
                    content = delta.get("content", "")
                    
                    if content:
                        accumulated_text += content
                        yield {
                            "type": "chunk",
                            "content": content,
                            "full_text": accumulated_text
                        }
                        
                except Exception as e:
                    continue

async def estimate_cost(model: str, token_count: int) -> Dict[str, float]:
    """Ước tính chi phí cho model đã chọn"""
    
    pricing = {
        "gpt-4.1": {"input": 2.50, "output": 8.00},
        "claude-sonnet-4.5": {"input": 3.00, "output": 15.00},
        "gemini-2.5-flash": {"input": 0.30, "output": 2.50},
        "deepseek-v3.2": {"input": 0.27, "output": 0.42}
    }
    
    if model not in pricing:
        model