AI Security

Erori LangChain: Ghid Complet de Depanare

Nicu Constantin
--7 min lectura
#langchain#llm#rag#troubleshooting#python

LangChain simplifica dezvoltarea cu LLM-uri, dar vine cu propriile provocari. Acest ghid acopera erorile frecvente LangChain si solutiile lor.

Eroare: OutputParserException

Simptom:

langchain.schema.output_parser.OutputParserException:
Could not parse LLM output: `I'll help you with that...`

Cauza: LLM-ul nu a respectat formatul de output asteptat.

Solutia 1 - Foloseste un parser cu corectare automata:

from langchain.output_parsers import OutputFixingParser
from langchain.output_parsers import PydanticOutputParser
from langchain_openai import ChatOpenAI
from pydantic import BaseModel
 
class Response(BaseModel):
    answer: str
    confidence: float
 
# Base parser
parser = PydanticOutputParser(pydantic_object=Response)
 
# Wrap with fixing parser
fixing_parser = OutputFixingParser.from_llm(
    parser=parser,
    llm=ChatOpenAI(temperature=0)
)
 
# Now it will auto-fix malformed outputs
result = fixing_parser.parse(llm_output)

Solutia 2 - Foloseste un parser cu reincercare:

from langchain.output_parsers import RetryWithErrorOutputParser
 
retry_parser = RetryWithErrorOutputParser.from_llm(
    parser=parser,
    llm=ChatOpenAI(temperature=0),
    max_retries=3
)

Solutia 3 - Simplifica formatul de output:

from langchain.output_parsers import StrOutputParser
 
# Instead of complex structured output
chain = prompt | llm | StrOutputParser()
 
# Parse the string manually if needed
def parse_response(text):
    # Custom parsing logic
    return {"answer": text.strip()}

Eroare: Chain Invoke returneaza None

Simptom:

result = chain.invoke({"input": "Hello"})
# result is None or empty

Solutia 1 - Verifica constructia chain-ului:

from langchain_openai import ChatOpenAI
from langchain.prompts import ChatPromptTemplate
from langchain.schema.output_parser import StrOutputParser
 
# ❌ Wrong - missing output parser
chain = prompt | llm
 
# ✅ Correct - include output parser
chain = prompt | llm | StrOutputParser()
 
# Debug chain
print(chain)  # See chain structure

Solutia 2 - Depaneaza pasii intermediari:

from langchain.callbacks import StdOutCallbackHandler
 
# Enable verbose output
chain.invoke(
    {"input": "Hello"},
    config={"callbacks": [StdOutCallbackHandler()]}
)

Solutia 3 - Verifica variabilele prompt-ului:

prompt = ChatPromptTemplate.from_template(
    "Answer this: {question}"  # Variable name matters!
)
 
# ❌ Wrong variable name
chain.invoke({"input": "Hello"})  # Should be "question"
 
# ✅ Correct
chain.invoke({"question": "Hello"})
 
# Check required variables
print(prompt.input_variables)  # ['question']

Eroare: Conexiune vector store esuata

Simptom:

chromadb.errors.InvalidCollectionException: Collection not found
pinecone.exceptions.NotFoundException: Index not found

Solutia 1 - Initializeaza corect vector store-ul:

from langchain_community.vectorstores import Chroma
from langchain_openai import OpenAIEmbeddings
 
# Create or load existing collection
vectorstore = Chroma(
    collection_name="my_collection",
    embedding_function=OpenAIEmbeddings(),
    persist_directory="./chroma_db"  # Persist to disk
)
 
# Add documents
vectorstore.add_documents(documents)
 
# Persist changes
vectorstore.persist()

Solutia 2 - Gestioneaza indexul Pinecone:

from pinecone import Pinecone, ServerlessSpec
from langchain_pinecone import PineconeVectorStore
 
# Initialize Pinecone
pc = Pinecone(api_key="your-api-key")
 
# Check if index exists
if "my-index" not in pc.list_indexes().names():
    pc.create_index(
        name="my-index",
        dimension=1536,  # OpenAI embeddings dimension
        metric="cosine",
        spec=ServerlessSpec(cloud="aws", region="us-east-1")
    )
 
# Connect to index
vectorstore = PineconeVectorStore(
    index_name="my-index",
    embedding=OpenAIEmbeddings()
)

Solutia 3 - Depaneaza embedding-urile:

# Test embeddings separately
embeddings = OpenAIEmbeddings()
test_embedding = embeddings.embed_query("test")
print(f"Embedding dimension: {len(test_embedding)}")  # Should be 1536 for OpenAI

Eroare: Numar maxim de iteratii al agentului depasit

Simptom:

AgentExecutorIterationLimit: Agent stopped due to iteration limit or time limit

Cauza: Agentul a ramas blocat intr-o bucla sau sarcina este prea complexa.

Solutia 1 - Creste limitele cu prudenta:

from langchain.agents import AgentExecutor
 
agent_executor = AgentExecutor(
    agent=agent,
    tools=tools,
    max_iterations=15,  # Increase from default 10
    max_execution_time=60,  # Seconds
    early_stopping_method="generate"  # Let agent generate final answer
)

Solutia 2 - Adauga descrieri mai bune pentru unelte:

from langchain.tools import Tool
 
# ❌ Vague description
search_tool = Tool(
    name="search",
    description="Search for information",
    func=search_func
)
 
# ✅ Clear, specific description
search_tool = Tool(
    name="web_search",
    description="Search the web for current information. Use this when you need up-to-date facts, news, or data that might not be in your training. Input should be a specific search query.",
    func=search_func
)

Solutia 3 - Foloseste un agent structurat:

from langchain.agents import create_structured_chat_agent
 
# Structured agents are more predictable
agent = create_structured_chat_agent(
    llm=ChatOpenAI(temperature=0),
    tools=tools,
    prompt=prompt
)

Eroare: Memoria nu persista

Simptom:

# Conversation context lost between calls
chain.invoke({"input": "My name is John"})
chain.invoke({"input": "What's my name?"})  # Doesn't remember

Solutia 1 - Adauga memoria corect:

from langchain.memory import ConversationBufferMemory
from langchain.chains import ConversationChain
 
memory = ConversationBufferMemory(return_messages=True)
 
chain = ConversationChain(
    llm=ChatOpenAI(),
    memory=memory,
    verbose=True
)
 
# Now it remembers
chain.invoke({"input": "My name is John"})
response = chain.invoke({"input": "What's my name?"})
print(response)  # "Your name is John"

Solutia 2 - Foloseste RunnableWithMessageHistory:

from langchain_core.runnables.history import RunnableWithMessageHistory
from langchain_community.chat_message_histories import ChatMessageHistory
 
# Store for sessions
store = {}
 
def get_session_history(session_id: str):
    if session_id not in store:
        store[session_id] = ChatMessageHistory()
    return store[session_id]
 
chain_with_history = RunnableWithMessageHistory(
    chain,
    get_session_history,
    input_messages_key="input",
    history_messages_key="history"
)
 
# Use with session
response = chain_with_history.invoke(
    {"input": "Hi, I'm John"},
    config={"configurable": {"session_id": "user123"}}
)

Solutia 3 - Persista memoria in baza de date:

from langchain_community.chat_message_histories import SQLChatMessageHistory
 
history = SQLChatMessageHistory(
    session_id="user123",
    connection_string="sqlite:///chat_history.db"
)
 
# Messages persist across restarts
history.add_user_message("Hello")
history.add_ai_message("Hi there!")

Eroare: Document Loader a esuat

Simptom:

ValueError: File type not supported
UnicodeDecodeError: 'utf-8' codec can't decode byte

Solutia 1 - Foloseste loader-ul corect:

from langchain_community.document_loaders import (
    PyPDFLoader,
    TextLoader,
    CSVLoader,
    UnstructuredWordDocumentLoader
)
 
# PDF files
loader = PyPDFLoader("document.pdf")
 
# Text with encoding
loader = TextLoader("document.txt", encoding="utf-8")
 
# CSV
loader = CSVLoader("data.csv")
 
# Word documents
loader = UnstructuredWordDocumentLoader("document.docx")
 
docs = loader.load()

Solutia 2 - Gestioneaza erorile de encoding:

from langchain_community.document_loaders import TextLoader
 
# Try different encodings
encodings = ["utf-8", "latin-1", "cp1252"]
 
for encoding in encodings:
    try:
        loader = TextLoader("document.txt", encoding=encoding)
        docs = loader.load()
        print(f"Success with {encoding}")
        break
    except UnicodeDecodeError:
        continue

Eroare: Retrieval returneaza rezultate irelevante

Simptom:

# Query: "What is the refund policy?"
# Returns: documents about shipping instead

Solutia 1 - Ajusteaza parametrii de retrieval:

retriever = vectorstore.as_retriever(
    search_type="similarity",
    search_kwargs={
        "k": 4,  # Number of results
        "score_threshold": 0.7  # Minimum similarity
    }
)
 
# Or use MMR for diversity
retriever = vectorstore.as_retriever(
    search_type="mmr",
    search_kwargs={
        "k": 4,
        "fetch_k": 20,  # Fetch more, then filter
        "lambda_mult": 0.5  # Diversity vs relevance
    }
)

Solutia 2 - Imbunatateste chunking-ul:

from langchain.text_splitter import RecursiveCharacterTextSplitter
 
# Better chunking preserves context
splitter = RecursiveCharacterTextSplitter(
    chunk_size=1000,
    chunk_overlap=200,  # Overlap prevents context loss
    separators=["\n\n", "\n", ". ", " ", ""]
)
 
chunks = splitter.split_documents(documents)

Solutia 3 - Adauga filtrare pe metadata:

# Add metadata when indexing
for doc in documents:
    doc.metadata["category"] = "refund_policy"
 
vectorstore.add_documents(documents)
 
# Filter during retrieval
retriever = vectorstore.as_retriever(
    search_kwargs={
        "k": 4,
        "filter": {"category": "refund_policy"}
    }
)

Referinta rapida: Rezolvari frecvente

| Eroare | Rezolvare rapida | |--------|-----------------| | OutputParserException | Foloseste OutputFixingParser | | Chain returneaza None | Adauga StrOutputParser() | | Vector store nu este gasit | Verifica persist_directory | | Agentul intra in bucla | Imbunatateste descrierile uneltelor | | Memoria se pierde | Foloseste ConversationBufferMemory | | Documente gresite | Ajusteaza k si score_threshold |

Bune practici LangChain

from langchain_openai import ChatOpenAI
from langchain.prompts import ChatPromptTemplate
from langchain.schema.output_parser import StrOutputParser
from langchain.callbacks import StdOutCallbackHandler
 
# Production-ready chain
def create_robust_chain():
    llm = ChatOpenAI(
        temperature=0,
        model="gpt-4o",
        request_timeout=60,
        max_retries=3
    )
 
    prompt = ChatPromptTemplate.from_messages([
        ("system", "You are a helpful assistant."),
        ("human", "{input}")
    ])
 
    chain = prompt | llm | StrOutputParser()
 
    return chain
 
# Usage with error handling
chain = create_robust_chain()
try:
    result = chain.invoke(
        {"input": "Hello"},
        config={"callbacks": [StdOutCallbackHandler()]}
    )
except Exception as e:
    print(f"Chain failed: {e}")

Construiesti aplicatii RAG?

Sistemele RAG de productie necesita un design atent. Echipa noastra ofera:

  • Consultanta pentru arhitectura RAG
  • Optimizare baze de date vectoriale
  • Audituri de securitate LLM
  • Optimizare performanta

Obtine expertiza LangChain

Ai nevoie de ajutor cu conformitatea EU AI Act sau securitatea AI?

Programeaza o consultatie gratuita de 30 de minute. Fara obligatii.

Programeaza un Apel

Weekly AI Security & Automation Digest

Get the latest on AI Security, workflow automation, secure integrations, and custom platform development delivered weekly.

No spam. Unsubscribe anytime.