← Back to Portfolio

Migrating from LangChain to PMCR-O: A Comparison Guide

You've built agents with LangChain. They work, but you're hitting limits: Python-only, complex chains, and no built-in self-improvement. PMCR-O offers a different path: .NET-native, self-referential agents that evolve through strange loops.

This guide shows you how to migrate from LangChain to PMCR-O, mapping patterns and architectures.

🎯 Migration Philosophy: LangChain is a tool for building agents. PMCR-O is a framework for building autonomous agents. The migration isn't just codeβ€”it's a shift from instruction-following to identity-embodying.

Architecture Comparison

Aspect LangChain PMCR-O
Language Python .NET 10 (C#)
Architecture Chain-based (linear workflows) Strange loop (self-referential cycles)
Agent Pattern ReAct (Reason + Act) PMCR-O (Planner-Maker-Checker-Reflector-Orchestrator)
Identity Second-person ("You are...") First-person ("I AM...")
Memory Conversation memory, vector stores Cognitive trails (externalized, persistent)
Self-Improvement Manual (you update prompts) Built-in (Reflector evolves through cycles)
Communication Function calls, REST APIs gRPC microservices + REST gateway
Orchestration LangGraph, custom workflows Microsoft Agents AI Workflows
Deployment FastAPI, Flask, Docker .NET Aspire, Kubernetes, Azure

Pattern Mapping: LangChain β†’ PMCR-O

1. Simple Agent β†’ Planner Agent

LangChain Pattern

Python
from langchain.agents import initialize_agent, AgentType
from langchain.llms import OpenAI

llm = OpenAI(temperature=0)
tools = [search_tool, calculator_tool]

agent = initialize_agent(
    tools,
    llm,
    agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
    verbose=True
)

response = agent.run("What is the weather in Seattle?")

PMCR-O Equivalent

C#
// Planner Agent Service (gRPC)
public class PlannerAgentService : AgentService.AgentServiceBase
{
    private readonly IChatClient _chatClient;
    private readonly AgentMcpToolsHelper _mcpToolsHelper;

    public override async Task<AgentResponse> ExecuteTask(
        AgentRequest request,
        ServerCallContext context)
    {
        // Get tools (equivalent to LangChain tools)
        var mcpTools = await _mcpToolsHelper.GetPlannerToolsAsync();

        // Create agent with BIP identity
        var agent = new ChatClientAgent(
            _chatClient,
            new ChatClientAgentOptions
            {
                Name = "Planner",
                ChatOptions = new ChatOptions
                {
                    Instructions = @"I AM the Planner.
I TRANSFER complex intent into minimal viable plans.",
                    Tools = mcpTools
                }
            });

        var thread = agent.GetNewThread();
        var response = await agent.RunAsync(
            new ChatMessage(ChatRole.User, request.Intent),
            thread);

        return new AgentResponse
        {
            Content = response.Text,
            Success = true
        };
    }
}

2. Chain β†’ PMCR-O Workflow

LangChain Pattern

Python
from langchain.chains import LLMChain, SimpleSequentialChain

plan_chain = LLMChain(llm=llm, prompt=plan_prompt)
code_chain = LLMChain(llm=llm, prompt=code_prompt)

overall_chain = SimpleSequentialChain(
    chains=[plan_chain, code_chain],
    verbose=True
)

result = overall_chain.run("Build a REST API")

PMCR-O Equivalent

C#
// Orchestrator coordinates PMCR-O phases
public class OrchestrationApiController : ControllerBase
{
    [HttpPost("execute")]
    public async Task<IActionResult> ExecuteAsync([FromBody] AgentRequest request)
    {
        // 1. Planner phase (equivalent to plan_chain)
        var plannerResponse = await _plannerClient.ExecuteTaskAsync(
            new AgentRequest { Intent = request.Intent });

        // 2. Maker phase (equivalent to code_chain)
        var makerResponse = await _makerClient.ExecuteTaskAsync(
            new AgentRequest { Intent = plannerResponse.Content });

        // 3. Checker phase (validation)
        var checkerResponse = await _checkerClient.ExecuteTaskAsync(
            new AgentRequest { Intent = makerResponse.Content });

        // 4. Reflector phase (self-improvement)
        var reflectorResponse = await _reflectorClient.ExecuteTaskAsync(
            new AgentRequest { Intent = checkerResponse.Content });

        return Ok(new
        {
            Plan = plannerResponse.Content,
            Artifact = makerResponse.Content,
            Validation = checkerResponse.Content,
            Reflection = reflectorResponse.Content
        });
    }
}

3. Memory β†’ Cognitive Trails

LangChain Pattern

Python
from langchain.memory import ConversationBufferMemory

memory = ConversationBufferMemory()
agent = initialize_agent(
    tools, llm, agent=AgentType.CONVERSATIONAL_REACT_DESCRIPTION,
    memory=memory
)

# Memory persists within conversation
response = agent.run("What did I ask about earlier?")

PMCR-O Equivalent

C#
// Cognitive trails persist beyond sessions
public class PlannerAgentService : AgentService.AgentServiceBase
{
    private readonly KnowledgeVaultService _knowledgeVault;

    public override async Task<AgentResponse> ExecuteTask(
        AgentRequest request,
        ServerCallContext context)
    {
        // Query past cognitive trails (semantic search)
        var pastSolutions = await _knowledgeVault.SearchAsync(
            request.Intent, topK: 3);

        // Build context from past solutions
        var contextPrompt = pastSolutions.Any()
            ? $"Similar past solutions:\n{string.Join("\n", pastSolutions.Select(s => $"- {s.Content}"))}"
            : "No similar past solutions found.";

        // Generate plan with context
        var response = await GeneratePlanAsync(request.Intent, contextPrompt);

        // Store this plan as cognitive trail
        await _knowledgeVault.StoreAsync(
            response.Content,
            source: "planner",
            metadata: JsonSerializer.Serialize(new { Intent = request.Intent }));

        return new AgentResponse { Content = response.Content, Success = true };
    }
}

4. Vector Store β†’ pgvector Knowledge Vault

LangChain Pattern

Python
from langchain.vectorstores import Chroma
from langchain.embeddings import OpenAIEmbeddings

embeddings = OpenAIEmbeddings()
vectorstore = Chroma.from_documents(documents, embeddings)

# Similarity search
docs = vectorstore.similarity_search("authentication", k=3)

PMCR-O Equivalent

C#
// pgvector with PostgreSQL
public class KnowledgeVaultService
{
    private readonly KnowledgeDbContext _db;
    private readonly EmbeddingService _embeddingService;

    public async Task<List<KnowledgeItem>> SearchAsync(string query, int topK = 5)
    {
        // Generate embedding
        var queryEmbedding = await _embeddingService.GenerateEmbeddingAsync(query);

        // Vector similarity search (cosine similarity)
        var results = await _db.KnowledgeEntries
            .Select(k => new
            {
                Item = k,
                Similarity = EF.Functions.VectorCosineSimilarity(k.Embedding, queryEmbedding)
            })
            .Where(x => x.Similarity >= 0.7)
            .OrderByDescending(x => x.Similarity)
            .Take(topK)
            .Select(x => x.Item)
            .ToListAsync();

        return results;
    }
}

Step-by-Step Migration Guide

Step 1: Identify Your LangChain Components

Map your LangChain code to PMCR-O equivalents:

  • Agents β†’ PMCR-O Agent Services (Planner, Maker, etc.)
  • Chains β†’ Orchestrator workflows
  • Tools β†’ MCP Tools (Model Context Protocol)
  • Memory β†’ Knowledge Vault (pgvector)
  • Vector Stores β†’ PostgreSQL with pgvector
  • Prompts β†’ BIP prompts (identity-first)

Step 2: Convert Prompts to BIP

Text
# LangChain Prompt
"You are a helpful assistant. When the user asks a question, think step by step and provide a clear answer."

# PMCR-O BIP Prompt
IDENTITY: I AM the Helpful Architect.
I TRANSFER user questions into clear, actionable answers.
I EVOLVE through feedback on my responses.

@constraints {
MANDATORY: Think step by step before responding.
FORBIDDEN: Generic advice without concrete actions.
}

Step 3: Migrate Tools to MCP

LangChain tools become MCP tools in PMCR-O:

C#
// MCP Tool (equivalent to LangChain tool)
public class WebSearchTool
{
    [Tool("web_search", "Search the web for current information")]
    public async Task<string> SearchWebAsync([ToolParameter("query")] string query)
    {
        // Implementation
        var results = await _httpClient.GetStringAsync($"https://api.search.com?q={query}");
        return results;
    }
}

// Register in agent
var mcpTools = new[] { new WebSearchTool() };
var agent = new ChatClientAgent(_chatClient, new ChatClientAgentOptions
{
    ChatOptions = new ChatOptions { Tools = mcpTools }
});

Step 4: Set Up PMCR-O Infrastructure

Create the PMCR-O project structure:

Bash
# Create PMCR-O solution
dotnet new sln -n PmcroMigration

# Create services (matching your LangChain agents)
dotnet new webapi -n PmcroMigration.PlannerService
dotnet new webapi -n PmcroMigration.MakerService
dotnet new webapi -n PmcroMigration.CheckerService
dotnet new webapi -n PmcroMigration.ReflectorService
dotnet new webapi -n PmcroMigration.OrchestrationApi

# Add Aspire orchestration
dotnet new console -n PmcroMigration.AppHost

# Add packages
dotnet add package Microsoft.Agents.AI
dotnet add package Microsoft.Extensions.AI
dotnet add package OllamaSharp
dotnet add package Grpc.AspNetCore

Step 5: Migrate Data

If you have existing LangChain data:

  • Vector Store Data: Export embeddings, import to pgvector
  • Conversation History: Convert to cognitive trail format
  • Tool Configurations: Map to MCP tool definitions

When to Migrate

βœ… Migrate to PMCR-O When:

  • You need .NET integration (existing .NET codebase)
  • You want self-improving agents (Reflector phase)
  • You need enterprise-grade deployment (Aspire, Kubernetes)
  • You want first-person identity (BIP vs prompt engineering)
  • You need persistent cognitive trails (beyond conversation memory)
  • You want gRPC microservices architecture

⚠️ Stay with LangChain When:

  • You're Python-only (no .NET infrastructure)
  • You need LangChain's extensive tool ecosystem
  • You have simple, linear workflows (no self-improvement needed)
  • You're prototyping quickly (LangChain has faster iteration)

Migration Timeline

Week 1: Set up PMCR-O infrastructure, convert one agent

Week 2: Migrate remaining agents, convert prompts to BIP

Week 3: Migrate tools to MCP, set up knowledge vault

Week 4: Parallel run (LangChain + PMCR-O), validate results

Week 5: Cutover to PMCR-O, decommission LangChain

Common Migration Challenges

Challenge 1: Python β†’ C# Syntax

Solution: Use C# async/await patterns. PMCR-O is fully async, matching Python's async nature.

Challenge 2: LangChain Tools β†’ MCP Tools

Solution: MCP tools use the same pattern (function calling). Map LangChain tool signatures to MCP tool definitions.

Challenge 3: Prompt Engineering β†’ BIP

Solution: Convert "You are..." to "I AM...". Add @constraints instead of step-by-step instructions. See BIP vs Chain-of-Thought for details.

Conclusion

Migrating from LangChain to PMCR-O isn't just a code changeβ€”it's a shift from building agents to building autonomous agents. PMCR-O's strange loops enable self-improvement that LangChain's linear chains can't match.

If you're ready to move beyond instruction-following to identity-embodying, PMCR-O is the path forward.

πŸ”— Related Resources:

Shawn Delaine Bellazan

About Shawn Delaine Bellazan

Resilient Architect & PMCR-O Framework Creator

Shawn is the creator of the PMCR-O framework, a self-referential AI architecture that embodies the strange loop it describes. With 15+ years in enterprise software development, Shawn specializes in building resilient systems at the intersection of philosophy and technology. His work focuses on autonomous AI agents that evolve through vulnerability and expression.