1. 为什么要在本地跑通 Microsoft Agent FrameworkMicrosoft Agent Framework 是微软官方开源的 Agent 框架把模型调用、工具、记忆、多轮对话统一成一套抽象再用 Workflows 编排多智能体协作DurableTask 负责长跑任务的状态持久化。官方文档把每个能力都讲得很清楚但“每个能力单独看懂”和“拼成一个能落地的真实项目”之间还差一段距离。Inkwell 就是拿来填这段距离的项目一个建在 Microsoft Agent Framework 之上的智能体工作空间支持自助创建、配置、发布、版本化 LLM Agent统一接入不同模型用桌面客户端和 Agent 对话。这篇面向需要在本地快速跑通 Agent 工作流的开发者交付一套可复制的配置骨架包含 settings.json 和 config.toml 示例以及逐步验证动作。核心思路是Agent 装配走 MAF 原生入口模型网关交给 LiteLLM Proxy而模型调用的 Key 和 API 通道统一通过 TaoToken 接入这样你本地不用散落各家厂商的凭据换模型只改一处配置。照着配完你能完成一次可验证的 Agent 调用看到流式返回。适合谁已经装好 .NET 10 SDK 和 Docker Desktop、想拿真实项目逼一遍 MAF 抽象的开发者或者手里有一堆模型 Key、想统一收口到一条通道再喂给 Agent 的人。下面从环境前置讲到配置骨架再到验证请求和排障每一步都能跟做。2. 前置准备TaoToken 统一 Key 与 API 通道在写配置文件之前先把模型通道这件事定下来。Inkwell 的设计里模型网关用 LiteLLM ProxyLiteLLM Portal 是模型与路由唯一的事实源Inkwell 自己不持有任何模型厂商凭据只持有 LiteLLM 内部地址和网关 Key。那么 LiteLLM 背后的上游模型从哪来这就是 TaoToken 的位置它提供统一的 Key 和 API 通道你把它配成 LiteLLM 的一个上游 provider后面所有 Agent 调用都走这条通道。先拿到 Key。打开控制台创建 API Keyhttps://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite创建后复制那串 Key形如sk-...后面要填进 LiteLLM 的 provider 配置。注意别把它提交进 git本地用 user-secrets 或环境变量存。TaoToken 的 API 基地址是https://taotoken.net/api这个地址不加任何查询参数直接作为 OpenAI 兼容的 base_url 使用。LiteLLM 里配 provider 时api_base填它api_key填你刚创建的 Key。如果你还想在配之前先确认模型能不能通可以用模型对话页面直接发一条消息试试https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite接入文档在这里LiteLLM 的 provider 字段含义、OpenAI 兼容格式的请求体都能对照https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite注意TaoToken 是统一的 API 通道不是让你去改编辑器或 IDE 的插件配置。它的角色是给 LiteLLM 提供一个 OpenAI 兼容的上游Agent 框架本身不感知它。3. 可复制配置骨架settings.json 与 config.toml这一节是全文的核心给你两份能直接抄的配置。先说明目录约定Inkwell 后端是 .NET 10 ASP.NET Core 10Agent 引擎用 MAF 的Microsoft.Agents.AI/.AGUI/.Workflows/.DurableTask几个包。本地跑起来需要 .NET 10 SDK 和 Docker Desktop。3.1 settings.jsonAgent 与模型通道settings.json放在src/core/Inkwell.AppHost同级或你项目的配置目录负责声明 Agent 装配参数和模型通道。下面这份是骨架字段按你的实际模型名替换{ AgentFramework: { DefaultAgent: { name: local-assistant, modelId: gpt-4o-mini, instructions: 你是一个本地跑通的 Agent回答简洁遇到工具调用先说明意图。, temperature: 0.3, maxTokens: 2048, stream: true }, Skills: { enabled: true, readOnlyCatalog: true } }, LLMGateway: { provider: litellm, portalUrl: http://localhost:6804, internalBaseUrl: http://litellm:4000, gatewayKeyRef: Parameters:litellm-master-key }, Upstream: { name: taotoken, apiBase: https://taotoken.net/api, apiKeyRef: Parameters:taotoken-api-key, compatible: openai }, Persistence: { provider: postgres, connectionStringRef: ConnectionStrings:Inkwell } }几个关键点解释一下。AgentFramework.DefaultAgent.modelId是逻辑模型名它必须能在 LiteLLM Portal 里被发现Inkwell 业务层只校验这个 ModelId 是否属于 Chat 类别真正的调用交给 MAF。Upstream.apiBase就是 TaoToken 的 API 地址apiKeyRef指向 user-secrets 里的键不写明文。LLMGateway.internalBaseUrl是容器内 LiteLLM 的地址本地开发时 AppHost 会把它编排起来。3.2 config.tomlLiteLLM 上游 providerLiteLLM 的配置用config.toml或config.yaml看你的 LiteLLM 版本字段一致。这份把 TaoToken 配成 OpenAI 兼容上游[general] master_key os.environ/LITELLM_MASTER_KEY database_url os.environ/DATABASE_URL [model_list] [[model_list.model]] model_name gpt-4o-mini litellm_params.model openai/gpt-4o-mini litellm_params.api_base https://taotoken.net/api litellm_params.api_key os.environ/TAOTOKEN_API_KEY [[model_list.model]] model_name claude-3-5-sonnet litellm_params.model openai/claude-3-5-sonnet litellm_params.api_base https://taotoken.net/api litellm_params.api_key os.environ/TAOTOKEN_API_KEY [router_settings] routing_strategy simple-shuffle num_retries 2 timeout 120model_name是 Inkwell 里modelId要匹配的名字litellm_params.model用openai/前缀表示走 OpenAI 兼容协议api_base统一指向 TaoTokenapi_key从环境变量读。这样你新增模型只改这一段Inkwell 那边通过ILLMProvider实时发现不用重启业务层。3.3 环境变量与 secrets把 Key 存进 user-secrets别写进文件dotnet user-secrets --project src/core/Inkwell.AppHost set Parameters:litellm-master-key local-litellm-key dotnet user-secrets --project src/core/Inkwell.AppHost set Parameters:taotoken-api-key sk-你的TaoTokenKeyLiteLLM 容器侧读环境变量export LITELLM_MASTER_KEYlocal-litellm-key export TAOTOKEN_API_KEYsk-你的TaoTokenKey export DATABASE_URLpostgresql://inkwell:inkwelllocalhost:5432/inkwell注意Parameters:taotoken-api-key和TAOTOKEN_API_KEY是同一个值的两种注入方式前者给 .NET 配置系统后者给 LiteLLM 容器。别只配一边。4. 启动与验证跑通一次 Agent 调用配置齐了按顺序启动。先克隆并进入项目git clone https://github.com/shuaihuadu/inkwell.git cd inkwell dotnet run --project src/core/Inkwell.AppHostAspire 会把 PostgreSQL、LiteLLM、后端服务一起编排起来。启动后先做三件事。第一登录 LiteLLM Portal 添加模型和供应商凭据http://localhost:6804/ui默认管理员账号密码都是admin首次登录要改密码。在 Portal 里确认gpt-4o-mini这类模型已经出现且上游指向 TaoToken。第二打开 Aspire Dashboard 看服务状态https://localhost:15888确认litellm、postgres、后端 API 都是 Running。如果 LiteLLM 起不来多半是TAOTOKEN_API_KEY没注入到容器。第三发一次验证请求。Inkwell 客户端和后端之间走 REST AG-UI流式交互直接用ag-ui/client对接 AG-UI Protocol 的 SSE 端点。先用 curl 直接打 LiteLLM确认通道通curl -s http://localhost:4000/v1/chat/completions \ -H Authorization: Bearer local-litellm-key \ -H Content-Type: application/json \ -d { model: gpt-4o-mini, messages: [{role: user, content: 用一句话说明你走的是哪条通道}], stream: false }返回里能看到choices[0].message.content就说明 LiteLLM 到 TaoToken 这条链路通了。接着验证 Agent 层通过 Inkwell 的 Agent 试运行接口发一条curl -N http://localhost:5000/api/agents/local-assistant/run \ -H Content-Type: application/json \ -d {input: 你好做个自我介绍, stream: true}-N关掉 curl 缓冲你能看到 SSE 分块返回。成功的结果是先收到若干data:事件内容是逐步生成的文本最后有一个结束事件。到这一步一次可验证的 Agent 调用就完成了。如果你更想先在网页里确认模型行为用模型对话页面发一条同样的消息对照输出https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite5. 本篇常见错排查配这套骨架时报错基本集中在几个地方逐个对。报错一ModelId not found或 Agent 试运行返回 404。说明 Inkwell 没在 LiteLLM Portal 里发现这个模型。检查settings.json的modelId和config.toml的model_name是否完全一致大小写敏感。改完 Portal 里的模型后Inkwell 通过ILLMProvider实时发现但如果你缓存了模型列表重启后端。报错二LiteLLM 返回 401。两种可能local-litellm-key和LITELLM_MASTER_KEY不一致或者TAOTOKEN_API_KEY没注入。先确认 curl 打 LiteLLM 时用的 Bearer 和容器里的 master key 一致再确认容器环境变量里有 TaoToken 的 Key。报错三LiteLLM 返回 502 或超时。上游不通。检查api_base是不是https://taotoken.net/api注意不要多加路径或查询参数。再确认你的 Key 在控制台里状态正常、额度够用。router_settings.timeout设 120 秒长回答别设太短。报错四SSE 没有分块一次性返回。检查请求里stream是否为true以及 curl 有没有加-N。AG-UI 的 SSE 端点对缓冲敏感中间如果有反向代理确认它没开响应缓冲。报错五dotnet run起不来Aspire 报端口占用。6804、15888、4000、5000 这几个端口被占。先docker ps看有没有残留容器docker compose down清掉再起。报错六数据库连不上。Persistence.provider设了postgres但ConnectionStrings:Inkwell没配。Inkwell 支持 PostgreSQL / SQL Server 双数据库切 provider 时连接串也要跟着换业务代码不用动这是 Ports Adapters 分层锁死的约束。提示排障时优先用 curl 直接打 LiteLLM把 Agent 层和通道层分开定位。通道通了再查 Agent 装配能省一半时间。6. 后续接入与长期编码跑通一次调用只是起点。接下来你要做的是把 Agent 从“能跑”推到“能长期用”。如果你打算把 Agent 接进日常编码流程、做长期跑的编码助手或 Agent 工作流建议用 Coding Plan 把调用额度和通道固定下来避免每次临时配 Keyhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite如果你要管理多个 Key、给团队分配不同通道去 API Keys 页面统一收口https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite接入细节和字段含义对照文档LiteLLM provider 配置、OpenAI 兼容请求体都在里面https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite如果你用的是 Claude Code 这类 Anthropic 协议的客户端接入方式单独看这一页https://taotoken.net/claude-code-anthropic?utm_sourcetaotoken_aicg_blog_endutm_contentclaude-code-anthropicutm_campaignrewrite回到 Inkwell 本身它现在能跑起来的部分包括 Agent 创建与完整配置、草稿保存与试运行、发布与版本历史、团队共享与复制、LiteLLM 模型发现与基础对话、Agent Skills 管理与只读工具目录、用户账号管理、Aspire 本地编排双数据库。还在做的是版本回滚的桌面操作、协作治理、知识库、长期记忆、多模态、调试与评测、对外协议兼容与生产部署。你可以拿这套骨架先跑通再按自己的需求往上加。最后留一个实操建议把settings.json和config.toml都纳入版本管理但 Key 一律走 user-secrets 和环境变量。这样团队里任何人 clone 下来只要注入自己的 TaoToken Key就能复现同一套 Agent 配置换模型只改config.toml的model_list一段业务层一行不动。