DeepEval Synthesizer with Google Gemini

PillowSophie·2026년 6월 14일

DeepEval 을 사용하여 RAG 시스템 평가를 위한 Golden Question & Answer 을 만들 때 생각보다 관련 자료가 부족해 동작하는 코드를 작성하기까지 많은 시행착오에 부딪혀 이를 정리해보고자 한다.

DeepEval 공식 홈페이지의 예제 코드를 보면 model 만 변경해서 넣는 코드만 나온다. 그러나 내가 이를 실행해봤을때 Synthesizer 클래스는 지속해서 OpenAI API Key 가 없다는 에러를 발생시켰다.

결론은 DeepEvalBaseLLM 뿐만아니라 DeepEvalBaseEmbeddingModel 역시 정의되어 Synthesizer 에 넘겨주어야한다. (뒤돌아 생각해보면 너무 당연하다. 임베딩 모델이 있어야 텍스트를 임베딩해서 골든 문장을 만들던가 말던가..)

DeepEvalBaseLLM


"""
공식 문서 예제를 사용해 DeepEvalBaseLLM 을 상속받는 
커스텀 DeepEval LLM Model 클래스 작성
"""

from deepeval.models.base_model import DeepEvalBaseLLM


class TestGoogleGenerativeAI(DeepEvalBaseLLM):
    """Class to implementGoogle Geverative AI for DeepEval"""
    def __init__(self, model):
        self.model = model

    def load_model(self):
        return self.model

    def generate(self, prompt: str) -> str:
        chat_model = self.load_model()
        return chat_model.invoke(prompt).content

    async def a_generate(self, prompt: str) -> str:
        chat_model = self.load_model()
        res = await chat_model.ainvoke(prompt)
        return res.content

    def get_model_name(self):
        return "Google Generative AI Model"
        
"""
langchain_google_genai 라이브러리를 사용해서 gemini 모델 객체를 생성한 후 
위에서 작성한 커스텀 클래스를 사용해 deep eval LLM 모델 객체 생성
"""
from langchain_google_genai import ChatGoogleGenerativeAI

gemini = ChatGoogleGenerativeAI(
    model="gemini-2.5-flash",
    temperature=0
)

deep_eval_gemini = TestGoogleGenerativeAI(model=gemini)

DeepEvalBaseEmbeddingModel

"""
공식 문서의 DeepEvalBaseEmbeddingModel을 상속받는 예제코드를 사용해 
gemini embedding model을 사용하는 embedding model 클래스 정의
"""

from langchain_google_genai import GoogleGenerativeAIEmbeddings
from deepeval.models import DeepEvalBaseEmbeddingModel

class GeminiEmbeddingModel(DeepEvalBaseEmbeddingModel):
    def __init__(self):
        pass

    def load_model(self):
        embeddings = GoogleGenerativeAIEmbeddings(
            model="gemini-embedding-2-preview"
        )

        return embeddings

    def embed_text(self, text: str) -> list[float]:
        embedding_model = self.load_model()
        return embedding_model.embed_query(text)
    def embed_texts(self, texts: list[str]) -> list[list[float]]:
        embedding_model = self.load_model()
        return embedding_model.embed_documents(texts)
    async def a_embed_text(self, text: str) -> list[float]:
        embedding_model = self.load_model()
        return await embedding_model.aembed_query(text)
    async def a_embed_texts(self, texts: list[str]) -> list[list[float]]:
        embedding_model = self.load_model()
        return await embedding_model.aembed_documents(texts)
    def get_model_name(self):
        "Custom gemini Embedding Model"

Synthesizer 구축

import os
import chromadb
from deepeval.synthesizer import Synthesizer
from deepeval.synthesizer.config import ContextConstructionConfig

synthesizer = Synthesizer(model = deep_eval_gemini)

goldens = synthesizer.generate_goldens_from_docs(
    document_paths=[os.path.join(workspace, "tax_refund_info.pdf")],
    context_construction_config=ContextConstructionConfig(
        critic_model=deep_eval_gemini,
        embedder=GeminiEmbeddingModel()
    )
)

결과

langchain_google_genai._common.GoogleGenerativeAIError: Error embedding content (RESOURCE_EXHAUSTED): 429 RESOURCE_EXHAUSTED. {'error': {'code': 429, 'message': 'You exceeded your current quota, please check your plan and billing details. For more information on this error, head to: https://ai.google.dev/gemini-api/docs/rate-limits. To monitor your current usage, head to: https://ai.dev/rate-limit. \n* Quota exceeded for metric: generativelanguage.googleapis.com/embed_content_free_tier_requests, limit: 100, model: gemini-embedding-2\nPlease retry in 27.289403086s.', 'status': 'RESOURCE_EXHAUSTED', 'details': [{'@type': 'type.googleapis.com/google.rpc.Help', 'links': [{'description': 'Learn more about Gemini API quotas', 'url': 'https://ai.google.dev/gemini-api/docs/rate-limits'}]}, {'@type': 'type.googleapis.com/google.rpc.QuotaFailure', 'violations': [{'quotaMetric': 'generativelanguage.googleapis.com/embed_content_free_tier_requests', 'quotaId': 'EmbedContentRequestsPerMinutePerUserPerProjectPerModel-FreeTier', 'quotaDimensions': {'location': 'global', 'model': 'gemini-embedding-2'}, 'quotaValue': '100'}]}, {'@type': 'type.googleapis.com/google.rpc.RetryInfo', 'retryDelay': '27s'}]}}
[Confident AI Synthesizer Log] SUCCESS: Successfully deleted: /tmp/deepeval_chroma_o560xmvi
[Confident AI Synthesizer Log] SUCCESS: Context Construction: Utilizing 0 out of 0 chunks.

잘 되다가 429 와 함께 에러. Google AI Studio 에서 확인해보니 임베딩하려는 pdf 파일크기가 꽤나 커 무료티어 임베딩 시간당 요청 횟수가 초과가 되어있었다. 애초 목적은 model 을 gemini 로 사용해보는 것 이었기 때문에 embedding 모델은 다른 무료 모델을 사용하는 것으로 바꾸어도 무방할 것으로 보임.

임베딩 모델을 설정해서 넘겨주지 않으면 Synthesizer 은 계속해서 OpenAI 임베딩 모델 사용을 위해 API key 를 요청한다.

0개의 댓글