some langchain llm call
This commit is contained in:
2
.env
Normal file
2
.env
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
#GOOGLE_API_KEY = "AQ.Ab8RN6KVRupKRqWZACksBWw7MrClcfbyMXGjHPyOFMssOGxFFQ"
|
||||||
|
GOOGLE_API_KEY = "AIzaSyAmitbNdx29t1uV3XYHdXpC55XCufAPM-g"
|
||||||
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
.venv/
|
||||||
49
agent.py
Normal file
49
agent.py
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
import os
|
||||||
|
from typing import Annotated
|
||||||
|
from typing_extensions import TypedDict # Plus robuste pour le State
|
||||||
|
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
from langgraph.graph import StateGraph, START, END
|
||||||
|
from langgraph.graph.message import add_messages
|
||||||
|
from langchain_google_vertexai import ChatVertexAI
|
||||||
|
|
||||||
|
load_dotenv()
|
||||||
|
|
||||||
|
# 1. Configuration du modèle (Syntaxe actuelle)
|
||||||
|
# Assure-hui que GOOGLE_APPLICATION_CREDENTIALS ou GOOGLE_CLOUD_PROJECT est dans ton .env
|
||||||
|
llm = ChatVertexAI(
|
||||||
|
model="gemini-1.5-flash",
|
||||||
|
temperature=0,
|
||||||
|
)
|
||||||
|
|
||||||
|
# 2. Définition de l'état
|
||||||
|
# add_messages permet d'accumuler l'historique au lieu de l'écraser
|
||||||
|
class State(TypedDict):
|
||||||
|
messages: Annotated[list, add_messages]
|
||||||
|
|
||||||
|
# 3. Le nœud de l'agent
|
||||||
|
def call_model(state: State):
|
||||||
|
response = llm.invoke(state["messages"])
|
||||||
|
# On retourne un dictionnaire qui sera mergé avec l'état actuel
|
||||||
|
return {"messages": [response]}
|
||||||
|
|
||||||
|
# 4. Construction du graphe (Architecture actuelle)
|
||||||
|
builder = StateGraph(State)
|
||||||
|
|
||||||
|
builder.add_node("agent", call_model)
|
||||||
|
|
||||||
|
builder.add_edge(START, "agent")
|
||||||
|
builder.add_edge("agent", END)
|
||||||
|
|
||||||
|
# Compilation
|
||||||
|
graph = builder.compile()
|
||||||
|
|
||||||
|
# 5. Exécution propre
|
||||||
|
if __name__ == "__main__":
|
||||||
|
initial_state = {"messages": [("user", "Salut, tu tournes sur quelle version de Gemini ?")]}
|
||||||
|
|
||||||
|
# Utilisation de .stream() pour voir ce qui se passe
|
||||||
|
for chunk in graph.stream(initial_state):
|
||||||
|
for node, values in chunk.items():
|
||||||
|
print(f"--- Node: {node} ---")
|
||||||
|
print(values["messages"][-1].content)
|
||||||
53
rag_import.py
Normal file
53
rag_import.py
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
import os
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
#from langchain_community.document_loaders import TextLoader
|
||||||
|
from langchain_community.document_loaders import Docx2txtLoader
|
||||||
|
from langchain_text_splitters import RecursiveCharacterTextSplitter
|
||||||
|
from langchain_google_genai import GoogleGenerativeAIEmbeddings
|
||||||
|
from langchain_qdrant import QdrantVectorStore
|
||||||
|
|
||||||
|
# 1. Chargement de la clé API
|
||||||
|
load_dotenv()
|
||||||
|
api_key = os.getenv("GOOGLE_API_KEY")
|
||||||
|
|
||||||
|
def inserer_documents():
|
||||||
|
print("1. Chargement du document...")
|
||||||
|
# Assurez-vous d'avoir un fichier mon_document.txt à côté de ce script
|
||||||
|
#loader = TextLoader("resources/cv.docx", encoding="utf-8")
|
||||||
|
loader = Docx2txtLoader("resources/cv.docx")
|
||||||
|
documents = loader.load()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
print("2. Découpage du texte en morceaux...")
|
||||||
|
# On coupe le texte par blocs de 500 caractères, avec un chevauchement de 50 caractères
|
||||||
|
# (Le chevauchement évite de couper une phrase importante au milieu)
|
||||||
|
text_splitter = RecursiveCharacterTextSplitter(
|
||||||
|
chunk_size=500,
|
||||||
|
chunk_overlap=50
|
||||||
|
)
|
||||||
|
morceaux = text_splitter.split_documents(documents)
|
||||||
|
print(f"-> Le document a été découpé en {len(morceaux)} morceau(x).")
|
||||||
|
|
||||||
|
print("3. Connexion au modèle d'Embedding...")
|
||||||
|
# C'EST CRUCIAL : C'est le même modèle que dans votre script de recherche !
|
||||||
|
embeddings = GoogleGenerativeAIEmbeddings(model="models/gemini-embedding-001")
|
||||||
|
|
||||||
|
print("4. Envoi vers Qdrant...")
|
||||||
|
# On utilise la méthode "from_documents" qui va tout faire d'un coup :
|
||||||
|
# Créer la collection (si elle n'existe pas), vectoriser, et sauvegarder.
|
||||||
|
qdrant_url = "http://qdrant:6333"
|
||||||
|
nom_collection = "rag-1"
|
||||||
|
|
||||||
|
QdrantVectorStore.from_documents(
|
||||||
|
documents=morceaux,
|
||||||
|
embedding=embeddings,
|
||||||
|
url=qdrant_url,
|
||||||
|
collection_name=nom_collection,
|
||||||
|
)
|
||||||
|
|
||||||
|
print("✅ Succès ! Les données sont dans Qdrant.")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
inserer_documents()
|
||||||
76
rag_llm.py
Normal file
76
rag_llm.py
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
import os
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
from langchain_google_genai import ChatGoogleGenerativeAI, GoogleGenerativeAIEmbeddings
|
||||||
|
from langchain_qdrant import QdrantVectorStore
|
||||||
|
from qdrant_client import QdrantClient
|
||||||
|
from langchain_classic.chains import create_retrieval_chain
|
||||||
|
from langchain_classic.chains.combine_documents import create_stuff_documents_chain
|
||||||
|
from langchain_core.prompts import ChatPromptTemplate
|
||||||
|
|
||||||
|
# 1. Chargement de la clé API
|
||||||
|
load_dotenv()
|
||||||
|
api_key = os.getenv("GOOGLE_API_KEY")
|
||||||
|
|
||||||
|
def interroger_mon_rag(question):
|
||||||
|
# --- A. CONFIGURATION DES MODÈLES ---
|
||||||
|
# Le modèle qui va générer la réponse
|
||||||
|
llm = ChatGoogleGenerativeAI(model="gemini-2.5-flash", google_api_key=api_key, temperature=0)
|
||||||
|
|
||||||
|
# Le modèle qui transforme le texte en vecteurs (doit être le même que celui utilisé pour remplir la base)
|
||||||
|
embeddings = GoogleGenerativeAIEmbeddings(model="models/gemini-embedding-001")
|
||||||
|
|
||||||
|
# --- B. CONNEXION À QDRANT ---
|
||||||
|
# Remplacez l'URL par l'adresse de votre VM (ex: http://localhost:6333)
|
||||||
|
# Et mettez le vrai nom de votre collection Qdrant
|
||||||
|
qdrant_url = "http://qdrant:6333"
|
||||||
|
nom_collection = "rag-1"
|
||||||
|
|
||||||
|
client = QdrantClient(url=qdrant_url)
|
||||||
|
|
||||||
|
# On connecte LangChain à Qdrant
|
||||||
|
vector_store = QdrantVectorStore(
|
||||||
|
client=client,
|
||||||
|
collection_name=nom_collection,
|
||||||
|
embedding=embeddings
|
||||||
|
)
|
||||||
|
|
||||||
|
# On transforme la base en "Retriever" (un outil qui va chercher les 3 meilleurs documents)
|
||||||
|
retriever = vector_store.as_retriever(search_kwargs={"k": 3})
|
||||||
|
|
||||||
|
# --- C. CRÉATION DU PROMPT RAG ---
|
||||||
|
# Le mot {context} sera automatiquement remplacé par les documents trouvés dans Qdrant
|
||||||
|
system_prompt = (
|
||||||
|
"Tu es un assistant utile. Utilise UNIQUEMENT les morceaux de contexte "
|
||||||
|
"fournis ci-dessous pour répondre à la question. Si tu ne connais pas la réponse "
|
||||||
|
"à partir du contexte, dis simplement que tu ne sais pas."
|
||||||
|
"\n\n"
|
||||||
|
"Contexte :\n{context}"
|
||||||
|
)
|
||||||
|
|
||||||
|
prompt = ChatPromptTemplate.from_messages([
|
||||||
|
("system", system_prompt),
|
||||||
|
("human", "{input}"),
|
||||||
|
])
|
||||||
|
|
||||||
|
# --- D. ASSEMBLAGE DE LA CHAÎNE ---
|
||||||
|
# 1. Chaîne qui combine les documents récupérés et le prompt
|
||||||
|
question_answer_chain = create_stuff_documents_chain(llm, prompt)
|
||||||
|
|
||||||
|
# 2. Chaîne globale qui fait la recherche PUIS appelle la chaîne précédente
|
||||||
|
rag_chain = create_retrieval_chain(retriever, question_answer_chain)
|
||||||
|
|
||||||
|
# --- E. EXÉCUTION ---
|
||||||
|
print(f"Recherche de la réponse pour : '{question}'...\n")
|
||||||
|
reponse = rag_chain.invoke({"input": question})
|
||||||
|
|
||||||
|
print("🤖 Réponse de Gemini :")
|
||||||
|
print(reponse["answer"])
|
||||||
|
|
||||||
|
print("\n📄 Documents sources utilisés :")
|
||||||
|
for doc in reponse["context"]:
|
||||||
|
# Affiche un extrait du document source et ses métadonnées
|
||||||
|
print(f"- {doc.page_content[:100]}... (Source: {doc.metadata})")
|
||||||
|
|
||||||
|
# Test du script
|
||||||
|
if __name__ == "__main__":
|
||||||
|
interroger_mon_rag("Quelles sont les passions de vincent poupet ?")
|
||||||
12
requirements
Normal file
12
requirements
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
langchain
|
||||||
|
langchain_classic
|
||||||
|
langchain_community
|
||||||
|
langgraph
|
||||||
|
langchain-google-vertexai
|
||||||
|
langchain-core
|
||||||
|
langchain-google-genai
|
||||||
|
dotenv
|
||||||
|
qdrant-client
|
||||||
|
langchain-qdrant
|
||||||
|
langchain-chain
|
||||||
|
docx2txt
|
||||||
BIN
resources/cv.docx
Normal file
BIN
resources/cv.docx
Normal file
Binary file not shown.
30
simple_llm_call.py
Normal file
30
simple_llm_call.py
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import os
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
from langchain_google_genai import ChatGoogleGenerativeAI
|
||||||
|
|
||||||
|
|
||||||
|
# Charger les variables du fichier .env
|
||||||
|
load_dotenv()
|
||||||
|
api_key = os.getenv("GOOGLE_API_KEY")
|
||||||
|
|
||||||
|
# 1. Configuration de la clé API
|
||||||
|
# Remplacez 'VOTRE_CLE_API' par votre véritable clé
|
||||||
|
#os.environ["GOOGLE_API_KEY"] = api_key
|
||||||
|
|
||||||
|
def interroger_gemini(question):
|
||||||
|
# 2. Initialisation du modèle
|
||||||
|
# On choisit le modèle 'gemini-1.5-flash' pour sa rapidité
|
||||||
|
llm = ChatGoogleGenerativeAI(model="gemini-2.5-flash",google_api_key=api_key)
|
||||||
|
|
||||||
|
# 3. Appel du modèle
|
||||||
|
print(f"Question posée : {question}")
|
||||||
|
reponse = llm.invoke(question)
|
||||||
|
|
||||||
|
# Affichage du contenu de la réponse
|
||||||
|
return reponse.content
|
||||||
|
|
||||||
|
# Test du script
|
||||||
|
if __name__ == "__main__":
|
||||||
|
resultat = interroger_gemini("Quels sont les 3 avantages d'apprendre Python ?")
|
||||||
|
print("\nRéponse de Gemini :")
|
||||||
|
print(resultat)
|
||||||
29
system_llm_call.py
Normal file
29
system_llm_call.py
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import os
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
from langchain_google_genai import ChatGoogleGenerativeAI
|
||||||
|
from langchain_core.prompts import ChatPromptTemplate
|
||||||
|
|
||||||
|
# Charger les variables du fichier .env
|
||||||
|
load_dotenv()
|
||||||
|
api_key = os.getenv("GOOGLE_API_KEY")
|
||||||
|
|
||||||
|
# Initialisation du modèle
|
||||||
|
llm = ChatGoogleGenerativeAI(model="gemini-2.5-flash",google_api_key=api_key)
|
||||||
|
|
||||||
|
def expert_en_codage(concept):
|
||||||
|
# 1. On définit un Template (le "moule" de la question)
|
||||||
|
prompt = ChatPromptTemplate.from_messages([
|
||||||
|
("system", "Tu es un expert en programmation Python. Explique les concepts de manière simple avec un exemple de code court."),
|
||||||
|
("human", "Explique-moi le concept suivant : {concept}")
|
||||||
|
])
|
||||||
|
|
||||||
|
# 2. On crée une "chaîne" (Chain) simple
|
||||||
|
chain = prompt | llm
|
||||||
|
|
||||||
|
# 3. On lance la chaîne en remplissant la variable
|
||||||
|
reponse = chain.invoke({"concept": concept})
|
||||||
|
|
||||||
|
print(reponse.content)
|
||||||
|
|
||||||
|
# Test
|
||||||
|
expert_en_codage("Les list comprehensions")
|
||||||
31
system_llm_stream.py
Normal file
31
system_llm_stream.py
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import os
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
from langchain_google_genai import ChatGoogleGenerativeAI
|
||||||
|
from langchain_core.prompts import ChatPromptTemplate
|
||||||
|
|
||||||
|
# Charger les variables du fichier .env
|
||||||
|
load_dotenv()
|
||||||
|
api_key = os.getenv("GOOGLE_API_KEY")
|
||||||
|
|
||||||
|
# Initialisation du modèle
|
||||||
|
llm = ChatGoogleGenerativeAI(model="gemini-2.5-flash",google_api_key=api_key)
|
||||||
|
|
||||||
|
def expert_en_codage(concept):
|
||||||
|
# 1. On définit un Template (le "moule" de la question)
|
||||||
|
prompt = ChatPromptTemplate.from_messages([
|
||||||
|
("system", "Tu es un expert en programmation Python. Explique les concepts de manière simple avec un exemple de code court."),
|
||||||
|
("human", "Explique-moi le concept suivant : {concept}")
|
||||||
|
])
|
||||||
|
|
||||||
|
# 2. On crée une "chaîne" (Chain) simple
|
||||||
|
chain = prompt | llm
|
||||||
|
|
||||||
|
# Au lieu de .invoke(), on utilise .stream()
|
||||||
|
# Cela retourne un générateur (itérable)
|
||||||
|
for chunk in chain.stream({"concept": concept}):
|
||||||
|
# Chaque 'chunk' est un morceau de la réponse
|
||||||
|
# On utilise end="" pour ne pas revenir à la ligne et flush=True pour forcer l'affichage
|
||||||
|
print(chunk.content, end="", flush=True)
|
||||||
|
|
||||||
|
# Test
|
||||||
|
expert_en_codage("Les variables")
|
||||||
Reference in New Issue
Block a user