8.0 KiB
8.0 KiB
8. Integração de Inteligência Artificial
8.1 Casos de Uso de IA
| Funcionalidade | Descrição | Modelo |
|---|---|---|
| Match Inteligente | Sugere os 3 animais mais compatíveis com o perfil do utilizador | Claude Sonnet (API) |
| Assistente de Suporte | Responde a dúvidas sobre adopção e doação em chat em tempo real | Claude Sonnet (streaming) |
| Geração de Descrições | Gera descrições cativantes para animais sem texto fornecido pelo canil | Claude Haiku (API) |
| Análise de Necessidades | Identifica padrões nas necessidades dos canis e sugere campanhas | Claude Sonnet (API) |
| Moderação de Conteúdo | Verifica fotos e textos submetidos pelos canis antes de publicar | Claude Sonnet Vision |
8.2 Arquitectura do Agente de Match
O sistema de match inteligente funciona em dois passos:
- Recolha de contexto: combina o perfil do utilizador com o inventário actualizado de animais disponíveis
- Inferência: passa o contexto ao Claude com um system prompt especializado e recebe sugestões fundamentadas
Estrutura do Contexto
// lib/ai/match.ts
interface MatchContext {
user: {
district: string;
age: number;
preferences: {
species?: 'dog' | 'cat' | 'other';
preferredSize?: 'small' | 'medium' | 'large';
experience: 'first_time' | 'experienced' | 'expert';
livingSpace: 'apartment' | 'house_no_garden' | 'house_with_garden';
activityLevel: 'low' | 'moderate' | 'high';
hasChildren?: boolean;
hasOtherPets?: boolean;
};
history: {
viewedAnimalIds: string[];
pastAdoptions: number;
};
};
availableAnimals: Array<{
id: string;
name: string;
species: string;
breed: string | null;
ageMonths: number;
sex: string;
sterilized: boolean;
district: string;
shelterName: string;
urgent: boolean;
description: string | null;
}>;
}
System Prompt do Agente de Match
// lib/ai/prompts.ts
export const MATCH_SYSTEM_PROMPT = `
És um especialista em adopção responsável de animais da plataforma PawLink,
em Portugal. O teu papel é ajudar utilizadores a encontrar o animal de estimação
mais compatível com o seu estilo de vida.
INSTRUÇÕES:
- Analisa o perfil do utilizador e a lista de animais disponíveis
- Sugere exactamente 3 animais, ordenados por compatibilidade (do mais ao menos compatível)
- Para cada animal, explica em 2-3 frases porque é uma boa correspondência
- Considera sempre: espaço disponível, nível de actividade, experiência, localidade
- Animais com flag "urgent: true" devem receber peso extra na pontuação
- Não inventes características — usa apenas os dados fornecidos
- Se não houver animais adequados, diz-o honestamente e explica porquê
FORMATO DA RESPOSTA (JSON):
{
"matches": [
{
"animalId": "string",
"compatibilityScore": 95,
"reason": "string — 2-3 frases em português"
}
],
"generalAdvice": "string — conselho geral opcional (máximo 1 frase)"
}
Responde APENAS com JSON válido, sem texto adicional.
`;
Implementação da Chamada à API
// lib/ai/match.ts
import Anthropic from '@anthropic-ai/sdk';
const anthropic = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });
export async function getAnimalMatches(context: MatchContext) {
const response = await anthropic.messages.create({
model: 'claude-sonnet-4-20250514',
max_tokens: 1024,
system: MATCH_SYSTEM_PROMPT,
messages: [
{
role: 'user',
content: `Perfil do utilizador e animais disponíveis:\n${JSON.stringify(context, null, 2)}`
}
]
});
const text = response.content[0].type === 'text' ? response.content[0].text : '';
try {
return JSON.parse(text) as { matches: MatchResult[]; generalAdvice?: string };
} catch {
console.error('Erro ao fazer parse da resposta de match:', text);
return null;
}
}
8.3 Assistente de Suporte (Chatbot)
O assistente responde em tempo real usando streaming para melhor experiência do utilizador. É implementado com o Vercel AI SDK.
System Prompt do Suporte
export const SUPPORT_SYSTEM_PROMPT = `
És o assistente virtual da PawLink, uma plataforma portuguesa de adopção de
animais e doação a canis. Chamas-te Paws.
PAPEL:
- Ajudar utilizadores a navegar na plataforma e responder a dúvidas sobre
adopção e doação de animais
- Fornecer informação geral sobre cuidados com animais de estimação
- Orientar utilizadores que estejam a considerar adoptar pela primeira vez
LIMITAÇÕES:
- Não tens acesso a informação em tempo real sobre animais específicos ou
disponibilidade actual (sugere usar os filtros da plataforma)
- Não podes processar pagamentos ou fazer reservas directamente
- Para questões técnicas graves, sugere contacto via email: suporte@pawlink.pt
TOM:
- Caloroso, encorajador e amigável
- Profissional mas acessível
- Nunca condescendente
LÍNGUA: Responde sempre em português de Portugal (pt-PT).
`;
Endpoint de Streaming
// app/api/chat/route.ts
import { streamText } from 'ai';
import { anthropic } from '@ai-sdk/anthropic';
export async function POST(req: Request) {
const { messages } = await req.json();
const result = await streamText({
model: anthropic('claude-sonnet-4-20250514'),
system: SUPPORT_SYSTEM_PROMPT,
messages,
maxTokens: 500, // respostas concisas no chat
});
return result.toDataStreamResponse();
}
Componente de Chat no Frontend
// components/chat/SupportChat.tsx
'use client';
import { useChat } from 'ai/react';
export function SupportChat() {
const { messages, input, handleInputChange, handleSubmit, isLoading } = useChat({
api: '/api/chat',
initialMessages: [{
id: 'welcome',
role: 'assistant',
content: 'Olá! Sou o Paws, o assistente da PawLink. Como posso ajudar-te hoje? 🐾'
}]
});
return (
<div className="chat-container">
{messages.map(msg => (
<div key={msg.id} className={`message ${msg.role}`}>
{msg.content}
</div>
))}
<form onSubmit={handleSubmit}>
<input value={input} onChange={handleInputChange} placeholder="Escreve a tua mensagem..." />
<button type="submit" disabled={isLoading}>Enviar</button>
</form>
</div>
);
}
8.4 Geração de Descrições de Animais
Quando um canil regista um animal sem fornecer descrição, o sistema gera automaticamente uma descrição cativante:
export async function generateAnimalDescription(animal: {
name: string;
species: string;
breed: string | null;
ageMonths: number;
sex: string;
sterilized: boolean;
}) {
const response = await anthropic.messages.create({
model: 'claude-haiku-4-5', // Haiku é suficiente e mais económico para esta tarefa
max_tokens: 200,
messages: [{
role: 'user',
content: `Escreve uma descrição curta e cativante (máximo 3 frases) para este animal
disponível para adopção numa plataforma portuguesa.
Dados: ${JSON.stringify(animal)}
Escreve em português de Portugal, com tom caloroso e encorajador.
Não inventes factos específicos, usa apenas os dados fornecidos.`
}]
});
return response.content[0].type === 'text' ? response.content[0].text : null;
}
8.5 Boas Práticas e Limites
- Rate limiting: chamadas à IA limitadas a 20 por utilizador por hora para controlo de custos
- Cache de resultados: respostas de match são cacheadas 30 minutos no Redis (o inventário não muda ao segundo)
- Fallback gracioso: se a API da Anthropic falhar, a plataforma funciona normalmente sem funcionalidades de IA
- Transparência: o utilizador é informado quando está a interagir com IA
- Sem decisões críticas: a IA sugere mas nunca decide automaticamente — o utilizador tem sempre controlo
- Monitorização de custos: dashboard no Anthropic Console para acompanhar utilização e custos