Varför använder jag inte LangChain? Vad gör jag istället? (Svenska (Swedish))

Varför använder jag inte LangChain? Vad gör jag istället?

Thursday, 18 December 2025

//

12 minute read

I' är en . NET-utvecklare . När jag började bygga LLM, -, kraftfulla system,,, pekade alla på mig mot LangChain.., ", det är ', standarden.," sa de: "" ., M SK10, alla exempel använder den ""..", och de hade rätt.

Men här är det: ' är grejen, : Jag undviker LangChain eftersom den är dålig. . Jag undvek den för att den löser problem som jag redan löst mer explicitt., och för mina användarfall.

Det här är en post om att förstå vilka problemframställningar löser och att inse att man kanske inte behöver dem.

Teorin: Om du förstår problemen som LangChain löser,

Vad LangChain faktiskt gör bra

Låt oss vara rättvisa först. LangChain är duktig på flera saker.

Rapid prototyping - Du kan få en fungerande demo på några minuter . De exemplen som du fått igång är riktigt bra

Pythons ekosystemintegration - Om du ' är redan i Python/Jupyter

Att sänka barriären - För folk som nykommar till LLMs , den ger användbara abstraktioner : prompt-templater M SK3 verktygsrakande mönster för att ringa Mska4 minneshantering M Ska5 vektordatabasintegreringar

LangChain är en integrationsaccelerator, inte en AI-anforderung . Den accelererar vägen från "~ Jag har en idé till "~ I have a demo ."~ Det är värdefullt

Men det är också där problemet börjar för mig som C-byggare som bygger produktionssystem.

Problemet som LangChain löser

Innan man avlägsnar ett ramverk, måste man förstå vilka problem det löser.

  1. Kontextkonstruktion - Att bygga konsekventa prompter från schemat , prover
  2. verktygsorkestering - Att hantera flera verktygsuttalande i sekvenser med villkorlig logik
  3. Stadsstyre - Att upprätthålla konversationskontext över flera vridningar
  4. Försök igen och lösa fel - Att återhämta elegant när LLM genererar felaktig utgång
  5. Multi-steg resonemang - Breaking of complex tasks into sequential steps
  6. Observerbarhet - Att följa vad som faktiskt hände under uitvoeringen

Det här är legitima problem.

Var LangChain börjar skadas

För mitt arbete - byggproduktion . NET-system med lokala LLMs | , | strikta privatlivsbehov |, | och deterministiskt beteende ♫ - | LangChain introducerar friktion i flera områden

Hemliga tillstånd och dolda kontrollflöden

LangChain sköter minnet och kontexten för dig.

Frameworket kankotekera instruktioner, sköter minnet , och hanterar exécutionsorten implizit. När något går sönderM SK3 gör duMSC4 avbuggar frameworket ' beteenden Mska6 inte din kod Mske7 beteendetMska8

Framework-Koppelat tankesätt

När du håller på med LangChain, så börjar du designa för LangChain. Din arkitektur blir kopplad till ramverket ' abstraktionerna M SK2 kedjor , agenter

Detta är inte unikt för LangChain. Alla ramverk gör det. Men i ett snabbt rörligt område som LLM, där rätt abstraktioner inte finns, är ' ännu löst. , kopplar ihop med ett ramverk, ' synsättet på världen är riskfyllt.

Impedans mismatch i Python

LangChain antar:

  • lång tidiga processer
  • Flygbar global tillstånd
  • Python's dynamiska typning och duck-typning
  • Att blockera I/O-mönster

Som .NET-utvecklare , antar jag

  • begäran-inriktade livslängder (ASPM SK2NET Core-mönster
  • Immutable or explicit-manad state
  • Den starka typen och sammansättningen-tidssäkerhet
  • Async/ väntar överallt

Den LangChain .NET-Porter existerar, men de spelar catch med Pythonversionen, och abstraktionerna känns fortfarande främmande för språkliga C.

Production Reality Gaps

När du flyttar från prototyp till produktion

  • Determinism - Samma inmatning borde ge ett förutsägbart beteende
  • Validering - Se till att LLMs output är säker innan man driver den
  • Sandboxing - Begränsa vad genererad kod faktiskt kan göra
  • kostnadskontroll - användandet av spårets token och införa gränser
  • Lokala slutsatser - kör modeller offline utan molnhängande

LangChain optimerar för upprepningshastigheten.

Vad jag bygger istället

Här är den mentala modellen jag använder LLM är tankemotorer

LLMs Do:

  • Interpretering - Att förstå användarmedvetandet från naturlig språk
  • Planering - Delade komplexa uppgifterna i steg
  • Vertaling - Konverterande av mening till strukturerade format SQL, JSONM SK3 funktionssignaler

LLMs gör inte det:

  • Beräkningar av agregater - sammanfattning 100,000 rader
  • Scan datamängder - Söker genom stora filer
  • Själva staten - Att upprätthålla lång tid

Principen: LLMs skäl. Motorernas beräkningar.

Den här separationen driver allt jag bygger.

Explicerad Kontext , Inte magisk minne

Istället för ett ramverk-kontrollerad minne , bygger jag kontext explicit per utmaning:

public class QueryContext
{
    public List<ColumnInfo> Schema { get; set; }
    public List<Dictionary<string, string>> SampleRows { get; set; }
    public List<ConversationTurn> History { get; set; }
    public string UserQuestion { get; set; }
}

Varje promptkonstruktion är synlig.

private string BuildPrompt(QueryContext context)
{
    var sb = new StringBuilder();
    sb.AppendLine("You are a SQL expert. Generate a query based on:");
    sb.AppendLine();
    
    // Schema
    sb.AppendLine("Schema:");
    foreach (var col in context.Schema)
        sb.AppendLine($"  - {col.Name}: {col.Type}");
    
    // History (if any)
    if (context.History.Any())
    {
        sb.AppendLine("\nPrevious conversation:");
        foreach (var turn in context.History.TakeLast(3))
            sb.AppendLine($"  Q: {turn.Question} → SQL: {turn.Sql}");
    }
    
    // Current question
    sb.AppendLine($"\nQuestion: {context.UserQuestion}");
    sb.AppendLine("Generate SQL (no explanation, just the query):");
    
    return sb.ToString();
}

Inga dolda tillstånd . Inga magiska koncatenationer. Bara explicitt strömbyggande. När det är felM SK3

Deterministiska utföringslayer

Istället för att låta LLM utföra något, använder jag den för att generera avsikt, sedan utför den intentionen genom deterministiska motorer

  • SQL-motorer (DuckDB
  • sökmotorer (LuceneM SK1 Postgresfulla -text) - För att hitta dokument
  • Reglermotorer - För affärslogi
  • Domaintjänster - För validerade operationer

LLM genererar SQL. DuckDB löser det

// LLM generates intent
var sql = await GenerateSqlAsync(context);

// Validate before execution
var error = ValidateSql(connection, sql);
if (error != null)
{
    // Retry with error feedback
    sql = await GenerateSqlAsync(context, previousError: error);
}

// Execute in sandboxed engine
var results = ExecuteQuery(connection, sql);

Det är säkrare, snabbare , och lösbart. LLM kan inte köra på grund av olyckor DROP TABLE eftersom jag validerar SQL först

Ett konkret exempel: CSV-analys utan ram

Jag skrev nyligen om att analysera stora CSV-filer med lokala LLMs. Architekturen

Användarfråga → LLM | → | SQL | → | DuckDB |→

LLM får:

  • CSV-schematen (columns namn och typer)
  • 3 prover rader ( för att förstå dataformatet
  • Användaren's fråga

LLM genererar:

  • En DuckDB SQL-fråga

Systemet då:

  • Validerar SQL med hjälp av EXPLAIN ( fångar syntaktiska fel utan att utföra
  • Executerar queryn mot CSV: s file
  • Ge tillbaka resultat till användaren

LLM ser aldrig faktiska data.

Detta är vad LangChain skulle kalla ett system som använder en LLM för att generera handlingar

Förutom att jag byggde den i ~200 linjer av C# utan ram

public class CsvQueryService
{
    private readonly OllamaApiClient _ollama;
    private readonly string _model;
    
    public async Task<QueryResult> QueryAsync(string csvPath, string question)
    {
        using var connection = new DuckDBConnection("DataSource=:memory:");
        connection.Open();
        
        // 1. Build context
        var context = BuildContext(connection, csvPath, question);
        
        // 2. Generate SQL
        var sql = await GenerateSqlAsync(context);
        
        // 3. Validate
        var error = ValidateSql(connection, sql);
        if (error != null)
        {
            // Retry once with error feedback
            sql = await GenerateSqlAsync(context, error);
        }
        
        // 4. Execute
        return ExecuteQuery(connection, sql);
    }
}

Det är ', det är det . No chains, no agent framework, no magic. Just explicit orchestration of LLM.

Vad är en agent?

Ordet """, agenten, ", sprids ständigt "", ,, brukar betyda """, allt som involverar en LLM.

En agent är:

  • En lus - Den kör flera repetitioner
  • Med stat - Den minns vad den triedt
  • Med verktyg - Den kan ta åtgärder i världen
  • Med återkoppling - Den observerar resultat och justerar

En agent är inte en bibliotek. Det ' är ett mönster

Mitt agentmönster i C#:

public class Agent
{
    private readonly List<ConversationTurn> _history = new();
    
    public async Task<string> RunAsync(string goal)
    {
        while (!IsGoalAchieved(goal))
        {
            // 1. Generate next action based on history
            var action = await GenerateActionAsync(goal, _history);
            
            // 2. Validate before executing
            if (!IsActionSafe(action))
            {
                _history.Add(new ConversationTurn 
                { 
                    Action = action, 
                    Result = "REJECTED: Unsafe action" 
                });
                continue;
            }
            
            // 3. Execute through deterministic tool
            var result = await ExecuteActionAsync(action);
            
            // 4. Record and continue
            _history.Add(new ConversationTurn { Action = action, Result = result });
        }
        
        return GenerateSummary(_history);
    }
}

Det här är en agent.

Där Microsofts Agent Framework passar

För att vara rättvis mot .NET ekosystem , Microsoft har släppt Microsoft Agent Framework att's syfte- byggts för NET utvecklare som bygger produktions-AI-system.

Vad Microsoft Agent Framework får rätt till

Frammedan ( tidigare känt som Microsoft .Extensioner.AIM SK3 erbjuder

  • Explicerad orkestrering - Du kontrollerar agentloopet , inte ramverket
  • Den starka typen - Kompilera - tids säkerhet för verktygsdefinitioner och funktionsändning
  • Observerbarhet i första klass - Inbyggda - i telemetrin , registrerade data, , och fördelade spårning via OpenTelemetry
  • Företagsgränser - Designad för produktion .NET-system med rätt DI, konfiguration , och livscykelanalys
  • Multi-modellstöd - Abstraktioner över OpenAI
  • Semantisk Kernelintegrering - Fungerar med Microsofts bredare AI-steg

Nyckelkomponenter:

  • IChatClient - Förenklad gränssnitt för konversationer
  • IEmbeddingGenerator - Vektor-inbäddar mellan leverantörer
  • AIFunction - Typ
  • Medverkningssledning - För att registrera apparater , för att återtesta apparaterna

exempel:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddChatClient(builder => 
    builder.UseOllama("llama3.2")
           .UseOpenTelemetry()
           .UseLogging());

var app = builder.Build();

app.MapPost("/chat", async (IChatClient client, string message) =>
{
    var response = await client.CompleteAsync(message);
    return response.Content;
});

Där jag fortfarande stannar lägre

Även med Microsofts framework, prefererar jag att hålla kärnans orkestr explicit.

Jag vill inte

  • Osynliga planörer - Ramen som självständigt bestämmer vilket verktyg man ska använda
  • Implicita verktygslektioner - Magikartade baserat på naturspråksbeschreibunger
  • Hemlig återtestningslogik - ramverk - skött felupphävaning Jag kan inspectera

Jag vill:

  • Visible kretsar - Jag ser varje repetition i min kod
  • Testbara steg - Jag kan testa beslutslogiken
  • Ersättningsbara komponenter - Jag kan byta ut LLM, ,, verktygen och ,, bekräftelselayern
  • Explicerad tillstånd - Jag vet exakt vad

Microsofts Agent Framework är närmare det jag tror än LangChains.

När man använder Microsoft Agent Framework:

  • Att bygga chat-applikationer med funktionen
  • Bra multi- --- -modellsupport. (- -överkoppling mellan OpenAI, ,- -Azure, ,- -Ollama och )-
  • Vill företagsdelar (telemetri,loggningM SK2 fördelad spårning )
  • Att arbeta i ett lag som föredrar ramkonsistens
  • Byggnader ovanför den semantiska kärnan

När ska man gå fram i ramverket-lös:

  • Du behöver full kontroll över agentloopet
  • Du, ', bygger egna tankesätt
  • Du vill ha noll abstraktion överhead
  • Du optimerar för specifika användningsområden ( som CSV-analys eller web scraping
  • Ni vill förstå exakt hur det fungerar

Frameworket eliminerar inte arkitektoniska beslut. Man väljer fortfarande vad man ska sätta in i sammanhanget. ,, hur man bryter ihop data.

Varför skalar detta bättre långt

Framework-lösa system åldras bättre av flera anledningar

Förmågor - Ingen abstraktion överhuvudtaget . Mitt CSV-sökningscenter kör sub-100ms eftersom det inte finns något ramverk mellan LLM och DuckDB

Förutsägbarhet - Jag kontrollerar exakt vad som går till LLM . Ingen gömd promptinflation från ramverket

Debuggbarhet - När något går sönder, Jag ' gör ont i min kod , inte bakåtvända, - utvecklar ett ramverk

Privatliv - För system med strikta dataresidensbehov , med exakt kunskap om vad som gör maskinen viktig

Offlinescenarior - Randdevicer , luft, - anpassningsbara nätverk, M SK3 reglerade miljöer, . Ramverk tar emot internet- och molntjänster,.

Reguleringsobservation - I finansiellt , inom sjukvården, , och i staten, M SK3 behöver man ofta förklara och revidera varje beslut.

Ju mer begränsad din miljö är, desto mer vill du ha explicit kontroll.

När jag skulle använda LangChain

För att avbrutna kritiker finns det legitima fall där jag

Hackathon - Rymden för att demonstrera är viktigare än arkitekturen

Slängda POCs - Om du 'Validerar en idé och planerar att skriva om för produktion i alla fall

Python-heavy teams - Om ditt team redan är flytande i Python

Lärningskoncepter - LangChain 's abstraktioner kan hjälpa nybörjare att förstå agentpattern innan de bygger sin egen

Att veta när inte att använda något är lika värdefullt som att veta när man ska använda det.

Det bredare mönstret, :, ramverk och ., första principerna

Det här handlar inte om LangChain, det handlar om ramverk och ingenjörskonst.

Ramper accelererar bekanta problem. Om du Builder ' den andra CRUD APIn

Men LLM, -, kraftfulla system, ?, rätt abstraktioner är inte klarat ännu, ', ., vi vet inte om ", kedjor, M SK6, eller ", agenter,", eller | ", sökare och ", är de rätta mentala modellerna.

I den miljön prefererar jag att bygga nära metallen

  • LLM via direkt API sändning (OllamaSharp, OpenAI SDK
  • Vinniga konstruktion genom explicitt strängbyggande
  • Validering via domain-specifik logik
  • Ausführung genom syfte-byggda motorer (SQLM SK2 sökningarMska3 etcMske4

Jag har starka åsikter om hur system ska byggas.

LangChains abstraktioner skiljer inte ' tydligt från de åsikterna, så jag använder dem inte

The Takeaway

Om du är en .NET-utvecklare som tittar på LangChain och undrar: "" Är det här något jag behöver? ""

Du behöver lösa problemen som LangChain löser - kontextstyrning , verktygsorganisering , repetitionslogik

Du behöver inte LangChain för att lösa dem. - Särskilt om du värderar upptydlighet , starkt skrivande M SK2 och att produktionen blir hårdare än snabb prototypisering

Principen jag bygger på

"LLMs skälM SK1 Motorernas beräkningar . Orchester är ditt eget

Eller mer enkelt:

"Om du förstår de problem som rammet löser,

Att bygga system som är vettiga i ditt ekosystem.,, med dina begränsningar.,, med hjälp av ditt språk.

För dig kanske det är annorlunda.

Målet är att välja dem medvetet, förstå vad de erbjuder och vad de kostar.


Weiterlesen:

Finding related posts...
logo

© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.