CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-langchain-google-genai

An integration package connecting Google's genai package and LangChain

Pending
Overview
Eval results
Files

aqa.mddocs/

Attributed Question Answering (AQA)

Grounded question answering service that provides responses based exclusively on provided source passages with full attribution. Google's AQA service ensures answers are grounded in the provided context and identifies which passages were used to construct the response.

Capabilities

AqaInput

Input data structure for AQA operations.

class AqaInput:
    prompt: str
    source_passages: List[str]

Fields:

  • prompt (str): The user's question or inquiry
  • source_passages (List[str]): List of text passages that should be used to answer the question

AqaOutput

Output data structure containing the grounded answer and attribution information.

class AqaOutput:
    answer: str
    attributed_passages: List[str]
    answerable_probability: float

Fields:

  • answer (str): The generated answer based on the source passages
  • attributed_passages (List[str]): Specific passages that were used to construct the answer
  • answerable_probability (float): Probability [0.0, 1.0] that the question can be answered from the provided passages

GenAIAqa

Primary AQA service interface that extends LangChain's RunnableSerializable for pipeline integration.

class GenAIAqa:
    def __init__(
        self,
        *,
        answer_style: int = 1,
        safety_settings: List[SafetySetting] = [],
        temperature: Optional[float] = None
    )

Parameters:

  • answer_style (int): Answer generation style (1 = ABSTRACTIVE, default)
  • safety_settings (List[SafetySetting]): Content safety configuration
  • temperature (Optional[float]): Generation temperature for answer variability

Core Method

def invoke(
    self,
    input: AqaInput,
    config: Optional[RunnableConfig] = None,
    **kwargs: Any
) -> AqaOutput

Generate an attributed answer based on the input question and source passages.

Parameters:

  • input (AqaInput): Question and source passages
  • config (Optional[RunnableConfig]): Run configuration
  • **kwargs: Additional parameters

Returns: AqaOutput with answer, attribution, and confidence

Usage Examples

Basic AQA Usage

from langchain_google_genai import GenAIAqa, AqaInput

# Initialize AQA service
aqa = GenAIAqa()

# Prepare source passages
passages = [
    "Machine learning is a subset of artificial intelligence that enables computers to learn and improve from experience without being explicitly programmed.",
    "Deep learning is a specialized form of machine learning that uses neural networks with multiple layers to model and understand complex patterns.",
    "Natural language processing (NLP) is a branch of AI that helps computers understand, interpret, and manipulate human language."
]

# Create input with question and passages
input_data = AqaInput(
    prompt="What is machine learning and how does it relate to AI?",
    source_passages=passages
)

# Generate attributed answer
result = aqa.invoke(input_data)

print(f"Answer: {result.answer}")
print(f"Confidence: {result.answerable_probability:.2f}")
print("Sources used:")
for i, passage in enumerate(result.attributed_passages, 1):
    print(f"{i}. {passage}")

Document-Based Q&A

# Simulate document content
document_sections = [
    "Python was created by Guido van Rossum and first released in 1991. It emphasizes code readability with its notable use of significant whitespace.",
    "Python supports multiple programming paradigms, including procedural, object-oriented, and functional programming.",
    "Python's design philosophy emphasizes code readability and a syntax that allows programmers to express concepts in fewer lines of code.",
    "Python has a large standard library, which is often cited as one of its greatest strengths, providing tools for many tasks."
]

# Ask specific questions about the document
questions = [
    "Who created Python and when?",
    "What programming paradigms does Python support?",
    "What are Python's main strengths?"
]

aqa = GenAIAqa()

for question in questions:
    input_data = AqaInput(
        prompt=question,
        source_passages=document_sections
    )
    
    result = aqa.invoke(input_data)
    
    print(f"\nQ: {question}")
    print(f"A: {result.answer}")
    print(f"Confidence: {result.answerable_probability:.2f}")

Research Assistant

# Research passages about climate change
research_passages = [
    "Climate change refers to long-term shifts in global temperatures and weather patterns, primarily caused by human activities since the 1800s.",
    "The greenhouse effect occurs when certain gases in Earth's atmosphere trap heat from the sun, warming the planet.",
    "Carbon dioxide levels have increased by over 40% since pre-industrial times, primarily due to fossil fuel burning.",
    "Renewable energy sources like solar, wind, and hydroelectric power produce electricity without releasing greenhouse gases.",
    "Climate adaptation strategies include building sea walls, developing drought-resistant crops, and creating early warning systems."
]

# Research questions
research_questions = [
    "What causes climate change?",
    "How do renewable energy sources help with climate change?",
    "What are some climate adaptation strategies?"
]

aqa = GenAIAqa()

research_results = {}
for question in research_questions:
    input_data = AqaInput(
        prompt=question,
        source_passages=research_passages
    )
    
    result = aqa.invoke(input_data)
    research_results[question] = result

# Generate research report
print("=== Climate Change Research Report ===\n")
for question, result in research_results.items():
    print(f"Question: {question}")
    print(f"Answer: {result.answer}")
    print(f"Source Attribution: {len(result.attributed_passages)} passages used")
    print(f"Confidence: {result.answerable_probability:.1%}")
    print("-" * 50)

Integration with Vector Store

from langchain_google_genai import GoogleVectorStore

# Assume we have a populated vector store
vector_store = GoogleVectorStore(corpus_id="knowledge-base")

def aqa_with_retrieval(question: str, num_passages: int = 5):
    """Combine vector search with AQA for grounded answers."""
    
    # Retrieve relevant passages
    docs = vector_store.similarity_search(question, k=num_passages)
    passages = [doc.page_content for doc in docs]
    
    # Generate attributed answer
    aqa = GenAIAqa()
    input_data = AqaInput(
        prompt=question,
        source_passages=passages
    )
    
    result = aqa.invoke(input_data)
    
    return result, docs  # Return both answer and source documents

# Use the combined approach
question = "How do neural networks work?"
aqa_result, source_docs = aqa_with_retrieval(question)

print(f"Question: {question}")
print(f"Answer: {aqa_result.answer}")
print(f"Attribution confidence: {aqa_result.answerable_probability:.2f}")

print("\nSource documents:")
for i, doc in enumerate(source_docs, 1):
    print(f"{i}. {doc.page_content[:100]}...")

Custom Answer Styles

import google.ai.generativelanguage as genai

# Abstractive answering (default)
abstractive_aqa = GenAIAqa(
    answer_style=genai.GenerateAnswerRequest.AnswerStyle.ABSTRACTIVE
)

# Extractive answering (if available)
extractive_aqa = GenAIAqa(
    answer_style=genai.GenerateAnswerRequest.AnswerStyle.EXTRACTIVE
)

passages = [
    "Photosynthesis is the process by which plants convert sunlight into energy.",
    "During photosynthesis, plants absorb carbon dioxide from the air and water from the soil.",
    "The chlorophyll in plant leaves captures solar energy to power the photosynthesis reaction."
]

question = "How do plants convert sunlight into energy?"

# Compare answer styles
for name, aqa_instance in [("Abstractive", abstractive_aqa), ("Extractive", extractive_aqa)]:
    try:
        input_data = AqaInput(prompt=question, source_passages=passages)
        result = aqa_instance.invoke(input_data)
        
        print(f"\n{name} Answer:")
        print(f"Response: {result.answer}")
        print(f"Attribution: {len(result.attributed_passages)} passages")
    except Exception as e:
        print(f"{name} style not available: {e}")

Temperature Control

# Conservative answers (lower temperature)
conservative_aqa = GenAIAqa(temperature=0.1)

# Creative answers (higher temperature)  
creative_aqa = GenAIAqa(temperature=0.9)

passages = [
    "Artificial intelligence can be applied to healthcare for diagnostic assistance.",
    "AI helps doctors analyze medical images like X-rays and MRIs more accurately.",
    "Machine learning algorithms can predict patient outcomes based on medical data."
]

question = "How is AI used in healthcare?"

print("Conservative Answer:")
result1 = conservative_aqa.invoke(AqaInput(prompt=question, source_passages=passages))
print(result1.answer)

print("\nCreative Answer:")
result2 = creative_aqa.invoke(AqaInput(prompt=question, source_passages=passages))
print(result2.answer)

Chain Integration

from langchain_core.runnables import RunnableLambda

def prepare_aqa_input(data):
    """Helper function to prepare AQA input from chain data."""
    return AqaInput(
        prompt=data["question"],
        source_passages=data["passages"]
    )

def extract_answer(aqa_output):
    """Extract just the answer from AQA output."""
    return aqa_output.answer

# Create a chain that processes questions with AQA
aqa = GenAIAqa()

aqa_chain = (
    RunnableLambda(prepare_aqa_input)
    | aqa
    | RunnableLambda(extract_answer)
)

# Use the chain
chain_input = {
    "question": "What is quantum computing?",
    "passages": [
        "Quantum computing uses quantum mechanical phenomena like superposition and entanglement.",
        "Unlike classical bits, quantum bits (qubits) can exist in multiple states simultaneously.",
        "Quantum computers could solve certain problems exponentially faster than classical computers."
    ]
}

answer = aqa_chain.invoke(chain_input)
print(f"Chain Answer: {answer}")

Quality Assessment

def assess_aqa_quality(question: str, passages: List[str], expected_keywords: List[str]):
    """Assess the quality of AQA responses."""
    
    aqa = GenAIAqa()
    input_data = AqaInput(prompt=question, source_passages=passages)
    result = aqa.invoke(input_data)
    
    # Check confidence
    confidence_score = result.answerable_probability
    
    # Check if answer contains expected keywords
    answer_lower = result.answer.lower()
    keyword_matches = sum(1 for keyword in expected_keywords 
                         if keyword.lower() in answer_lower)
    keyword_coverage = keyword_matches / len(expected_keywords)
    
    # Check attribution quality
    attribution_ratio = len(result.attributed_passages) / len(passages)
    
    return {
        "answer": result.answer,
        "confidence": confidence_score,
        "keyword_coverage": keyword_coverage,
        "attribution_ratio": attribution_ratio,
        "quality_score": (confidence_score + keyword_coverage) / 2
    }

# Test quality assessment
passages = [
    "Machine learning algorithms learn patterns from data to make predictions.",
    "Supervised learning uses labeled examples to train models.",
    "Unsupervised learning finds hidden patterns in unlabeled data."
]

assessment = assess_aqa_quality(
    question="What is machine learning?",
    passages=passages,
    expected_keywords=["algorithms", "data", "patterns", "predictions"]
)

print(f"Answer: {assessment['answer']}")
print(f"Confidence: {assessment['confidence']:.2f}")
print(f"Keyword Coverage: {assessment['keyword_coverage']:.2f}")
print(f"Overall Quality: {assessment['quality_score']:.2f}")

Best Practices

  1. Provide relevant passages: Ensure source passages contain information relevant to the question
  2. Use sufficient context: Include enough passages to provide comprehensive coverage of the topic
  3. Check confidence scores: Use answerable_probability to determine if the answer is reliable
  4. Review attributions: Examine attributed_passages to understand which sources influenced the answer
  5. Handle low confidence: Consider providing additional or different passages if confidence is low
  6. Combine with retrieval: Use vector search to find relevant passages before applying AQA
  7. Monitor passage quality: Ensure source passages are accurate and up-to-date
  8. Consider answer style: Choose between abstractive and extractive based on your use case

Install with Tessl CLI

npx tessl i tessl/pypi-langchain-google-genai

docs

aqa.md

chat-models.md

embeddings.md

index.md

llm-models.md

safety-config.md

vector-store.md

tile.json