ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

AutoGen .NET 实战:基于 Ollama + LiteLLM 的本地模型 Function Call 完整指南

AutoGen .NET 实战:基于 Ollama + LiteLLM 的本地模型 Function Call 完整指南 AutoGen .NET 实战基于 Ollama LiteLLM 的本地模型 Function Call 完整指南【免费下载链接】autogenA programming framework for agentic AI项目地址: https://gitcode.com/GitHub_Trending/au/autogen本文围绕 AutoGen .NET 官方文档《Function call with Ollama and LiteLLM》展开讲解如何使用本地部署的 Ollama 模型以支持函数调用的dolphincoder:latest为例配合 LiteLLM 代理服务器让 AutoGen 的OpenAIChatAgent在本地完成类型安全的 Function Call。读完本篇你可以独立搭建一套本地模型 OpenAI 兼容接口 AutoGen 工具调用的完整链路并理解FunctionCallMiddleware在消息流中的底层处理机制。一、整体架构为什么需要 LiteLLM 做中间层AutoGen .NET 中与 OpenAI 生态对接的入口是OpenAIChatAgent它依赖 OpenAI SDK 的OpenAIClient。本地 Ollama 服务本身提供的是 Ollama 私有接口而 LiteLLM 可以将任意模型含 Ollama包装成OpenAI API 兼容的服务端点于是整条链路为OpenAIChatAgent (AutoGen) - OpenAI SDK (指向 http://localhost:4000) - LiteLLM 代理 (OpenAI 兼容接口) - Ollama (本地模型 dolphincoder:latest)正因为 LiteLLM 提供的是 OpenAI 兼容接口AutoGen 侧无需任何 Ollama 专属适配代码只需把OpenAIClient的 Endpoint 指向本地代理即可。二、前置条件与环境准备运行该示例需要以下三项前置条件引自官方文档 Function-call-with-ollama-and-litellm.md在本地安装 Ollama 与 LiteLLM一个支持函数调用的本地模型示例使用dolphincoder:latest已启用 .NET SDK 的 AutoGen 项目。2.1 安装 Ollama 并拉取模型按照 Ollama 官方说明完成安装后执行以下命令拉取模型ollama pull dolphincoder:latestOllama 默认监听http://localhost:11434这一点在示例代码的注释中也有明确说明见 Tool_Call_With_Ollama_And_LiteLLM.cs// Before running this code, make sure you have // - Ollama: // - Install dolphincoder:latest in Ollama // - Ollama running on http://localhost:11434 // - LiteLLM // - Install LiteLLM // - Start LiteLLM with the following command: // - litellm --model ollama_chat/dolphincoder --port 40002.2 安装 LiteLLM 并启动代理服务器通过 pip 安装带代理功能的 LiteLLMpip install litellm[proxy]然后启动指向 Ollama 模型的 OpenAI 兼容代理litellm --model ollama_chat/dolphincoder --port 4000该命令会在http://localhost:4000启动 OpenAI API 兼容的代理服务。终端出现如下输出即表示启动成功#------------------------------------------------------------# # # # The worst thing about this product is... # # https://github.com/BerriAI/litellm/issues/new # # # #------------------------------------------------------------# INFO: Application startup complete. INFO: Uvicorn running on http://0.0.0.0:4000 (Press CTRLC to quit)注意--model参数的格式约定ollama_chat/dolphincoder中前缀ollama_chat告诉 LiteLLM 底层是 Ollama 的 chat 端点dolphincoder是模型名。三、安装 AutoGen 与 AutoGen.SourceGenerator在项目目录中执行dotnet add package AutoGen dotnet add package AutoGen.SourceGeneratorAutoGen.SourceGenerator是一个 Roslyn 源生成器包用于把标记了[Function]特性的方法自动编译为类型安全的FunctionContract以及对应的XXXWrapper委托免去手工编写 JSON Schema 与参数解析代码。关于该机制的详细说明可参考 Create-type-safe-function-call.md。为了让源生成器读取方法的 XML 文档注释用于生成工具描述直接影响 LLM 对工具的识别效果需要在项目文件中启用结构化 XML 文档PropertyGroup !-- This enables structural xml document support -- GenerateDocumentationFiletrue/GenerateDocumentationFile /PropertyGroup四、定义 WeatherReport 函数并创建 FunctionCallMiddleware4.1 定义工具函数约定承载方法的类必须是public partial方法必须是public实例方法返回类型必须是Taskstring并用[Function]特性标记。示例完整代码如下摘自 Tool_Call_With_Ollama_And_LiteLLM.cs#region Function public partial class Function { [Function] public async Taskstring GetWeatherAsync(string city) { return await Task.FromResult(The weather in city is 72 degrees and sunny.); } } #endregion Function编译后源生成器会为GetWeatherAsync生成GetWeatherAsyncFunctionContract工具契约与GetWeatherAsyncWrapper可被中间件调用的包装委托。4.2 创建 FunctionCallMiddleware#region Create_tools var functions new Function(); var functionMiddleware new FunctionCallMiddleware( functions: [functions.GetWeatherAsyncFunctionContract], functionMap: new Dictionarystring, Funcstring, Taskstring { { functions.GetWeatherAsyncFunctionContract.Name!, functions.GetWeatherAsyncWrapper }, }); #endregion Create_tools构造参数含义参数类型作用functionsIEnumerableFunctionContract?工具契约列表会被透传给 Agent模型据此生成工具调用functionMapIDictionarystring, Funcstring, Taskstring?工具名 → 实际执行委托的映射用于真正执行工具并拿到结果namestring?中间件名称默认为FunctionCallMiddleware源码级原理FunctionCallMiddleware的完整实现位于 FunctionCallMiddleware.cs它实现了IStreamingMiddleware即同时支持流式与非流式。其非流式入口InvokeAsync第 63-86 行的处理逻辑值得细看它决定了工具调用的完整闭环入站短路如果消息队列中最后一条消息是ToolCallMessage通常是上一轮模型发起的调用结果回传中间件会直接在InvokeToolCallMessagesBeforeInvokingAgentAsync中执行functionMap里对应的函数返回ToolCallResultMessage内层 Agent 被短路、不会再次调用模型第 138-164 行。若某个工具名不在functionMap中会返回Function {name} is not available...的报错信息作为工具结果让模型自行纠正若functionMap为 null 则直接抛出InvalidOperationException。工具契约合并调用 Agent 前中间件会把自身持有的functions与GenerateReplyOptions.Functions中的工具合并后一并下发第 71-76 行因此可以在不同中间件中注册多组工具而不互相覆盖。出站拦截如果 Agent 的回复是ToolCallMessage且工具名在functionMap中中间件会立即执行工具并把工具调用 工具结果打包为ToolCallAggregateMessage返回第 166-190 行若回复不是工具调用或工具不可执行则原样返回模型回复。正是这个出站拦截 结果聚合的行为解释了下文运行结果中为什么一次SendAsync就能看到工具调用和工具结果两条消息。五、创建 OpenAIChatAgent 并发起对话由于 LiteLLM 代理是 OpenAI API 兼容的直接用OpenAIChatAgent作为第三方 OpenAI 兼容后端接入即可。本地服务不需要真实密钥ApiKeyCredential传任意字符串即可#region Create_Agent // api-key is not required for local server // so you can use any string here var openAIClient new OpenAIClient(new ApiKeyCredential(api-key), new OpenAIClientOptions { Endpoint new Uri(http://localhost:4000), }); var agent new OpenAIChatAgent( chatClient: openAIClient.GetChatClient(dolphincoder:latest), name: assistant, systemMessage: You are a helpful AI assistant) .RegisterMessageConnector() .RegisterMiddleware(functionMiddleware) .RegisterPrintMessage(); await agent.SendAsync(whats the weather in new york); #endregion Create_Agent关键点说明Endpoint 指向代理http://localhost:4000是 LiteLLM 端口而非 Ollama 的 11434模型名保持 Ollama 侧命名GetChatClient(dolphincoder:latest)中的模型名会透传到 LiteLLM再映射到 Ollama 的dolphincoder:latestRegisterMessageConnector()来自 OpenAIAgentExtension.cs负责把 AutoGen 消息与 OpenAI SDK 的ChatMessage互转RegisterMiddleware(functionMiddleware)注册工具调用中间件RegisterPrintMessage()控制台打印消息便于观察。六、运行结果与消息流解读运行上述对话后控制台输出形如引自官方文档AggregateMessage from assistant -------------------- ToolCallMessage: ToolCallMessage from assistant -------------------- - GetWeatherAsync: {city: new york} -------------------- ToolCallResultMessage: ToolCallResultMessage from assistant -------------------- - GetWeatherAsync: The weather in new york is 72 degrees and sunny. --------------------对照第五节的源码分析这条输出正是ToolCallAggregateMessage的打印形态外层是聚合消息AggregateMessage内部依次包含模型的ToolCallMessage参数{city: new york}和中间件本地执行后生成的ToolCallResultMessage72 degrees and sunny。模型识别出意图 → 生成工具调用 → 中间件执行本地函数 → 结果聚合回消息流整个闭环在本地完成没有任何请求离开局域网。七、小结与适用边界本方案的价值在于用最少代码打通本地模型 工具调用AutoGen 侧只写了工具类、中间件和 Agent 三段代码所有协议适配都交给 LiteLLM 完成。需要注意的适用前提与限制所选本地模型必须真正支持 function calling否则模型无法生成结构化工具调用示例选用dolphincoder:latest正是基于该能力端口与模型名需三方对齐Ollama11434← LiteLLM4000ollama_chat/模型名← OpenAI SDKEndpoint 4000模型名原样FunctionCallMiddleware依赖functionMap执行工具未注册的工具名会得到不可用错误信息而非静默失败便于调试若希望进一步理解类型安全工具契约的生成机制可继续阅读 Create-type-safe-function-call.md 与 FunctionCallGenerator.cs。完整可运行示例见 Tool_Call_With_Ollama_And_LiteLLM.cs其Program.cs入口位于同目录可按需加入自己的解决方案运行验证。【免费下载链接】autogenA programming framework for agentic AI项目地址: https://gitcode.com/GitHub_Trending/au/autogen创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进