AutoGen .NET 连接 LM Studio:使用 AutoGen.LMStudio 包调用本地 OpenAI 兼容服务
AutoGen.LMStudio 是 AutoGen .NET 中专门用于消费 LM Studio 本地服务器所暴露的 OpenAI 兼容(openai-like)API 的封装包。本篇基于仓库中该包的 README、源码实现与官方示例,讲解其安装方式、LMStudioConfig / LMStudioAgent 的用法与参数、内部如何通过自定义 HTTP 传输层把 OpenAI SDK 请求重定向到本地服务,以及在较新版本中推荐的替代方案 OpenAIChatAgent 接法,帮助你在 .NET 应用中把 LLM 对话能力完全落地到本地、离线环境。
包定位与安装
AutoGen.LMStudio 的定位非常聚焦:让 AutoGen 的 agent 能够把模型请求发往运行在本地的 LM Studio 服务,而不依赖云端 OpenAI 服务。从项目文件 AutoGen.LMStudio.csproj 可以看到,该包引用了 AutoGen.Core(提供 IAgent、IMessage 等核心抽象与 ILLMConfig 接口)和 AutoGen.OpenAI.V1(提供 GPTAgent 与 OpenAI 客户端封装),这决定了它的实现思路是"复用 OpenAI 客户端、只替换目标地址"。
安装方式(摘自 dotnet/src/AutoGen.LMStudio/README.md):在 .csproj 中添加
<ItemGroup>
<PackageReference Include="AutoGen.LMStudio" Version="AUTOGEN_VERSION" />
</ItemGroup>
其中 AUTOGEN_VERSION 需替换为你实际采用的 AutoGen 版本号(仓库中所有 README 均使用占位符写法,发布时由打包流程填充)。
基本用法:LMStudioConfig 与 LMStudioAgent
README 给出的最小可用示例如下:
using AutoGen.LMStudio;
var localServerEndpoint = "localhost";
var port = 5000;
var lmStudioConfig = new LMStudioConfig(localServerEndpoint, port);
var agent = new LMStudioAgent(
name: "agent",
systemMessage: "You are an agent that help user to do some tasks.",
lmStudioConfig: lmStudioConfig)
.RegisterPrintMessage(); // register a hook to print message nicely to console
await agent.SendAsync("Can you write a piece of C# code to calculate 100th of fibonacci?");
要真正跑通,前提是你已在本机启动 LM Studio 并开启其本地开发服务器(LM Studio 的默认端口为 1234;示例代码中使用了 5000,只要与实际服务端口一致即可),并且已在 LM Studio 中加载了一个模型。
LMStudioConfig:host + port 生成服务 URI
LMStudioConfig.cs 的实现非常精简,提供了两个构造重载:
public class LMStudioConfig : ILLMConfig
{
public LMStudioConfig(string host, int port)
{
this.Host = host;
this.Port = port;
this.Uri = new Uri($"http://{host}:{port}");
}
public LMStudioConfig(Uri uri)
{
this.Uri = uri;
this.Host = uri.Host;
this.Port = uri.Port;
}
public string Host { get; }
public int Port { get; }
public Uri Uri { get; }
}
要点:
LMStudioConfig : ILLMConfig:该接口定义于 dotnet/src/AutoGen.Core/ILLMConfig.cs,是 AutoGen .NET 各 LLM 配置(OpenAI、Azure OpenAI、LM Studio 等)的统一契约;- 构造时固定拼接
http://{host}:{port},即默认走 HTTP 明文连接——这与"本地服务器"的使用场景相符; - 也支持直接传入完整
Uri,便于复用既有配置。
LMStudioAgent:内部是一个 GPTAgent
LMStudioAgent.cs 的构造函数暴露了完整参数面,比 README 示例多出 temperature、maxTokens、function calling 相关参数:
public LMStudioAgent(
string name,
LMStudioConfig config,
string systemMessage = "You are a helpful AI assistant",
float temperature = 0.7f,
int maxTokens = 1024,
IEnumerable<FunctionDefinition>? functions = null,
IDictionary<string, Func<string, Task<string>>>? functionMap = null)
name:agent 名称,在群聊等场景下用于消息路由;systemMessage:默认"You are a helpful AI assistant";temperature默认0.7f,maxTokens默认1024;functions/functionMap:可选的函数定义与处理函数映射,表示该 agent 在协议层支持 OpenAI 风格的 function calling——能否实际生效取决于 LM Studio 所选模型是否支持工具调用。
从源码结构看,LMStudioAgent 本质上是一个组合包装:内部持有 GPTAgent innerAgent,GenerateReplyAsync、Name 等 IAgent 成员全部直接委托给内部 agent:
var client = ConfigOpenAIClientForLMStudio(config);
innerAgent = new GPTAgent(
name: name,
systemMessage: systemMessage,
openAIClient: client,
modelName: "llm", // model name doesn't matter for LM Studio
temperature: temperature,
maxTokens: maxTokens,
functions: functions,
functionMap: functionMap);
注释说明了 modelName: "llm" 的取值:本地服务对模型标识不敏感,任意占位字符串均可。
源码解析:请求是如何被重定向到本地服务的
LMStudioAgent 的核心在于 ConfigOpenAIClientForLMStudio 与私有类 CustomHttpClientHandler。其做法不是修改 OpenAI SDK 的默认 Endpoint 语义,而是给 OpenAIClient 注入一个自定义 HttpClientTransport:
private OpenAIClient ConfigOpenAIClientForLMStudio(LMStudioConfig config)
{
// create uri from host and port
var uri = config.Uri;
var handler = new CustomHttpClientHandler(uri);
var httpClient = new HttpClient(handler);
var option = new OpenAIClientOptions(OpenAIClientOptions.ServiceVersion.V2022_12_01)
{
Transport = new HttpClientTransport(httpClient),
};
return new OpenAIClient("api-key", option);
}
OpenAIClient使用占位 API Key("api-key"),因为本地服务器不需要鉴权;ServiceVersion.V2022_12_01指定了 OpenAI 客户端的服务版本;- 真正起作用的是
CustomHttpClientHandler:
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var uriBuilder = new UriBuilder(_modelServiceUrl);
uriBuilder.Path = request.RequestUri?.PathAndQuery ?? throw new InvalidOperationException("RequestUri is null");
request.RequestUri = uriBuilder.Uri;
return base.SendAsync(request, cancellationToken);
}
即在每次发送请求前,把 OpenAI SDK 生成的 RequestUri 的 Host 部分替换为 LM Studio 的地址(http://{host}:{port}),保留原有的路径与查询串(如 /chat/completions),再交由基类发出。这是"把一个标准 OpenAI SDK 客户端无缝指向任意 OpenAI 兼容本地服务"的经典手法,后续版本中的 Ollama 等第三方接入示例沿用了同样的模式。
版本提示:Obsolete 标记与推荐的 OpenAIChatAgent 写法
需要注意的是,LMStudioAgent.cs 类上带有如下特性:
[Obsolete("Use OpenAIChatAgent to connect to LM Studio")]
public class LMStudioAgent : IAgent
也就是说,仓库当前版本已将 LMStudioAgent 标记为过时,推荐使用 AutoGen.OpenAI 包中的 OpenAIChatAgent 直接连接 LM Studio。官方示例 Example08_LMStudio.cs 展示的正是这一新写法(示例默认端口为 LM Studio 惯用的 1234):
using System.ClientModel;
using AutoGen.Core;
using AutoGen.OpenAI;
using AutoGen.OpenAI.Extension;
using OpenAI;
var endpoint = "http://localhost:1234";
var openaiClient = new OpenAIClient(new ApiKeyCredential("api-key"), new OpenAIClientOptions
{
Endpoint = new Uri(endpoint),
});
var lmAgent = new OpenAIChatAgent(
chatClient: openaiClient.GetChatClient("<does-not-matter>"),
name: "assistant")
.RegisterMessageConnector()
.RegisterPrintMessage();
await lmAgent.SendAsync("Can you write a piece of C# code to calculate 100th of fibonacci?");
与旧版 LMStudioAgent 相比,新写法有两点差异值得注意:
- Endpoint 由
OpenAIClientOptions.Endpoint直接指定,无需再手写CustomHttpClientHandler做 URI 重写; - 必须调用
RegisterMessageConnector():OpenAIChatAgent使用 OpenAI V1 的新消息模型,需要消息连接器把 AutoGen 核心消息类型(TextMessage、FunctionCallMessage等)转换为 OpenAI 协议消息。同一示例中模型名<does-not-matter>与旧实现的modelName: "llm"语义一致——本地服务对模型标识不敏感。
仓库中类似的第三方 OpenAI 兼容服务接入(Ollama 等)可参考 Connect_To_Ollama.cs 与文档 OpenAIChatAgent-connect-to-third-party-api.md,其核心思路(占位 API Key + 指定本地 Endpoint)与 LM Studio 完全一致。
更新历史与适用前提
按 dotnet/src/AutoGen.LMStudio/README.md 的 Update history:0.0.7(2024-02-11)版本引入了 LMStudioAgent 以支持消费 LM Studio 本地服务器的 openai-like API。
使用前提归纳:
- 本机已安装并启动 LM Studio,且其本地开发服务器(默认
http://localhost:1234)已加载模型; - 若使用旧版
AutoGen.LMStudio包,其内部依赖AutoGen.OpenAI.V1的GPTAgent,会因Obsolete特性在编译期产生过时警告,建议迁移到OpenAIChatAgent方案; - 函数调用、结构化输出等高级能力能否生效,取决于 LM Studio 中实际加载的模型是否支持相应 OpenAI 特性,仓库文档对这类平台差异也提示以对应平台文档为准。
相关源码与文档索引
| 类型 | 路径 |
|---|---|
| 包 README(本文档依据) | dotnet/src/AutoGen.LMStudio/README.md |
| Agent 实现(含 URI 重写逻辑) | dotnet/src/AutoGen.LMStudio/LMStudioAgent.cs |
| 配置类(host/port → URI) | dotnet/src/AutoGen.LMStudio/LMStudioConfig.cs |
| 包工程文件(依赖 AutoGen.Core / AutoGen.OpenAI.V1) | dotnet/src/AutoGen.LMStudio/AutoGen.LMStudio.csproj |
| 官方 LM Studio 示例(OpenAIChatAgent 新写法) | dotnet/samples/AgentChat/AutoGen.Basic.Sample/Example08_LMStudio.cs |
| ILLMConfig 接口定义 | dotnet/src/AutoGen.Core/ILLMConfig.cs |
| 第三方 OpenAI API 接入文档 | dotnet/website/articles/OpenAIChatAgent-connect-to-third-party-api.md |
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00