# 为什么我用兰查因语 和我的所作所为

<!--category-- AI, Architecture, LLM, Agents, Systems Design, C# -->
<datetime class="hidden">2025-12-18T10:00</datetime>

当我开始建造LLM-+Power Systems ,}每个人都指出我指向朗查尼・.+ @"#It'

但这里的'QQQ@: @I don's'_T 避开兰查因,因为它解决的问题我已经更明确地解决了 mSSK4}和我使用的案例“-{C#,}本地推文=,}隐私~,}确定论#-}框架增加了摩擦而不是价值\.}

这是反对-+LangChain的一篇文章, 内容是了解哪些问题框架能解决 @,+和意识到你可能不需要这些#.+

**如果你理解兰查因解决的问题 , 你不需要朗查恩・.**

[TOC]

## 兰钱究竟能做什么?

让'成为公平第一 .+LangChain在几件事情上优异

**快速原型** “- ” 您可以在分钟内有一个工作演示“ . ” 。 获得“ I- ” — 开始的示例是真正好的$. @

**Python生态系统一体化** - 如果你已经在 Python/JupyterMS K3pandas 世界?

**降低屏障** 对新加入LLM,的人来说,它提供了有用的抽象性@:提示模板 @, 工具叫做模式_,内存管理\,矢量DB集成=.

Lang Chain是一个 **集成加速器**“,”不是AI要求“.” 它加快了从 "'I 有想法的路径, 从“MS K2’I”到“MSC4I”有一个演示“."”

但问题也从我作为开发商 建造生产系统开始

## LangChain 解决问题

在驳回一个框架前, 您需要了解它解决了哪些问题? ' 兰钱(Lang Chain)能解决这些真正的问题?

1. **内部建筑** 建立来自 schema @,_样本的一致提示@,}历史_,}和限制
2. **工具管弦化** - 管理多个工具按条件逻辑顺序调用
3. **国家管理** - 维护多旋转的聊天环境
4. **重试和错误处理** - 当 LLM 生成无效输出时, 优雅地恢复@ title: group
5. **多重- step 推理** 将复杂任务分成相继步骤
6. **可观察性** 跟踪行刑期间的实情

这些是合法问题 . 问题是 您需要一个框架来解决它们吗?

## Lang Chain 开始伤害的地方

与本地LLMZ,的严格隐私要求 ,和确定性行为

### 隐藏状态和隐含控制流动

Lang Chain 管理您的内存和上下文@.}这听起来很方便,直到你需要调试为什么你的提示是 @10,000}标记比预期的还要长吗?

当某件事打破了 “,” 你和' 重新调试框架“'”行为\,}而不是您的代码'行为\MPK8

### 共同思考框架

一旦你收养了兰查伊 , 你就开始设计 **Lang Chain代表兰钱**. 您的架构与此框架相连接 *' 抽象元素 *MS K2 链串*, 代理@, 检索器\, 内存缓冲 *. 

这是Langchain 唯一的 -}所有框架都这样做 但是在一个快速移动的域里 比如LLMZ-

### Python 阻力错配

Lang Chain 假设:

- Long - @ listen process {(}\ 注意本-} 风格工作流程@)
- 可变全球状态
- Python' 动态打字和鸭子打字
- 屏蔽 I/O 模式

作为“.NET 开发者” “,” 我猜我想是“MS K2”

- 请求的--范围寿命
- 不可移动或明确{-}管理状态
- 强大的打字和编译@- @时间安全
- Async M/ 等待无处不在

缩略 [Lang Chain 朗清端口@. @NET](https://github.com/tryAGI/LangChain) @,Q}(但他們在與 Python 版本玩追蹤-+Pythons 版本的遊戲) @MSC3QQ},

### 生产实际差距

当您从原型转到生产时 @ , 您需要\ MS K1@

- **确定论** @-_Z}同样的输入应该产生可预测的行为
- **审定** - 确保 LLM'%s 输出在执行前是安全的
- **沙箱** - 限制生成代码能实际做什么
- **费用控制** - 音轨象征性使用和强制限制
- **当地推断** - 运行不依赖云的离线模型

Lang Chain 优化迭代速度@, @ not producting hardening @. @ that'_%s follow for demos @MS K3} it @ '}s a problem to programation . @

## 我所构建的

这里'是 我使用的心理模式 :" **LLMs是推理引擎 , 不是执行引擎**

### 多姆斯克女士

- **口译口译 口译 口口译口译口译** 理解自然语言的用户意图
- **规划 规划** 将复杂任务分成步骤
- **笔译翻译** - 将意图转换为结构化格式 @(SQL,JsonMS K3函数调用@)

### LL女士 诺:

- **计算总量** * - 漫射 * @100,000 列
- **扫描数据集** 正在搜索大文件@ - @% 1
- **自状态** 保持长久的- 长期内存

原则#: **计算引擎=.**

这个分离驱动了一切 我建造的一切 .

### 明确的上下文@, @% 不是魔法内存

而不是框架 @-}管理过的内存@,}我根据请求建立明确的上下文{:}

```csharp
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; }
}
```

每个快速工程都是可见的 '.... ...我确切知道什么' 被发送到LLM 因为我自己建造了字符串_

```csharp
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();
}
```

没有隐藏的状态@ . @ no magic concatenation_ MS K1} 只要直线字符串结构 * . 当它' 错误"\ ,} I know why '.#

### 确定性执行层

而不是让 LLM 执行任何东西@, @I 使用它生成 **意图**然后通过确定性引擎执行此意图 :

- **SQL 引擎** (DuckDB){}-供数据查询
- **搜索引擎** (Lucene,Postgres full *-text){@-用于文件检索
- **规则引擎** -商业逻辑
- **域服务** *-用于验证操作

LLM 生成 SQL. DuckDB 执行它 .}LLM 从不见数据@:

```csharp
// 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);
```

这是更安全的@ , @ faster @ MS K1 @ 和可调试的\ . @ LLM 可以 *'} 不小心运行 `DROP TABLE` 因为我验证了 SQL 第一次=.} LLM can'}因为从未看到过数据,

## 无框架的CSV分析

我最近写到 [用本地 LLM 分析大型 CSV 文件](https://mostlylucid.net/blog/analysing-large-csv-files-with-local-llms)“.” 建筑结构“:”

**用户问题 @→%LLM @MS K1SQL@→ DuckDB#→}结果**

法学硕士接收到:

- CSV schema @ (# column names and type_ MSSK1}CSV Schema # MSk0$colun 名称和类型@)+%
- 3樣本列( 以理解数据格式MS K2
- 用户@' @s question

LLM 生成:

- DuckDB SQL 查询

系统然后:

- 使用 SQL 校验 `EXPLAIN` ( 抓获的语法错误未执行@)
- 对 CSV 文件执行查询
- 向用户返回结果

LLM从未看到实际数据@.}它只看见结构 @.

Lang Chain 称之为“"agent"”的系统, 它使用LLM来生成动作@,验证它们 @,执行它们, 并可能重试失败时\.

除了我把它建在C#的“~200”线上,

```csharp
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);
    }
}
```

-=YTET -伊甸园字幕组=- 翻译:

## 什么是代理 ,? 真的吗?

“"”这个术语被不断地“,”,通常是指“MS K3” 任何涉及LLM."的事物。

代理商是:

- **循环环** - 它有多个迭代
- **状态** 它记得它尝试过什么
- **带工具的工具** 它可以在全世界采取行动。
- **附有反馈** 它观察结果和调整

探员是 **非库**它是一个模式 .

我在C#:的代理模式

```csharp
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);
    }
}
```

这是代理@. @ it'}用 state{,}工具\},}和反馈}♪.}我寫在「 30」 線上

## 微软{'}代理框架适合的地方

微软已发布此消息。 [微软代理框架](https://learn.microsoft.com/en-us/agent-framework/overview/agent-framework-overview) 专为@._NET开发商建造的

### 微软代理框架的正确方向

先前称为微软.#Extension@._AI_}提供 @:的框架

- **表达式** - 您控制代理机构循环\ MS K1 而不是框架
- **强打字** 用于工具定义和函数调用的安全时间
- **第一批-级可观测性** -Nilut-在遥测@,rab,,并通过开放遥测分布追踪。
- **企业边界** “-”设计用于生产“.”NET系统,配有适当的DIQ,”配置“MS K3”和生命周期管理。
- **M-+# 模型支持** “OpenAI,Azure OptiAI,OllamaMS K3和其他提供者的文摘”
- **语义内核整合** “-”与微软“'”一起工作。

密钥元件@: @%

- `IChatClient` - 聊天补全的统一界面
- `IEmbeddingGenerator` - 矢量嵌入各提供者
- `AIFunction` - type @-}安全功能呼叫
- 用于日志的中元管道 @ - @ retry @ I,}\ k2 caching@ MS K3遥测

**实例::**

```csharp
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;
});
```

### 我仍然停留在低的 -级

即使有微软的'框架 ~,我更喜欢保持核心管弦直线\:

**我并不想要 : ***

- **透明规划者** - 框架自主决定调用哪个工具
- **隐含工具选择** 以自然语言描述为基础的魔法路线
- **隐藏重试逻辑** -框架-管理错误回收

**我想要"MMSKO"**

- **可见环** 我看到我代码中的每一个迭代
- **可试验步骤** -我单位可以测试判断逻辑
- **可替换组件** -我可以用LLM,换工具 MS K2验证层
- **明确状态** 我确切地知道上下文里的内容

微软'As Agent Framework 更接近于我所想的Lang Chain.它尊重 @.NET模式@,适当使用依赖性注射\,, 并且不理会'T 与生态系统抗争. 但我还是喜欢自己写弦乐团_.

**何时使用微软代理框架@: @%**

- 建立有功能呼叫的聊天应用程序
- 需要多@-}模式支援 @ (} OpenAI MS K2}Azure,}Ollama)}两者之间的切换
- 需要企业特写 @( @teleconomic_,}记录@,}分布式追踪#)
- 在一个更倾向于框架一致性的团队中工作
- 建筑在语义核心楼顶

**何时去框架@- @less @: @%**

- 您需要完全控制代理环
- 您正在建立定制推理模式
- 你想要的零抽象间接间接费用
- 您为特定用途案例优化了 (@ like CSV 分析或网络剪切@) @%
- 你想知道它是如何工作的

框架删除了建筑设计决定@.}您仍然选择在上下文中设置什么来填充数据\,}和何时重试{.} 它只是让管道更容易去“.”

## 为何此缩放时间越长越好

由于若干原因,无系统年龄越大越好

**业绩表现 实绩** @ - @ no mession subject@.} 我的 CSV 查询服务运行 supp*-100}%s 因为 LLM 和 DuckDB 之间没有框架

**成本可预测性** @- @I control exactly what goes to the LLM.}没有来自框架的隐藏即时通膨 *-* 管理的记忆=.*

**可调试性** -}当某事打破我的代码时 @, @ I@'_m debuging my code#, @ not translate\-}设计一个框架=' @smagic*.{

**隐私隐私权** @- 对于有严格数据居住要求的系统来说#, 确切知道机器留下什么

**离线情景** @._Framewerations 承担互联网接入和云服务=.#

**监管合规** @-_Finance@,_BARBAR_,}和政府经常需要解释并审核每个决定 :#._Q"{框架是"}'}一个可以接受的答案 .}

您的环境越受限制 \ @ ,} 你就越想要明确的控制@ MS K1

## 我什么时候会用兰钱

为了解除批评者的武装 : 有合法的案例

**Hackathons( 哈卡通)** 快速演示比建筑更重要

**丢弃的POCs** - 如果您正在验证一个想法并计划重写生产内容\ .

**Python-重球队** 如果您的团队在 Python ,中已经流利,

**教学概念** 抽象可以帮助初学者在建立自己的代理模式前先了解该代理人的模式

了解时间 **否** 用于使用某物的价值与知道何时使用该物质一样重要@. @ @

## 较宽的范式:}框架与优先原则

有关框架与第一条原则之间的取舍?

框架加速了熟悉问题@.如果您正在建设“实体框架”或“Dapper.”的“MSSK2th CRUD API, 达致实体框架或 DapperMS K4”。

但LLM-动力系统 ?}正确的抽象是正确的精神模型 MS K2}我们不知道它是否还算出

在那个环境中 我更喜欢在金属附近建造

- 通过直接API电话拨打的LLMs * @(`OllamaSharp`门卡罗 开诚布公的SDK
- 通过直线弦建筑迅速建造
- 通过域校验@-}特定逻辑
- 通过目标执行@- @ 制造引擎 @ (_ SQL,# search\ ,} (等等) @.){

作为“.@NET developmenter @,我对如何建立系统有强烈的看法 ” “: 明确的终身时间 mSSK3 强的打字, async 一路往下"\, 用于测试的依赖性注射"\ .

Lang Chain' 抽象的地图是 mosk1t 直截了当地写到这些观点的地图 @.所以我不用't使用它@.}

## 外卖

如果你是一个 .+NET开发商 看着朗查因 想知道这是什么?

**你需要解决兰钱解答的问题** - 语境管理 @, 工具管弦@, 重试逻辑_,}可观察性=.

**你不需要兰钱解决他们** “-” 特别是如果您重视清晰度“,” 强烈的打字“MS K2” 和生产在快速原型上更加坚固,

原则我建立在#:的基础上

**@"LLM 理由@.}引擎计算=%.管弦是你拥有的#."}**

或者更简单一点 :

**“"”如果你理解一个框架解决了问题, 您经常需要这个框架“ ."” 。**

在您的生态系统中建立具有意义的系统@, @ 与您的限制,}使用 您的语言 @ ' @ idoms @ I. @ 用于 me@ MS K4 @ 坚固的打字@ MPK7}\ 明确控制流Q,}和确定性执行层 @.}

对于你来说,这也许不同... ...

目标是为避免框架而选择它们, 以便自觉地选择它们提供什么和花费什么。

---


**继续读取@: @%**

- [用 C# 中的本地LMs 分析大型 CSV 文件](/blog/analysing-large-csv-files-with-local-llms) *-* 一个没有框架的LLM {+}SQL的具体例子
- [使用 LLMM 获取和分析网络内容](/blog/fetching-and-analysing-web-content-with-llms) -无框架的网络剪切和分析
- [微软代理框架文件](https://learn.microsoft.com/en-us/agent-framework/overview/agent-framework-overview) -官方微软代理框架
- [微软.扩展@.AI](https://devblogs.microsoft.com/dotnet/introducing-microsoft-extensions-ai-preview/) -+NET的基建AI抽象数据
- [语义核心](https://github.com/microsoft/semantic-kernel) 微软'LLM指挥SDK
- [Lang Chain 文件文件](https://python.langchain.com/) 来理解你选择不使用什么
- [奥利亚马沙尔普](https://github.com/awaescher/OllamaSharp) - C# 本地 LLM 推断的客户端