# Migration Guide: LangChain to Pydantic AI

This guide documents the migration of Information Composer's LLM integration layer from LangChain to Pydantic AI.

## Overview

Information Composer has migrated from LangChain to Pydantic AI as its primary LLM integration framework. This migration enables better type safety, improved developer experience, and reduced dependency footprint.

**Migration Date:** March 2026  
**Affected Modules:** `pubmed/analyzer`, examples, documentation

## What Changed

### 1. Removed Files

The following LangChain-specific files have been completely removed:

- `src/information_composer/pubmed/analyzer/langchain_adapter.py` - LangChain LLM adapter layer
- `src/information_composer/pubmed/analyzer/prompts.py` - LangChain prompt templates
- `tests/test_prompt_consistency.py` - LangChain vs Pydantic AI comparison tests

### 2. Removed Dependencies

The following packages are no longer required and have been removed from `pyproject.toml` and `requirements.txt`:

```toml
# Removed
"langchain>=0.1.0",
"langchain-core>=0.1.0",
"langchain-openai",
"langchain-ollama",
```

### 3. API Changes

#### Removed: `use_pydantic_ai` Feature Flag

The `AnalysisConfig` class no longer has a `use_pydantic_ai` field:

```python
# Old (removed)
config = AnalysisConfig(
    api_key="your-key",
    use_pydantic_ai=True  # This field no longer exists
)

# New (current)
config = AnalysisConfig(
    api_key="your-key"
)
```

**Impact:** Pydantic AI is now the only implementation. If you previously had `use_pydantic_ai=True`, your code will continue to work without modification. If you had `use_pydantic_ai=False`, you will automatically use Pydantic AI.

#### Internal Implementation Changes

The internal implementation of `PaperAnalyzer` has been updated:

- `_analyze_summary()` now always calls `_analyze_summary_pydantic()`
- `_analyze_domain()` now always calls `_analyze_domain_pydantic()`
- LangChain-specific methods have been removed

The public API remains largely unchanged - you still create a `PaperAnalyzer` with an `AnalysisConfig`:

```python
from information_composer.pubmed.analyzer import PaperAnalyzer, AnalysisConfig

# This usage remains unchanged
config = AnalysisConfig(
    api_key="your-api-key",
    model="gpt-4",
    provider="openai"
)

analyzer = PaperAnalyzer(config)
```

## Benefits of Pydantic AI

### 1. Native Pydantic Integration

Pydantic AI provides first-class support for Pydantic models as output types:

```python
from pydantic import BaseModel
from pydantic_ai import Agent

class AnalysisResult(BaseModel):
    summary: str
    confidence: float

# Type-safe output parsing
agent = Agent(
    model="openai:gpt-4",
    output_type=AnalysisResult
)
```

### 2. Better Developer Experience

- **Structured responses**: Automatic validation of LLM outputs against Pydantic schemas
- **Dependency injection**: Clean separation of concerns with `AnalysisDeps`
- **Simpler agent definitions**: System prompts are defined declaratively

### 3. Reduced Dependency Footprint

The migration removes 4 LangChain-related packages, reducing:
- Installation time
- Dependency conflicts
- Security surface area

### 4. Improved Type Safety

All LLM outputs are now validated against Pydantic models at runtime:

```python
# Result is guaranteed to match SummaryAnalysisOutput schema
result = await summary_agent.run(
    system_prompt=SYSTEM_PROMPTS["summary_analysis"],
    output_type=SummaryAnalysisOutput,
    deps=deps
)
```

## Migration Steps for Users

### Step 1: Update Package

```bash
pip install -e .
```

This will automatically remove LangChain dependencies and ensure Pydantic AI is installed.

### Step 2: Remove Feature Flag (if applicable)

If your code explicitly sets `use_pydantic_ai=True`, you can remove it:

```python
# Before
config = AnalysisConfig(
    api_key="key",
    use_pydantic_ai=True  # Remove this line
)

# After
config = AnalysisConfig(
    api_key="key"
)
```

### Step 3: Verify Installation

Test that the package imports correctly:

```python
python -c "from information_composer.pubmed.analyzer import PaperAnalyzer; print('OK')"
```

### Step 4: Run Your Code

Your existing code should work without changes. If you encounter any issues:

1. Check that `pydantic-ai` is installed: `pip show pydantic-ai`
2. Verify your API keys are still valid
3. Review any custom error handling that may reference LangChain exceptions

## Code Comparison

### Before (LangChain)

```python
from langchain_core.output_parsers import JsonOutputParser
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate

# Setup
llm = ChatOpenAI(model="gpt-4")
prompt = ChatPromptTemplate.from_template("...")
parser = JsonOutputParser()

# Execution
chain = prompt | llm | parser
result = chain.invoke({"input": data})
```

### After (Pydantic AI)

```python
from pydantic_ai import Agent
from pydantic import BaseModel

# Define output schema
class Result(BaseModel):
    summary: str
    confidence: float

# Setup and execution in one
agent = Agent(
    model="openai:gpt-4",
    output_type=Result
)

result = await agent.run("...")
```

## Breaking Changes

### For End Users

**None.** The public API remains compatible. Existing code using `PaperAnalyzer` will continue to work.

### For Contributors

1. **LangChain imports removed**: Any code importing from LangChain packages will fail
2. **Internal API changes**: Methods like `_analyze_summary_langchain()` no longer exist
3. **Test updates**: Tests relying on LangChain behavior need to be updated

## Troubleshooting

### Import Errors

If you see:
```
ModuleNotFoundError: No module named 'langchain'
```

**Solution:** Update your installation:
```bash
pip install -e .
```

### API Key Issues

Pydantic AI uses the same environment variables for API keys:
- `OPENAI_API_KEY` for OpenAI
- No special key needed for Ollama (local)

### Behavior Differences

Pydantic AI provides equivalent functionality to LangChain but with stricter type validation. If you encounter validation errors, check that your LLM outputs match the expected Pydantic schemas.

## References

- [Pydantic AI Documentation](https://ai.pydantic.dev/)
- [Project Repository](https://github.com/yourusername/information-composer)
- [Issue Tracker](https://github.com/yourusername/information-composer/issues)

## Support

If you encounter issues during migration:

1. Check this guide for common solutions
2. Review the updated examples in the `examples/` directory
3. Open an issue on GitHub with the `migration` label

---

*Last updated: March 2026*
