<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Provider Abstraction on YennJ12 Engineering Blog</title><link>https://yennj12.js.org/yennj12_blog_V4/tags/provider-abstraction/</link><description>Recent content in Provider Abstraction on YennJ12 Engineering Blog</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Fri, 07 Aug 2026 12:00:00 +0800</lastBuildDate><atom:link href="https://yennj12.js.org/yennj12_blog_V4/tags/provider-abstraction/feed.xml" rel="self" type="application/rss+xml"/><item><title>OpenWorker 深度解析（四）：LLM 層 — Provider 抽象、能力降級與 Context 自動壓縮</title><link>https://yennj12.js.org/yennj12_blog_V4/posts/openworker-intro-part4-llm-provider-compaction-zh/</link><pubDate>Fri, 07 Aug 2026 12:00:00 +0800</pubDate><guid>https://yennj12.js.org/yennj12_blog_V4/posts/openworker-intro-part4-llm-provider-compaction-zh/</guid><description>「支援多家 LLM」聽起來像是一個 adapter pattern 練習題。 直到你發現：Anthropic 沒有 mid-thread system message、 Gemini 的 thought signature 必須原樣送回、 OpenAI 的 GPT-5.6 在 Chat Completions 上不准 tools 搭配 reasoning、 而使用者可以在對話中途從 Claude 換到 Ollama 上的 Llama。
本篇是 OpenWorker 深度解析系列 的第四篇，處理 coworker/providers/（4,507 行）與 coworker/compaction.py（561 行）。
一、為什麼不能只用 LiteLLM 多 provider 抽象的市場已經很成熟（LiteLLM、aisuite 自己、OpenRouter）。 OpenWorker 仍然自己寫了一層，理由可以歸納成四點：
┌──────────────────────────────────────────────────────────────────────────┐ │ ① 需要「能力查詢」而不只是「呼叫代理」 │ │ provider.capabilities(model) → tools / vision / pdf / │ │ parallel_tool_calls / streaming │ │ → 使用者上傳 PDF，模型不支援時要在本地抽文字，而不是直接 400 │ ├──────────────────────────────────────────────────────────────────────────┤ │ ② 需要保存「provider 私有欄位」跨輪次 │ │ Gemini thought signature、OpenAI Responses 的 encrypted reasoning │ │ → 純代理層會把這些欄位丟掉，導致思考鏈中斷 │ ├──────────────────────────────────────────────────────────────────────────┤ │ ③ 需要正規化的 token 計數（含快取拆分） │ │ input / output / cache_read / cache_write │ │ → 這是 context 壓縮的觸發訊號，也是成本顯示的來源 │ ├──────────────────────────────────────────────────────────────────────────┤ │ ④ 需要「單次呼叫、不含迴圈」的契約 │ │ 因為迴圈裡要塞權限檢查、中斷、審計 — 那是 runtime 的職責 │ └──────────────────────────────────────────────────────────────────────────┘ 二、ProviderClient：一個刻意樸素的契約 1class ProviderClient(ABC): 2 &amp;#34;&amp;#34;&amp;#34;Single-shot, provider-agnostic completion interface.</description></item></channel></rss>