mirror of
https://github.com/Ladebeze66/coffreobsidian.git
synced 2025-12-16 21:47:45 +01:00
231 lines
6.2 KiB
Markdown
231 lines
6.2 KiB
Markdown
# Tutoriel Complet : Créer et Utiliser des Agents LLM Dynamiques avec Ollama, Python, CLI, Streamlit et Cursor
|
|
|
|
---
|
|
|
|
## Objectif
|
|
|
|
- **Obsidian** (notes, organisation)
|
|
- **Cursor** (code, développement)
|
|
- **Streamlit** (interface utilisateur graphique)
|
|
- **CLI** (ligne de commande)
|
|
|
|
Chaque agent peut :
|
|
|
|
- Être instancié avec un **modèle différent** (mistral, codellama, etc.)
|
|
- Avoir un **rôle personnalisé** défini dynamiquement à l'appel
|
|
- Utiliser des **paramètres avancés** comme temperature, top_p, top_k
|
|
- Travailler en **mode synchrone ou asynchrone**
|
|
|
|
---
|
|
|
|
## I. Architecture des fichiers
|
|
|
|
```bash
|
|
llm_agents/
|
|
├── ollama_interface.py # Interface générique avec Ollama
|
|
├── base_agent.py # Classe d'agent configurable
|
|
├── agent_factory.py # Création d'agents depuis JSON
|
|
├── agent_router.py # Routage intelligent selon le contenu
|
|
├── cli.py # Interface terminale (CLI)
|
|
├── streamlit_app.py # Interface Streamlit dynamique
|
|
├── main.py # Démo complète
|
|
├── profiles.json # Profils agents (modèles, rôles)
|
|
└── agents/ # Agents spécialisés (optionnel)
|
|
```
|
|
|
|
---
|
|
|
|
## II. Interface avec Ollama (ollama_interface.py)
|
|
|
|
```python
|
|
import requests
|
|
|
|
class OllamaInterface:
|
|
def __init__(self, model, **params):
|
|
self.model = model
|
|
self.api_url = "http://localhost:11434/api/generate"
|
|
self.params = params
|
|
|
|
def generate(self, prompt):
|
|
payload = {"model": self.model, "prompt": prompt, **self.params}
|
|
try:
|
|
response = requests.post(self.api_url, json=payload)
|
|
response.raise_for_status()
|
|
return response.json().get("response", "")
|
|
except Exception as e:
|
|
return f"[Erreur Ollama] {e}"
|
|
```
|
|
|
|
---
|
|
|
|
## III. Classe de base des agents (base_agent.py)
|
|
|
|
```python
|
|
import logging
|
|
from ollama_interface import OllamaInterface
|
|
|
|
class BaseAgent:
|
|
def __init__(self, name, model, system_prompt="", async_mode=False, enable_logging=True, **params):
|
|
self.name = name
|
|
self.system_prompt = system_prompt.strip()
|
|
self.async_mode = async_mode
|
|
self.enable_logging = enable_logging
|
|
self.llm = OllamaInterface(model=model, **params)
|
|
self.history = []
|
|
if enable_logging:
|
|
logging.basicConfig(
|
|
filename=f"{self.name}.log",
|
|
level=logging.INFO,
|
|
format="%(asctime)s [%(name)s] %(message)s",
|
|
datefmt="%Y-%m-%d %H:%M:%S"
|
|
)
|
|
|
|
def set_role(self, prompt_system):
|
|
self.system_prompt = prompt_system.strip()
|
|
|
|
def build_prompt(self, user_input):
|
|
return f"{self.system_prompt}\n\n{user_input}" if self.system_prompt else user_input
|
|
|
|
def log(self, prompt, response):
|
|
if self.enable_logging:
|
|
logging.getLogger(self.name).info(f"Prompt:\n{prompt}\nRéponse:\n{response}\n")
|
|
|
|
def process(self, user_input):
|
|
prompt = self.build_prompt(user_input)
|
|
response = self.llm.generate(prompt)
|
|
self.log(prompt, response)
|
|
self.history.append((prompt, response))
|
|
return response
|
|
```
|
|
|
|
---
|
|
|
|
## IV. Création d'agents dynamiques avec des rôles
|
|
|
|
```python
|
|
from base_agent import BaseAgent
|
|
|
|
agent1 = BaseAgent("AnalyseurNote", model="mistral")
|
|
agent1.set_role("Tu analyses les notes markdown pour en extraire la structure.")
|
|
|
|
agent2 = BaseAgent("Correcteur", model="mistral")
|
|
agent2.set_role("Tu corriges l'orthographe et mets en page le texte Markdown.")
|
|
|
|
note = "ceci est une not mal structuré avec des errurs"
|
|
print(agent1.process(note))
|
|
print(agent2.process(note))
|
|
```
|
|
|
|
---
|
|
|
|
## V. AgentRouter — routage intelligent selon le contenu
|
|
|
|
```python
|
|
class AgentRouter:
|
|
def __init__(self, agents):
|
|
self.agents = {agent.name.lower(): agent for agent in agents}
|
|
|
|
def route(self, prompt):
|
|
if "code" in prompt.lower():
|
|
return self.agents["codeoptimizer"].process(prompt)
|
|
elif "note" in prompt.lower() or "obsidian" in prompt.lower():
|
|
return self.agents["analyseurnote"].process(prompt)
|
|
else:
|
|
return self.agents["correcteur"].process(prompt)
|
|
```
|
|
|
|
---
|
|
|
|
## VI. Exemple avec plusieurs agents dynamiques (main.py)
|
|
|
|
```python
|
|
from base_agent import BaseAgent
|
|
|
|
analyse = BaseAgent("analyseur", model="mistral")
|
|
analyse.set_role("Tu es un expert Obsidian. Analyse les notes et suggère des améliorations.")
|
|
|
|
optimiseur = BaseAgent("codeoptimizer", model="codellama:13b-python")
|
|
optimiseur.set_role("Tu es un assistant Python. Améliore le code donné.")
|
|
|
|
texte = "Voici une note mal formée sur FastAPI"
|
|
code = "def app(): return None"
|
|
|
|
print(analyse.process(texte))
|
|
print(optimiseur.process(code))
|
|
```
|
|
|
|
---
|
|
|
|
## VII. Interface CLI (cli.py)
|
|
|
|
```python
|
|
from base_agent import BaseAgent
|
|
|
|
name = input("Nom de l'agent : ")
|
|
model = input("Modèle Ollama (ex: mistral) : ")
|
|
role = input("Décris le rôle de l'agent : ")
|
|
|
|
agent = BaseAgent(name=name, model=model)
|
|
agent.set_role(role)
|
|
|
|
while True:
|
|
prompt = input("\nPrompt > ")
|
|
if prompt in ["exit", "quit"]:
|
|
break
|
|
print(agent.process(prompt))
|
|
```
|
|
|
|
---
|
|
|
|
## VIII. Interface Streamlit (streamlit_app.py)
|
|
|
|
```python
|
|
import streamlit as st
|
|
from base_agent import BaseAgent
|
|
|
|
st.title("Créateur d'agents LLM dynamiques")
|
|
|
|
name = st.text_input("Nom de l'agent")
|
|
model = st.text_input("Modèle Ollama", value="mistral")
|
|
role = st.text_area("Prompt système (rôle)")
|
|
prompt = st.text_area("Message utilisateur")
|
|
|
|
if st.button("Créer et exécuter"):
|
|
agent = BaseAgent(name=name, model=model)
|
|
agent.set_role(role)
|
|
st.write(agent.process(prompt))
|
|
```
|
|
|
|
---
|
|
|
|
## IX. Exemple de configuration JSON (profiles.json)
|
|
|
|
```json
|
|
{
|
|
"agents": [
|
|
{
|
|
"name": "ObsidianNoteur",
|
|
"model": "mistral",
|
|
"system_prompt": "Tu aides à structurer des notes Markdown.",
|
|
"temperature": 0.6
|
|
},
|
|
{
|
|
"name": "PythonHelper",
|
|
"model": "codellama:13b-python",
|
|
"system_prompt": "Tu améliores du code Python.",
|
|
"temperature": 0.4
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Conclusion
|
|
|
|
Tu disposes maintenant :
|
|
|
|
- D'une **base agent dynamique** et paramétrable
|
|
- De **rôles personnalisables** via `set_role()`
|
|
- D'exemples concrets dans Obsidian, Cursor, CLI et Streamlit
|