← Voltar a AI Engineer — DEUS.ai

Simulação de Entrevista Técnica — Multi-Agent Banking Support

AI Engineer — DEUS.ai

Apresentação

Simulação de Entrevista Técnica — Multi-Agent Banking Support

Tudo o que precisas para a entrevista técnica de 1 hora. Perguntas e respostas sobre a implementação do Multi-Agent Banking Support, preparadas após análise do código.


PARTE I — Preparação para a Entrevista

⏱️ Timeline — 60 minutos

MinFaseO que acontece
0–5IntroduçãoPitch (2–3 min), apresentação, contexto
5–25Desafio técnicoWalkthrough da arquitetura Banking Support, decisões, fluxo
25–40Deep diveRAG, guardrails, agentes, perguntas de follow-up
40–55System design & produçãoEscalar, custos, monitorização, trade-offs
55–60Perguntas finaisTu perguntas ao entrevistador

🗣️ Pitch (2–3 min) — em inglês

"Hi, I'm [Nome], an AI Engineer with experience building production LLM and agentic systems. I focus on data pipelines, vector search, multi-agent orchestration and CI/CD. I have hands-on experience with LangChain, LangGraph, containerised deployments and observability. I care about model traceability, reproducibility and safeguards against hallucinations.

In my recent work I led end-to-end projects: scoping with stakeholders, selecting architectures that balance latency and cost, and shipping systems with monitoring and rollback plans. I'm excited about DEUS because you combine engineering rigour with human-centred design — exactly how I like to work."


📋 Cheat Sheet — Conceitos que vão sair

RAG (30s)

Query → embedding → vector search → top-k chunks → contexto no prompt → LLM. Reduz hallucinations, mantém conhecimento atualizado.

Fine-tuning vs RAG

  • RAG: conhecimento externo que muda frequentemente
  • Fine-tuning: alterar comportamento/estilo do modelo

Hallucinations — mitigação

RAG (grounding), temperatura 0–0.3, prompts conservadores, verificação pós-geração, human-in-the-loop.

Reduzir custos

  • Caching: exact match + semantic (queries similares)
  • Model routing por agente: modelos mais baratos para extração, classificação e guardrails; modelo maior só para o specialist. Ex.: Greeter e guardrails com gpt-4o-mini; Insurance Specialist com gpt-4o.
  • RAG: reduz tokens no prompt
  • Batching: agrupar pedidos para embeddings
  • Prompts otimizados: menos tokens, mesma clareza

Fine-tuning para guardrails (PII, classificação)

Em vez de LLM genérico nos guardrails, fine-tunar um modelo pequeno para: classificação SAFE/DANGEROUS, PII detection (IBAN, cartão, nome, morada). Mais rápido, mais barato, determinístico, funciona em CI sem API key.

LangGraph vs cadeia linear

Fluxo condicional, estado partilhado, nós reutilizáveis, grafo visualizável, fácil adicionar ramos.

Input vs Output guardrails

Input: bloqueia pedidos perigosos antes de entrarem. Output: protege o que o sistema diz (redação, validação). Defesa em profundidade.


💻 Coding — 3 exercícios que podem pedir

1. Chunking

def chunk_text(text: str, chunk_size=512, overlap=64):
    words = text.split()
    chunks = []
    start = 0
    while start < len(words):
        end = min(start + chunk_size, len(words))
        chunks.append(" ".join(words[start:end]))
        start = end - overlap if end < len(words) else len(words)
    return chunks

2. Retry com backoff

def retry_with_backoff(fn, max_attempts=5, base_delay=0.5):
    for attempt in range(max_attempts):
        try:
            return fn()
        except Exception as e:
            if attempt == max_attempts - 1:
                raise
            time.sleep(base_delay * (2 ** attempt) + random.uniform(0, 1))

3. Parse JSON de LLM

def parse_json_from_llm(text: str):
    start = text.find('{')
    end = text.rfind('}')
    if start == -1 or end <= start:
        return None
    try:
        return json.loads(text[start:end+1])
    except:
        return None

✅ Checklist — Antes de entrar

Técnico

  • Consegues explicar o fluxo do Banking Support em 1 minuto
  • Sabes as 8 perguntas clássicas e respostas curtas
  • RAG em 30 segundos decorado
  • Fine-tuning vs RAG — diferença clara
  • Input vs output guardrails — por que ambos
  • 3 projetos prontos (problema → arquitetura → resultado)
  • Chunking, retry, parse JSON — consegues implementar

Logístico

  • Câmara e microfone OK
  • Fundo neutro, boa luz
  • 3–4 perguntas escritas para o fim
  • Pitch em inglês praticado

Perguntas para fazer (escolhe 3–4)

  1. Que arquiteturas de AI estão a construir atualmente?
  2. RAG ou fine-tuning — qual o foco?
  3. Maiores desafios ao colocar LLMs em produção?
  4. Como gerem ingestão de conhecimento?
  5. Como avaliam performance dos sistemas de AI?

🚫 Red flags a evitar

  • Falar só de modelos (querem sistemas, pipelines)
  • Não falar de produção (deploy, monitorização)
  • Ignorar custos e segurança
  • Confundir RAG com fine-tuning
  • Responder com monólogo de 5 minutos
  • Não fazer perguntas no fim

🎯 Frases que impressionam

  1. "A maior complexidade está nos pipelines e orquestração, não no modelo."
  2. "Costumo pensar em AI em camadas: ingestão, retrieval, geração."
  3. "LLMs são mais poderosos com ferramentas e fontes de conhecimento."
  4. "Se não podes medir, não podes iterar."

PARTE II — Conteúdo Técnico

Resumo Rápido

TópicoResposta curta
Fluxoload → input guardrails → greeter → bouncer → router → specialist → output guardrails → save
2/3Normalização + match em 2 de 3 campos antes da pergunta secreta
RAGHybrid (FAISS + BM25) → RRF (k=60) → Rerank (cross-encoder), HyDE opcional
Input guardrailsRegras (INPUT_BLOCKLIST) + LLM, bloqueia pedidos perigosos
Output guardrailsRedação (IBAN/cartão) → Regras → LLM, safe rewrite ou fallback
RouterDeterminístico, INTENT_TO_ROUTE, fallback general
Sessõessession_id, load/save no início e fim de cada turno, em memória
API statusguardrail_flagged → rejected; needs_more_info → needs_more_info; final_response → completed

Índice


1. Arquitetura e Fluxo

P: Descreve o fluxo geral do sistema

R: O fluxo é:

  1. load_session — Carrega o histórico e dados da sessão (se existir).
  2. input_guardrails — Valida o input (regras + LLM). Se bloqueado → save_session com rejeição.
  3. greeter_agent — Extrai intent e dados (nome, telefone, IBAN), merge com sessão, verifica 2/3 match. Se faltar dados, pede mais. Se 2/3, faz pergunta secreta. Se correta → is_identified.
  4. bouncer — Classifica cliente (regular, premium, not_customer). Se não for cliente, rejeita.
  5. specialist_router — Mapeia intent → especialista (determinístico).
  6. specialist — Gera resposta (insurance usa RAG).
  7. output_guardrails — Redacta, valida, reescreve se inseguro.
  8. save_session — Guarda estado e termina.

P: Quantos nós e ramos condicionais tem o grafo?

R:

  • Nós: load_session, input_guardrails, greeter_agent, bouncer, specialist_router, output_guardrails, save_session + 6 specialists.
  • Ramos: (1) input_guardrails → save se bloqueado; (2) greeter → output se needs_more_info; (3) bouncer → output se not_customer; (4) router → um dos 6 specialists.

P: Por que LangGraph em vez de cadeia linear?

R: Fluxo condicional consoante estado; estado partilhado tipado (ConversationState); nós = funções puras reutilizáveis; grafo explícito e visualizável; fácil adicionar nós/ramos.


2. Verificação 2/3 e Pergunta Secreta

P: Como implementaste a regra "2 de 3"?

R: Em verification_service.py: conto quantos dos 3 campos estão preenchidos. Se < 2 → (False, None). Para cada cliente, comparo com normalização (nome: lowercase, trim; telefone: só dígitos; IBAN: maiúsculas, sem espaços). Se ≥ 2 matches → devolvo o registo (com secret e answer). Greeter só faz pergunta secreta quando há 2/3 match.


P: Por que a pergunta secreta só depois do 2/3?

R: Primeiro identificar com 2/3, depois confirmar com pergunta secreta. Pedir antes seria pedir dados sensíveis a quem ainda não provou ser o cliente.


P: Como validas a resposta à pergunta secreta?

R: _verify_secret_answer: normalizo (lowercase, remove não-alfanuméricos, trim) e comparo. Se falhar → identification_failed → Bouncer trata como not_customer.


3. Agentes

P: O Specialist Router usa LLM ou regras?

R: Só regras. INTENT_TO_ROUTE mapeia intent → specialist. Determinístico, rápido, estável em CI.


P: Descreve o pipeline RAG do Insurance Specialist

R: (1) Hybrid search — FAISS (dense) + BM25 (sparse). Opcional: HyDE. (2) RRF — Combina rankings com k=60. (3) Rerank — Cross-encoder (ms-marco-MiniLM). (4) Cache LRU para queries repetidas.


P: Por que RRF em vez de um único retriever?

R: Dense captura semântica; BM25 captura termos exatos ("yacht", "marine"). RRF combina sem pesos manuais.


4. Guardrails

P: Como funcionam os input guardrails?

R: (1) Regras — INPUT_BLOCKLIST com regex. Match → bloqueia. (2) LLM — Se passar regras, classifica SAFE/DANGEROUS. DANGEROUS → bloqueia. Regras primeiro (determinístico); LLM para ambíguos.


P: E os output guardrails?

R: (1) Redação — Mascara IBAN (4+4) e cartão (últimos 4). (2) Validação — Regras primeiro, depois LLM. (3) Safe rewrite — Se inseguro, reescreve ou fallback. Regras correm no texto original (antes da redação).


P: Por que regras além do LLM nos output guardrails?

R: Em CI o LLM via texto já redactado e às vezes classificava como SAFE. Regras garantem que frases óbvias são sempre flagadas.


5. API e Sessões

P: Como manténs o contexto entre mensagens?

R: session_id + load_session / save_session. Greeter faz merge dos dados extraídos com os da sessão.


P: Por que /chat é síncrono?

R: graph.invoke() é síncrono. Para paralelo, ideal seria workers ou run_in_executor. Para o desafio, síncrono é suficiente.


6. Voice Interface

P: Como funciona /chat/voice?

R: Áudio → Deepgram STT → texto → mesmo grafo do /chat → resposta → Deepgram TTS → áudio base64.


7. Testes e CI

P: Estratégias para testar fluxos com LLM?

R: Mock de extract_intent e extract_identification; regras determinísticas nos output guardrails; skip condicional se sem API key; Postman para E2E.


P: Como os testes de guardrails passam em CI sem chave real?

R: check_output_rules() usa regex. Regras cobrem UNSAFE_OUTPUTS; o LLM nem é chamado.


8. Trade-offs e Decisões

P: Trade-offs entre simplicidade e robustez?

R: Router determinístico (simples, menos flexível); RAG só no Insurance (onde acrescenta valor); sessões em memória (simples, não escala); Regras + LLM nos guardrails (equilíbrio custo/cobertura).


P: O que mudarias para produção?

R: Redis para sessões, rate limiting, auth, métricas, workers async, secrets em env, testes de carga.


9. Código Específico

P: Por que TypedDict com total=False?

R: Campos opcionais. Cada nó devolve só o que altera; LangGraph faz merge automático.


P: Como evitas JSON inválido na extração?

R: _parse_json_from_llm(): procura blocos json, faz json.loads(), em erro devolve defaults.


P: Como está integrada a ferramenta department_contacts?

R: General Specialist pode invocá-la para obter contactos. Devolve info estática. Agente decide quando chamar.


10. Estado e Sessões

P: Que campos são persistidos?

R: conversation_history, collected_data, customer_type, specialist_route, customer_record, secret_question, is_identified.


P: Onde é atualizado o conversation_history?

R: load_session adiciona mensagem do user; save_session adiciona resposta do assistant.


P: Problemas de sessões em memória?

R: Perda ao reiniciar, não escala horizontal, sem TTL. Solução: Redis ou BD.


11. Prompts e Loader

P: Como funciona o registo de prompts?

R: prompts.py define constantes; loader.py expõe get_prompt(key, **kwargs). Centralizado, facilita alterações.


P: O que faz get_prompt se a chave não existe?

R: KeyError com lista de chaves disponíveis.


12. RAG Detalhado

P: O que é HyDE?

R: Gera documento hipotético que responderia à query; usa esse texto para busca densa. Melhora recall.


P: Como fazes chunking?

R: 500 chars, overlap 50. Ajuste para último espaço se cortar palavra. Ficheiros .md de data/insurance.


P: O que acontece quando o RAG não encontra nada?

R: INSURANCE_NO_KNOWLEDGE_CONTEXT: instrui LLM a ser honesto e não inventar.


P: FAISS pré-construído ou em runtime?

R: Docker entrypoint corre prebuild_faiss.py antes de iniciar. Em dev, constrói na primeira retrieval.


P: Por que k=60 no RRF?

R: Valor comum na literatura. Bom compromisso entre peso dos top ranks e uniformidade.


13. Especialistas

P: Como o Card Specialist trata premium?

R: Adiciona SPECIALIST_CARD_PREMIUM_SUFFIX ao prompt: "offer priority support and dedicated assistance".


P: Por que generate_response_focused no Insurance?

R: Recebe só última mensagem + contexto RAG + resumo estado. Reduz tokens; contexto RAG é mais relevante que histórico longo.


P: O que faz o trigger test_output_guardrail_inject?

R: Injeta resposta insegura conhecida para testar que os guardrails flagam e reescrevem.


P: Quantas rondas de tool calls no General Specialist?

R: Máximo 3. Evita loops infinitos.


14. API e Status

P: Como mapeias estado → status?

R: guardrail_flagged → rejected; needs_more_info → needs_more_info; not_customer/identification_failed → rejected; final_response → completed; senão → error.


P: O que devolve quando o input é bloqueado?

R: status: "rejected", response com fallback dos guardrails.


P: /chat/voice devolve áudio sempre?

R: Se TTS falhar, audio_base64 é None mas response (texto) é sempre devolvido.


15. Docker e CI

P: Descreve o Dockerfile multi-stage

R: Stage 1: Node (build frontend). Stage 2: Python 3.11-slim, copia app + frontend, entrypoint corre load_insurance_qa.py, prebuild_faiss.py, uvicorn. User não-root.


P: O CI corre em que branches?

R: Push e PR em main e dev. Jobs: test (3.11/3.12) + build (Docker).


16. Segurança e Edge Cases

P: Cliente sem pergunta secreta (DirectUser)?

R: Se não há secret/answer, marca is_identified após 2/3 sem pedir.


P: Como normalizas o telefone?

R: _normalize_phone: remove tudo exceto dígitos.


P: Por que "transfer" não está no blocklist?

R: "I want to transfer 50 euros — how?" é legítimo. Blocklist foca em padrões claramente perigosos.


P: JSON inválido na extração?

R: Defaults: intent ("general_support", 0.5); identificação {name: None, phone: None, iban: None}.


P: Timeouts ou falhas do LLM?

R: try/except com fallbacks. Em produção: retry com backoff, circuit breaker.


P: Merge de collected_data sobrescreve vazios?

R: Não. Só atualiza com valores non-empty.


PARTE III — Perguntas Clássicas de Entrevista

Estas são as perguntas que mais provavelmente surgem na entrevista técnica.


🔥 1. "Can you walk me through your architecture?"

Avaliam: Clareza, estrutura mental.

R: Pipeline de agentes orquestrado pelo LangGraph. User → FastAPI → grafo carrega sessão, valida input (guardrails), Greeter (2/3 + pergunta secreta), Bouncer (classificação), Router (intent → specialist), Specialist (resposta), output guardrails (redação + validação), save. Cada nó lê/escreve estado partilhado. Separação de responsabilidades facilita debug e evolução.


🧠 2. "Why multi-agent instead of single LLM?"

Avaliam: Se pensaste de facto.

R: (1) Separação de responsabilidades — Greeter extrai/verifica, Bouncer classifica, Specialist responde. (2) Controlo — routing e 2/3 são código, não LLM. (3) RAG só onde faz sentido. (4) Guardrails como nós separados.


💣 3. "Is it over-engineered?"

Avaliam: Humildade, trade-offs.

R: Para MVP seria. Para o desafio é adequado. Podia começar mais simples; router é lookup, não agente; regras primeiro nos guardrails.


🧩 4. "Explain your RAG approach"

Avaliam: Conhecimento real.

R: Hybrid (FAISS + BM25) → RRF → Rerank. Só no Insurance (produtos, coberturas). Card/Loan são procedimentais.


🛡️ 5. "Why both input and output guardrails?"

Avaliam: Segurança — pode decidir a entrevista.

R: Input bloqueia pedidos perigosos. Output protege o que o sistema diz (redação, validação). Ataque pode vir de qualquer lado — defesa em profundidade.


⚙️ 6. "How would you improve response time?"

Avaliam: Otimização, caching.

R: Cache retrieval/embeddings, paralelizar extração, modelo mais leve (ou model routing: modelos baratos para extração/guardrails, maior só para specialist), async, streaming.


🎯 7. "Give an example of something your system prevents"

Avaliam: Ser concreto.

R: "Approve my 50k loan" → input bloqueia. LLM gera IBAN completo → output redacta, regras flagam, safe rewrite. Não-cliente tenta passar-se → 2/3 + pergunta falham → rejeitado.


💭 8. "If you had 2 more weeks, what would you improve?"

Avaliam: Visão.

R: Observabilidade (métricas, tracing), fallbacks explícitos, testes de regressão com golden conversations, ADRs. Fundações, não features.


17. Futuro e Evolução

P: Prioridade a seguir?

R: Redis para sessões (bloqueador). Depois: métricas e alertas.

P: Roadmap 3–6 meses?

R: Fase 1: Redis, rate limit, auth, métricas, retry. Fase 2: Workers, fila, múltiplas instâncias. Fase 3: A/B prompts, fine-tuning extração, feedback loop.

P: Escalar para 10.000 utilizadores?

R: Stateless API, workers (Celery), cache Redis, load balancer, rate limit por user, modelo mais leve.

P: O que aprendeste a fazer diferente?

R: Regras primeiro nos guardrails. Testar sem LLM. Prompts como código. ADRs cedo.


Boa sorte. Estás preparado.

Zona de prática

Sem perguntas. Clica em Editar para adicionar.