Sam
Update aduc_framework/engineers/prompt_engine.py
e897ba2 verified
Raw
History Blame
4.24 kB
# aduc_framework/engineers/prompt_engine.py
#
# Copyright (C) August 4, 2025 Carlos Rodrigues dos Santos
#
# Versão 2.0.0 (Context-Aware Prompt Translator)
#
# O PromptEngine atua como o tradutor entre a lógica de tarefa agnóstica
# do Composer e o formato de prompt específico exigido por um LLM.
# Esta versão é consciente do contexto, sabendo diferenciar entre
# prompts que requerem contexto visual (imagens) e os que são apenas texto.
import logging
from pathlib import Path
from typing import Dict
logger = logging.getLogger(__name__)
class PromptEngine:
"""
O PromptEngine traduz prompts genéricos para o formato específico do
modelo de linguagem alvo. Ele seleciona o template correto com base
na presença de imagens na requisição.
"""
def __init__(self, model_map_name: str):
"""
Inicializa o PromptEngine carregando os templates específicos do modelo.
Args:
model_map_name (str): O nome do diretório do mapa do modelo em
'aduc_framework/prompts/model_maps/'.
"""
self.model_map_name = model_map_name
# Carrega os dois templates essenciais: um para prompts com imagens
# e outro para prompts que contêm apenas texto.
self.template_with_image = self._load_model_template(model_map_name, "image_template.txt")
self.template_text_only = self._load_model_template(model_map_name, "text_template.txt")
logger.info(f"PromptEngine inicializado com o mapa de modelo '{model_map_name}'.")
def _load_model_template(self, map_name: str, template_file: str) -> str:
"""
Carrega um arquivo de template de um mapa de modelo específico.
"""
map_path = Path(__file__).resolve().parent.parent / "prompts" / "model_maps" / map_name / template_file
if not map_path.is_file():
# Este é um erro crítico de configuração, então levantamos uma exceção clara.
raise FileNotFoundError(f"Template de modelo '{template_file}' não encontrado no mapa '{map_name}' em: {map_path}")
with open(map_path, 'r', encoding='utf-8') as f:
return f.read()
def translate(self, generic_prompt_content: str, has_image: bool) -> str:
"""
Envolve o conteúdo do prompt genérico com o template específico do modelo,
escolhendo o template correto com base na presença de uma imagem.
Args:
generic_prompt_content (str): O conteúdo do prompt agnóstico gerado pelo Composer.
has_image (bool): Sinaliza se a tarefa atual inclui um contexto visual.
Returns:
str: O prompt final, formatado e pronto para ser enviado ao LLM.
"""
logger.debug(f"--- PROMPT ENGINE: INICIANDO TRADUÇÃO (Imagem: {has_image}) ---")
logger.debug(f"PROMPT GENÉRICO RECEBIDO:\n---\n{generic_prompt_content[:500]}...\n---")
# Seleciona o "mapa" correto com base no contexto
if has_image:
template = self.template_with_image
logger.debug("Usando o template de modelo com imagem.")
else:
template = self.template_text_only
logger.debug("Usando o template de modelo apenas de texto.")
try:
# Insere o conteúdo genérico dentro do template específico do modelo
final_prompt = template.format(generic_prompt_content=generic_prompt_content)
logger.debug(f"PROMPT FINAL (TRADUZIDO) GERADO:\n---\n{final_prompt}\n---")
logger.debug("--- PROMPT ENGINE: TRADUÇÃO CONCLUÍDA ---")
return final_prompt
except KeyError as e:
logger.error(f"PROMPT ENGINE: Erro de chave durante a tradução! Chave não encontrada: {e}", exc_info=True)
logger.error("Verifique se o template do modelo contém apenas o placeholder '{generic_prompt_content}'.")
raise e
# --- Instância Singleton ---
# A seleção do mapa de modelo é feita aqui. No futuro, isso poderia ser
# lido do arquivo de configuração `config.yaml` para maior flexibilidade.
prompt_engine_singleton = PromptEngine(model_map_name="llama_3_2_vision")