File size: 13,790 Bytes
3e6b9d2 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 |
"""
Agent avec outils financiers et mémoire (history)
Cet exemple démontre:
1. Utilisation d'outils Python pour calculs financiers
2. Mémoire/conversation history pour maintenir le contexte
3. Agents qui se souviennent des calculs précédents
"""
import asyncio
from typing import Annotated, List
from pydantic import BaseModel
from pydantic_ai import Agent, ModelSettings
from app.models import finance_model
# Simple History wrapper for managing conversation
class ConversationHistory:
"""Gère l'historique de conversation pour les agents."""
def __init__(self):
self.messages: List[dict] = []
def add_user_message(self, content: str):
"""Ajoute un message utilisateur."""
# Pour simplifier, on crée une structure simple
# En production, utiliser les types corrects de PydanticAI
self.messages.append({"role": "user", "content": content})
def add_assistant_message(self, content: str):
"""Ajoute un message assistant."""
self.messages.append({"role": "assistant", "content": content})
def get_history_for_agent(self) -> List[dict]:
"""Retourne l'historique au format pour l'agent."""
return self.messages
def __len__(self):
return len(self.messages)
# ============================================================================
# OUTILS FINANCIERS
# ============================================================================
def calculer_valeur_future(
capital_initial: float,
taux_annuel: float,
duree_annees: float
) -> str:
"""Calcule la valeur future avec intérêts composés.
Args:
capital_initial: Montant initial en euros
taux_annuel: Taux d'intérêt annuel (ex: 0.04 pour 4%)
duree_annees: Durée en années
Returns:
Résultat formaté du calcul
"""
valeur_future = capital_initial * (1 + taux_annuel) ** duree_annees
interets = valeur_future - capital_initial
rendement_pct = (interets / capital_initial) * 100
return (
f"💰 Valeur future: {valeur_future:,.2f}€\n"
f" Capital initial: {capital_initial:,.2f}€\n"
f" Intérêts générés: {interets:,.2f}€ ({rendement_pct:.2f}%)\n"
f" Durée: {duree_annees} ans à {taux_annuel*100:.2f}% par an"
)
def calculer_versement_mensuel(
capital_emprunte: float,
taux_annuel: float,
duree_annees: int
) -> str:
"""Calcule le versement mensuel pour un prêt immobilier.
Args:
capital_emprunte: Montant emprunté en euros
taux_annuel: Taux d'intérêt annuel (ex: 0.035 pour 3.5%)
duree_annees: Durée du prêt en années
Returns:
Résultat formaté du calcul
"""
duree_mois = duree_annees * 12
taux_mensuel = taux_annuel / 12
versement = capital_emprunte * (
taux_mensuel * (1 + taux_mensuel) ** duree_mois
) / ((1 + taux_mensuel) ** duree_mois - 1)
total_rembourse = versement * duree_mois
cout_total = total_rembourse - capital_emprunte
return (
f"🏠 Versement mensuel: {versement:,.2f}€\n"
f" Capital emprunté: {capital_emprunte:,.2f}€\n"
f" Total remboursé: {total_rembourse:,.2f}€\n"
f" Coût du crédit: {cout_total:,.2f}€\n"
f" Durée: {duree_annees} ans ({duree_mois} mois) à {taux_annuel*100:.2f}%"
)
def calculer_performance_portfolio(
valeur_initiale: float,
valeur_actuelle: float,
duree_jours: int
) -> str:
"""Calcule la performance d'un portfolio.
Args:
valeur_initiale: Valeur initiale en euros
valeur_actuelle: Valeur actuelle en euros
duree_jours: Durée en jours
Returns:
Résultat formaté du calcul
"""
gain_absolu = valeur_actuelle - valeur_initiale
gain_pourcentage = (gain_absolu / valeur_initiale) * 100
rendement_annuelise = ((valeur_actuelle / valeur_initiale) ** (365 / duree_jours) - 1) * 100
return (
f"📈 Performance portfolio:\n"
f" Gain absolu: {gain_absolu:+,.2f}€ ({gain_pourcentage:+.2f}%)\n"
f" Rendement annualisé: {rendement_annuelise:+.2f}%\n"
f" Durée: {duree_jours} jours"
)
def calculer_ratio_dette(
dette_totale: float,
revenus_annuels: float
) -> str:
"""Calcule le ratio d'endettement.
Args:
dette_totale: Dette totale en euros
revenus_annuels: Revenus annuels en euros
Returns:
Résultat formaté du calcul
"""
ratio = (dette_totale / revenus_annuels) * 100
annees_remboursement = dette_totale / revenus_annuels
return (
f"💳 Ratio d'endettement:\n"
f" Ratio: {ratio:.2f}% des revenus annuels\n"
f" Dette totale: {dette_totale:,.2f}€\n"
f" Revenus annuels: {revenus_annuels:,.2f}€\n"
f" Années de remboursement: {annees_remboursement:.2f} ans"
)
# ============================================================================
# AGENT AVEC OUTILS ET MÉMOIRE
# ============================================================================
finance_advisor = Agent(
finance_model,
model_settings=ModelSettings(max_output_tokens=2000),
system_prompt=(
"Vous êtes un conseiller financier expert qui aide les clients à prendre "
"des décisions financières éclairées. Vous avez accès à des outils de calcul "
"financier précis.\n\n"
"Utilisez les outils disponibles pour:\n"
"- Calculer les valeurs futures d'investissements\n"
"- Calculer les versements de prêts immobiliers\n"
"- Analyser la performance de portfolios\n"
"- Évaluer les ratios d'endettement\n\n"
"Gardez en mémoire les informations précédentes de la conversation pour "
"fournir des conseils cohérents et personnalisés.\n\n"
"Répondez toujours en français de manière claire et structurée."
),
tools=[
calculer_valeur_future,
calculer_versement_mensuel,
calculer_performance_portfolio,
calculer_ratio_dette,
],
)
# ============================================================================
# EXEMPLES D'UTILISATION
# ============================================================================
async def exemple_conversation_avec_memoire():
"""Exemple de conversation avec mémoire (history)."""
print("💬 Exemple: Conversation avec mémoire et outils")
print("=" * 60)
# Créer une histoire de conversation vide
history = ConversationHistory()
# Question 1: Calcul initial
print("\n👤 Client: 'J'ai 50 000€ à placer à 4% par an pendant 10 ans. Combien aurai-je?'")
prompt1 = "J'ai 50 000€ à placer à 4% par an pendant 10 ans. Combien aurai-je?"
result1 = await finance_advisor.run(prompt1)
history.add_user_message(prompt1)
history.add_assistant_message(result1.output)
print(f"\n🤖 Conseiller:\n{result1.output[:400]}...")
# Question 2: Référence au calcul précédent (mémoire via contexte)
print("\n" + "-" * 60)
print("\n👤 Client: 'Et si j'augmente à 5%?'")
# Inclure le contexte précédent dans le prompt
context = "\n".join([
f"{'👤' if msg['role'] == 'user' else '🤖'} {msg['content'][:200]}..."
for msg in history.get_history_for_agent()
])
prompt2 = f"Contexte précédent:\n{context}\n\nNouvelle question: Et si j'augmente le taux à 5%?"
result2 = await finance_advisor.run(prompt2)
history.add_user_message("Et si j'augmente le taux à 5%?")
history.add_assistant_message(result2.output)
print(f"\n🤖 Conseiller:\n{result2.output[:400]}...")
# Question 3: Nouvelle question avec contexte
print("\n" + "-" * 60)
print("\n👤 Client: 'En fait, je veux plutôt emprunter 200 000€ sur 20 ans à 3.5% pour un achat immobilier'")
context = "\n".join([
f"{msg['role']}: {msg['content'][:150]}..."
for msg in history.get_history_for_agent()[-4:] # Derniers 4 messages
])
prompt3 = f"Contexte:\n{context}\n\nEn fait, je veux plutôt emprunter 200 000€ sur 20 ans à 3.5% pour un achat immobilier. Combien paierai-je par mois?"
result3 = await finance_advisor.run(prompt3)
history.add_user_message("En fait, je veux plutôt emprunter 200 000€ sur 20 ans à 3.5%")
history.add_assistant_message(result3.output)
print(f"\n🤖 Conseiller:\n{result3.output[:400]}...")
# Afficher l'historique complet
print("\n" + "=" * 60)
print("📚 Historique de la conversation:")
print("=" * 60)
for i, msg in enumerate(history.get_history_for_agent(), 1):
role = msg['role']
content = msg['content'][:100] + "..." if len(msg['content']) > 100 else msg['content']
print(f"{i}. {role.upper()}: {content}")
async def exemple_portfolio_avec_memoire():
"""Exemple d'analyse de portfolio avec mémoire des calculs précédents."""
print("\n\n📊 Exemple: Analyse de portfolio avec mémoire")
print("=" * 60)
history = ConversationHistory()
# Initialisation du portfolio
print("\n👤 Client: 'Mon portfolio valait 100 000€ il y a 6 mois, aujourd'hui il vaut 115 000€'")
prompt1 = "Mon portfolio valait 100 000€ il y a 6 mois, aujourd'hui il vaut 115 000€. Calcule la performance."
result1 = await finance_advisor.run(prompt1)
history.add_user_message(prompt1)
history.add_assistant_message(result1.output)
print(f"\n🤖 Conseiller:\n{result1.output}")
# Suivi avec mémoire
print("\n" + "-" * 60)
print("\n👤 Client: 'Et si je projette cette performance sur 5 ans?'")
context = f"Contexte précédent:\n{result1.output[:300]}...\n\n"
prompt2 = context + "Et si je projette cette performance annuelle sur 5 ans avec mon capital actuel de 115 000€?"
result2 = await finance_advisor.run(prompt2)
history.add_user_message("Et si je projette cette performance sur 5 ans?")
history.add_assistant_message(result2.output)
print(f"\n🤖 Conseiller:\n{result2.output[:500]}...")
return history
async def exemple_analyse_complete_avec_memoire():
"""Exemple complet d'analyse financière avec outils et mémoire."""
print("\n\n🎯 Exemple: Analyse financière complète avec mémoire")
print("=" * 60)
history = ConversationHistory()
questions = [
"Je gagne 80 000€ par an et j'ai une dette de 200 000€. Quel est mon ratio d'endettement?",
"Je veux emprunter 300 000€ pour une résidence principale à 3.5% sur 25 ans. Combien paierai-je?",
"Si j'investis les 74 000€ restants après le prêt à 5% par an pendant 15 ans, combien aurai-je?",
]
for i, question in enumerate(questions, 1):
print(f"\n{'='*60}")
print(f"Question {i}: {question}")
print("=" * 60)
# Inclure le contexte si ce n'est pas la première question
if i > 1:
context = "\n".join([
f"{msg['role']}: {msg['content'][:200]}..."
for msg in history.get_history_for_agent()[-2:] # 2 derniers messages
])
full_question = f"Contexte:\n{context}\n\n{question}"
else:
full_question = question
result = await finance_advisor.run(full_question)
history.add_user_message(question)
history.add_assistant_message(result.output)
print(f"\nRéponse:\n{result.output[:600]}...")
# Petit délai pour éviter les timeouts
await asyncio.sleep(1)
print("\n" + "=" * 60)
print("✅ Analyse complète terminée!")
print(f"📊 Total de messages dans l'historique: {len(history)}")
async def exemple_extraction_memoire():
"""Montre comment extraire des informations de la mémoire."""
print("\n\n🔍 Exemple: Extraction d'informations de la mémoire")
print("=" * 60)
history = ConversationHistory()
# Conversation initiale
prompt1 = "J'ai un capital de 100 000€ à placer à 4% pendant 10 ans."
result1 = await finance_advisor.run(prompt1)
history.add_user_message(prompt1)
history.add_assistant_message(result1.output)
prompt2 = "Je gagne 75 000€ par an et j'ai une dette de 180 000€."
result2 = await finance_advisor.run(prompt2)
history.add_user_message(prompt2)
history.add_assistant_message(result2.output)
# Question qui utilise la mémoire
print("\n👤 Client: 'Résume ma situation financière'")
context = "\n".join([
f"{msg['role']}: {msg['content']}"
for msg in history.get_history_for_agent()
])
result = await finance_advisor.run(
f"Contexte de la conversation:\n{context}\n\n"
"Peux-tu résumer ma situation financière actuelle basée sur ce que je t'ai dit?"
)
print(f"\n🤖 Conseiller:\n{result.output}")
# Afficher l'historique
print("\n" + "-" * 60)
print("📚 Messages dans l'historique:")
for msg in history.get_history_for_agent():
print(f" {msg['role']}: {msg['content'][:150]}...")
if __name__ == "__main__":
print("\n" + "=" * 60)
print("AGENTS AVEC OUTILS FINANCIERS ET MÉMOIRE")
print("=" * 60)
# Exemple 1: Conversation avec mémoire
asyncio.run(exemple_conversation_avec_memoire())
# Exemple 2: Portfolio avec mémoire
asyncio.run(exemple_portfolio_avec_memoire())
# Exemple 3: Extraction de mémoire
asyncio.run(exemple_extraction_memoire())
print("\n\n" + "=" * 60)
print("✅ Tous les exemples terminés!")
print("=" * 60)
|