This is a viewer only at the moment see the article on how this works.
To update the preview hit Ctrl-Alt-R (or ⌘-Alt-R on Mac) or Enter to refresh. The Save icon lets you save the markdown file to disk
This is a preview from the server running through my markdig pipeline
Thursday, 18 December 2025
我是一个开发者。当我开始建立LLM 动力系统时, 所有人都把我指向Lang Chain。 “这是标准标准,”他们说,“所有的例子都使用它。”他们说得对,如果你在Python生态系统, Lang Chain无处不在。
但事情是这样的:我不回避朗查因(Lang Chain),因为那不好。我避免它,因为它解决的问题我已经更明确地解决了, 并且为了我使用的案例C#、当地推论、隐私、确定论框架增加了摩擦而不是价值。
这不是一个反LangChain的文章。这是一个关于理解问题框架解决了哪些问题, 并意识到你可能不需要这些问题的文章。
论文:如果你理解兰钱解决的问题, 你不需要朗钱。
让我们先公平一点,兰钱在很多方面都很出色:
快速原型 你可以在几分钟内做一个工作演示。
Python生态系统一体化 - 如果你已经进入了Python/Jupyter/pandas世界, Lang Chain 将一切无缝地粘在一起。
降低屏障 - 对于新到LLMs的人,它提供有用的抽象信息:即时模板、工具调用模式、记忆管理、矢量DB集成。
Lang Chain是一个 集成加速器它加快了从"我有想法"到"我有一个演示"的道路。这很有价值。
但这也是我作为C#开发商 建立生产系统的问题 开始出现的地方。
在排除一个框架之前,你需要了解它正在解决什么问题。朗查因解决了这些真正的问题:
这些是正当的问题。问题是:你需要一个框架来解决它们吗?
Lang Chain在多个领域引发摩擦。
Lang Chain 管理您的记忆和上下文。 这听起来很方便, 直到你需要调试为什么你的提示比预期的要长一万个符号, 或者为什么LLM突然能进入您认为已经清除的谈话历史。
框架集合了提示, 管理内存, 并隐含地处理执行命令 。 当某事破裂时, 您正在调试框架的行为, 而不是代码的行为 。
一旦你收养了兰钱 你就会开始设计 Lang Chain 代表兰钱。您的结构与框架的抽象概念相结合:链条、代理人、检索器、记忆缓冲器。
这不是兰钱所独有的 所有框架都这样做。但是在像LLMS这样的快速移动的领域, 正确的抽象概念还没有解决, 与框架的世界观挂钩是危险的。
Lang Chain假设:
作为网络开发商,我想:
缩略 Lang Chain.NET港口 但是他们正在追赶 Python 版本, 和抽象 仍然觉得陌生 的特异C#。
当您从原型转向生产时,需要:
Lang Chain 优化迭代速度, 而不是生产硬化。 这对演示来说很好; 这是生产的问题 。
我使用的心理模型是这样的: LLMs是推理引擎,不是执行引擎。
原则: LLM 理由 引擎计算
这种分离会驱动我建造的一切
而不是由框架管理的内存,我根据请求明确构建上下文:
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 因为我自己制造了弦:
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();
}
没有隐藏的状态,没有魔法的结合,只有明确的弦建筑,当它错了,我知道为什么。
而不是让LLM执行任何东西, 我用它来产生 意图,然后通过确定性引擎执行这一意图:
LLM 生成 SQL. DuckDB 执行它。 LLM 从未看到数据 :
// 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);
这是更安全、更快和可调试的。 LLM 不能意外运行 。 DROP TABLE 因为我首先验证了 SQL 。 LLM 不能泄露数据, 因为它从未看到过数据, 只看到计划。
我最近写到 使用本地LLMS 分析大型 CSV 文件架构:
用户问 题 * LLM * SQL * DuckDB * 结果
法学硕士接收:
LLM 产生:
然后,系统:
EXPLAIN (未执行的渔获物语法错误)法学硕士从不看实际数据,只看结构。
Lang Chain将这个称为“代理”一个使用LLM生成动作、验证它们、执行它们以及可能重试失败的系统。
除了我把它建在~200条C#线上,没有框架:
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);
}
}
没有链子,没有代理框架,没有魔法,只是明确指挥LLM 校验执行
"代理"这个词经常被传来传去 通常是指"任何与LLM有关的东西"
代理人是:
探员是 非库库这是一个模式。
我的经纪人模式在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);
}
}
这是一个代理。这是一个关于状态、 工具和反馈的循环。 我用30行写下来。 我不需要一个框架 。
微软为了公平对待.NET生态系统, 微软代理框架 这是专门为.NET开发商 建造的 生产人工智能系统
该框架(前称微软.Extensions.AI)规定:
关键组成部分:
IChatClient - 聊天补全统一界面IEmbeddingGenerator - 供应商之间的矢量嵌入AIFunction - 安全类型功能调用示例:
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;
});
即使有微软的框架, 我更喜欢保持核心管弦 明确:
我不想:
我想:
微软的代理框架比朗查因更接近于我的想法。 它尊重.NET模式, 正确使用依赖注射, 并且不对抗生态系统。 但我还是更喜欢自己写管弦曲。
何时使用 Microsoft 代理框架 :
何时去无框架:
框架并不消除建筑决策。 您仍然选择了上下文、 数据块、 以及何时重试。 它只会让管道更容易操作 。
没有框架的系统年龄更高,原因如下:
业绩 业绩业绩 业绩业绩 我的CSV查询服务运行子100米 因为LLM和DuckDB之间没有框架
成本可预测性 框架管理的记忆里没有隐蔽的快速通货膨胀
可调试性 - 当有东西坏了,我在调试我的代码, 而不是反向设计一个框架的魔力。
隐私隐私 - 使用有严格数据居住要求的系统,确切知道机器有什么问题。
离线情景 - 边缘装置、空控网络、受管制的环境,框架包括互联网接入和云服务。
监管合规 - 在金融、医疗和政府方面,你经常需要解释和审核每一个决定。“框架做到了”是一个无法接受的答案。
环境越受限制,你就越需要明确的控制。
解除批评者的武装: 有一些合法的案例, 我会找到朗钱恩。
Hackathons( 哈卡通) - 快速演示比建筑更重要
丢弃的POCs - 如果你正在验证一个想法 并计划改写 制作反正。
Python重重队 - 如果你的团队在Python已经流利, 生态系统的适合性是很强的。
教学概念 Lang Chain的抽象学可以帮助初学者在建立自己的模式之前 了解特工的模式
了解时间 否 使用某物与知道何时使用一样重要。
这不是兰钱,而是框架和第一原则工程之间的取舍
框架加速了熟悉问题。 如果您正在构建第100 CRUD API, 将会达到实体框架或 Dapper 。 模式会稳定下来 。
但是LLM 动力系统?正确的抽象元素还没有解决。 我们不知道“ 链条” 或“ 试剂” 或“ 试剂” 是正确的心理模型。 我们还在研究。
在那种环境中,我更喜欢靠近金属:
OllamaSharp,开放的AISDK)作为一个.NET开发者,我对如何建立系统有强烈的看法: 明确的寿命、强的打字、连续不断的同步、 依赖性注射以进行测试。
Lang Chain的抽象观点并不完全符合这些观点,所以我不使用它。
如果你是一个.NET开发商 看着朗钱 想知道"我需要这个吗?" 这就是我的回答:
你需要解决兰钱解决的问题 - 环境管理、工具协调、重试逻辑、可观察性。
你不需要兰钱解决他们 - 特别是如果你重视清晰度, 强打字, 和生产硬化 相对于快速原型。
原则一建立在以下基础上:
"LLMs理由 引擎计算 指挥权属于你"
或更简单的:
"如果你理解一个框架解决的问题, 你经常不需要这个框架。"
建立在生态系统中有意义的系统, 利用你的语言的风格。对我来说,就是C#, 强大的打字, 明确的控制流, 和决定性的执行层。
对你来说,可能不同,那很好
目标不是回避框架,而是有意识地选择框架,了解框架提供的内容和成本。
进一步阅读:
© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.