選擇前要看的是模型、語境、索引、附加功能
僅憑“本地對應”這個詞,並不能決定外掛整體的傳送目的地。 分別確認傳遞給模型的筆記的摘錄、製作索引的地方、Web搜尋和檔案轉換的服務、診斷、更新確認。
- 模型provider・endpoint・agent
- 參考語境選擇文・摘錄・template
- 索引・搜尋是本地還是其他server
- 附加功能Web・檔案轉換・診斷・更新
這個圖是為了閱讀官方資料而整理的。 不是實際的通訊記錄。 比較是確認固定的資料和來源,不包括設定畫面的操作和實際請求、提供者的運用審計。
首先請在下表中確認使用功能的路徑。 表中的“來源”表示從程式碼中讀取的常數和分支,“提供來源的說明”表示README和指南的記載。
3個固定版,透過傳送目的地和設定進行比較
| 固定版 | 資料中顯示的路線 | 語境・索引 | 確認按鍵・設定 | 剩餘未確認 |
|---|---|---|---|---|
| 副駕駛 4.0.12 | 提供來源的說明:hosted是Brevilabs和enterprise provider。 Cloud BYOK是指定provider/endpoint,Local BYOK是local endpoint。 opencode、Claude、Codex也有各自的路線。 Q03 | 所選筆記的摘錄是模型語境。 Miyo的索引、搜尋地址另設local/remote。 Web搜尋、檔案轉換、project context確認附加路徑。 Q03 / Q05 | 來源:確認是否有SecretStorage的getter。 enableMiyo=false、activeBackend=opencode等的初期定數。 實際儲存和現行GUI尚未確認。 Q07 / Q08 / Q09 | 實payload、索引物件、終端的金鑰儲存、加密、backend的保留、遵守非學習方針。 自我選擇的診斷ZIP upload通常與request區分開來。 |
| 智慧連線 4.7.2 | 提供來源的說明:介紹內建local embedding model。 說明了不需要API key的索引製作。 Q10 / Q11 | README說明在enable之後製作Vault的索引。 設定、model的一部分是外部依賴的。 未讀完所有構成的資料路徑。 | 來源:有GitHub latest-release的GET和首次介紹中傳遞的URL。 從local embedding的說明來看,無法判斷為沒有全部通訊。 Q12 / Q13 | 實際索引、獲取模型、依賴整體、實際通訊和payload、替代model、key storage、telemetry/保留的整體。 |
| 文字生成器 0.8.7 | 源初始值:OpenAI Chat (Langchain)、https://api.openai.com/v1、key為空。 Ollama provider接收設定的basePath。 Q15 / Q23 / Q24 | includeClipboard=true可以獲取值的分支。 初期template是title・starredBlocks・tg_selection。 實際進入prompt的值需要另外確認。 Q15 / Q17 | 來源初始值:encrypt_keys=false。 不可加密/無效的話,返回固定prefix+輸入key的分支。 即使plain key欄是空的,也不能判斷為已加密。 Q15 / Q19 / Q20 / Q21 / Q22 | 實際payload、現行GUI、終端的加密結果、全功能的通訊、收費・回答質量、telemetry/保持的整體。 |
BYOK是使用自己的鍵和endpoint的方式。“ “使用自己的鑰匙”和“只停留在終端內處理”是不同的條件。
Copilot:即使選擇模型,附加功能的路徑也會另外留下
固定版的指南分為hosted・Cloud BYOK・Local BYOK・opencode・Claude・Codex的處理物件。 例如,Local BYOK的模型是local endpoint的解釋,根據使用的Skill和project context,也有涉及其他服務的情況。 Q03
將筆記的參考和Miyo的索引分開
資料中有說明,agent閱讀筆記,將必要的部分放入選擇模型的prompt中。“ 僅僅開啟Agent Chat就上傳了整個Vault”的行為沒有說明。 Miyo有local連線和remote server連線,分別選擇索引和搜尋目的地。 透過搜尋找到的摘錄也進入了模型的語境。 僅僅使用local的索引,不能說摘錄不會傳到模型provider。 Q03 / Q05
檔案處理也不是統一的。 資料上,Agent Chat的Miyo處理使用local CLI,Quick Chat使用連線的Miyo service,remote的話使用那個server處理。 使用Web・YouTube・binary file的saved project context有使用hosted project service的情況,與Miyo的選擇是不同的路徑。 Q03
不保證Self-Host Mode會切斷通訊
指南明確指出,即使是Self-Host Mode,cloud也不會失效。 傳送到選定的Claude、Codex、cloud model和搜尋provider等的路徑仍然存在。 這是為了確認每個功能是否與想要使用的功能和允許的處理物件一致的設定。 Q04
關鍵的getter、初期定數、診斷的方針,根據各自的依據來閱讀
確認的KeychainService的範圍是,確認有沒有app.secretStorage,如果沒有就會出錯的getter。 不是實際儲存金鑰的結果,也不是驗證OS加密的記錄。 enableMiyo=false、enableMiyoSearchSkill=false、activeBackend=opencode、debugFullFrames=true是源內的初始值,不顯示已轉移的設定或讀者GUI的值。 Q07 / Q08 / Q09
README說明了hosted request的隨機UUID和讀者選擇upload的診斷ZIP。 ZIP的60天后刪除,hosted request的臨時處理、非保留、非學習是提供者說明的方針。 並不是在這裡稽核backend的運用。 不能判斷只從debugFullFrames=true開始自動傳送診斷ZIP。 Q02
Smart Connections:local embedding的說明和,全部通訊的有無分開
README稱,內建本地模型會為Vault建立索引,無需API金鑰。這可作為查詢相關筆記機制的說明,但在本次比較中,我們沒有執行模型,也沒有觀察實際索引過程或網路通訊。README關於“private”“offline”和移動端的說明也僅作為提供方的宣告。Q10 / Q11
另一方面,自己的src/main.js有從initialize後的更新確認到GitHub latest-release的GET預約程式碼。 首次使用者的StoryModal會傳遞smartconnections.app的URL。 這是與通訊相關的程式碼路徑的確認。 StoryModal的實現在依賴方,實際讀取URL,以及傳遞什麼樣的payload尚未確認。 Q12 / Q13
model・settings・HTTP等部分參考了Smart Environment/jsbrains相關的外部package。 僅憑這個範圍,不能斷定“所有功能都在終端內”“沒有telemetry”“筆記本一定會被髮送”。 將本地索引的說明、更新確認的程式碼、未確認的依賴、實際通訊分開的話,可以知道追加調查的物件。 Q14
Text Generator:確認上下文的候選人和金鑰儲存的分支
可以獲取剪貼簿的設定和實際prompt是不同的
固定版的初始設定有includeClipboard=true,context builder如果其值為true,則具有可以獲取clipboard的分支。 另一方面,引用的初期template是title、starredBlocks、tg_selection,不是clipboard placeholder。 Q15 / Q17
根據template、frontmatter、context options、選擇範圍,解決的值會發生變化。 請不要將可用的值一覽表和實際請求中的值視為相同的。 這個程式碼確認不是“clipboard一定會被髮送”“Vault全部會一直被髮送”的結果。 Q17 / Q18
plain key欄的空文字不能成為加密的證據
初始值是encrypt_keys=false。 有儲存時將plain key欄清空的處理和準備其他secret相關欄位的處理。 getEncryptedKey在加密不可用或encrypt_keys無效時,返回連線固定prefix和輸入key的值。 即使欄位名稱中包含encrypted/hashed,也不能僅憑這一點判斷為加密的bytes。 Q15 / Q19 / Q20 / Q21 / Q22
鍵,所以實際儲存的內容和這個終端的safeStorage動作尚未確認。 在共享包含金鑰的配置檔案和診斷記錄之前,不僅需要關注plain欄,還需要關注儲存的其他值。
將初期provider和local對應分開選擇
源的初始provider是OpenAI Chat (Langchain),endpoint是https://api.openai.com/v1。 Ollama provider有接收設定的basePath的實現。 僅憑有local對應provider的事實,並不能證明其他功能的處理目的地和全通訊都沒有。 Q15 / Q23 / Q24
附加request、automatic suggestions、slash suggestions、JavaScript執行在引用的初始值中是OFF。 這些也不是現行GUI的實際測量值。 請在自己的環境中確認使用的template和已儲存的設定。 Q15 / Q16
根據自己的使用方法,決定要確認的設定
| 想做的事情 | 確認物件 | 僅憑這個比較是無法理解的 |
|---|---|---|
| 用雲模型處理筆記本 | model/provider/endpoint,選擇文・摘錄・template,使用的agent/Skill | 實際payload、provider的運用、請求、回答質量 |
| 想在local製作索引 | embedding/index的處理物件、remote server設定、後段的模型、模型獲取和附加功能 | 所有功能的通訊停止,依賴的所有路徑,終端的實際索引 |
| 想知道儲存、共享金鑰的範圍 | 儲存的欄位、無法使用加密的分支、日誌/診斷/設定的共享目的地 | 遵守該終端的實際儲存bytes、backend保留、刪除 |
更改設定後的狀態,不是本表實測的結果。 在使用自己的筆記本之前,請將其作為決定使用哪些功能、將哪些資料傳遞給允許的目的地的閱讀方法。
常見問題
選擇本地模型的話,外掛完全不通訊嗎?
Smart Connections會把筆記本傳送到外部嗎?
Text Generator的includeClipboard=true,是一定要傳送剪貼簿的意思嗎?
如果儲存資料的api_key是空的,金鑰已經加密了嗎?
這篇報道是否比較了AI的回答質量和費用、iPhone的動作?
確認的版本和依據的原文
以下是2026年9月30日14:25 UTC記錄的官方release和固定commit。“ 是當時確認的版本”,不保證未來的最新版。 Minimum Obsidian是manifest的值。 沒有從mobile對應flag中推測實際終端的動作。
- 副駕駛4.0.12·最小Obsidian 1.11.4 · 釋放 · 提交8c56781c43
- 智慧連線 4.7.2 · 最小 Obsidian 1.8.7 · 釋放 · 提交 92e8d56c66
- 文字生成器0.8.7 · 最小Obsidian 1.6.0 · 釋放 · 提交4b9ddf8767
官方registry也固定在commit 2db5da29e67e7600176c8c9450fd1c36c3a6831b。 關於24引用、14檔案、579行,確認與原始檔案bytes/SHA256、行範圍、引用文一致。 為了確認固定版資料的再現性而進行的核對,不是runtime privacy認證。
主要說明和程式碼的引用
英文原文和程式碼是固定commit的對應範圍。 從表中的Q號碼開始,也可以進行GitHub原文。
副駕駛 · docs/copilot-plus-and-self-host.md · Q03
75:
76: | Model source | How access works | Who processes the prompt |
77: | --------------------------- | -------------------------------------------------------------- | --------------------------------------------------------------- |
78: | **Copilot-hosted** | Lite, Plus, or included Supporter access | Brevilabs and the enterprise model provider used for that model |
79: | **Cloud BYOK** | Your API key under BYOK | The provider and endpoint you configured |
80: | **Local BYOK** | Ollama, LM Studio, or another local OpenAI-compatible endpoint | Your local endpoint |
81: | **opencode-reported model** | Authentication managed by opencode | The provider behind that opencode model |
82: | **Claude** | Claude Code login or environment | Anthropic under your Claude account |
83: | **Codex** | Codex CLI login through `codex-acp` | OpenAI under your Codex or ChatGPT account |
84:
85: A Claude or ChatGPT subscription is not an API key. Use the Claude or Codex Agent Chat setup for those subscriptions. Use BYOK only when you have API access or an OpenAI-compatible endpoint.
86:
87: ## Understand service data routes
88:
89: The selected model is only one possible route. A feature may call another service for the part of the task you asked it to perform:
90:
91: - A **Copilot-hosted Skill** sends the search query, URL, or document needed by that Skill to Brevilabs.
92: - **Plus document processing** sends the supported document to Copilot's hosted processor.
93: - In **Agent Chat**, **Miyo document processing** runs through the local Miyo CLI, so PDF and EPUB parsing stays on this computer even when search uses a remote Miyo server.
94: - In **Quick Chat**, **Miyo document processing** uses the connected Miyo service. A configured remote Miyo server processes the document there rather than on this computer.
95: - Saved **project context** that needs web, YouTube, or binary-file conversion can use Copilot's hosted project service. The Miyo Document Processor choice does not change that project route.
96: - An agent can read a local note and include relevant text in the prompt sent to the selected model. Opening Agent Chat alone does not upload the whole vault.
97:
98: For a workflow that does not send task content to Brevilabs, use direct Markdown context, local tools or local Miyo, and a local model. Disable Copilot's cloud-backed Skills for every agent you use. Do not add web pages, YouTube links, or binary files as saved project context when their hosted conversion is outside your intended boundary.
99:
100: The [privacy policy](https://www.obsidiancopilot.com/en/privacy) describes how Copilot's hosted requests are processed. Your model provider and Miyo server have their own boundaries and terms.副駕駛 · docs/copilot-plus-and-self-host.md · Q04
103:
104: Supporter and eligible legacy licenses can open **Settings → Copilot → Self-Host** and enable **Self-Host Mode**.
105:
106: When it is on, Copilot:
107:
108: - Lets you supply Firecrawl, Perplexity, Parallel, or Exa credentials for web search.
109: - With OpenCode selected, routes Agent Chat web searches through that selected provider while keeping its API key inside Obsidian. This does not require Obsidian's command line interface.
110: - Disables OpenCode's native web-search and web-fetch tools so they cannot bypass the selected route. Full-page fetching through OpenCode is unavailable until the self-host providers share a supported fetch interface.
111: - Lets you supply a Supadata key for YouTube transcripts.
112: - Directs you to BYOK for local or self-hosted model endpoints.
113: - Flags and sorts cloud agents and models below local or self-hosted choices.
114:
115: It does not disable the cloud. Claude, Codex, Copilot-hosted models, cloud BYOK providers, Firecrawl, Perplexity, Parallel, Exa, and Supadata can still send data to their services when you select them. The warnings make those routes visible so you can decide.
116:
117: You do not need Self-Host Mode to use a local BYOK model or local Miyo. Those are available independently.副駕駛 · src/services/keychainService.ts · Q09
239: /** Whether the OS keychain is available in this Obsidian version. */
240: // DESIGN NOTE — intentionally only checks for the `secretStorage` object,
241: // not individual methods (`getSecret`/`setSecret`/`listSecrets`). Obsidian
242: // ships SecretStorage as a single API surface (1.11.4); there is no
243: // released version where the object exists but methods are missing.
244: // Capability-probing each method would add branching for a partial-API
245: // world that does not exist. If a future review flags this again, point
246: // them at this note.
247: isAvailable(): boolean {
248: return !!this.app.secretStorage;
249: }
250:
251: /** Get the current vault namespace ID. */
252: getVaultId(): string {
253: return this.vaultId;
254: }
255:
256: /**
257: * Set the vault namespace ID from persisted settings.
258: * Reason: called during load to replace the path-derived fallback with the
259: * stable persisted ID, so vault renames don't orphan keychain entries.
260: */
261: setVaultId(id: string): void {
262: this.vaultId = id;
263: }
264:
265: /**
266: * Access SecretStorage with a runtime guard.
267: * Reason: replaces scattered non-null assertions with a single guard
268: * that produces a clear error when keychain is unavailable.
269: */
270: private get storage(): SecretStorage {
271: if (!this.app.secretStorage) {
272: throw new Error("OS keychain (SecretStorage) is not available.");
273: }
274: return this.app.secretStorage;智慧連線 · src/main.js · Q13
144: async check_for_updates() {
145: if (await this.is_new_plugin_version(this.manifest.version)) {
146: // console.log("opening release notes modal");
147: try {
148: this.ReleaseNotesView.open(this.app.workspace, this.manifest.version);
149: } catch (error) {
150: console.error('Failed to open ReleaseNotesView', error);
151: }
152: await this.set_last_known_version(this.manifest.version);
153: }
154: window.setTimeout(this.check_for_update.bind(this), 3000);
155: }
156:
157: async check_for_update() {
158: try {
159: const { json: response } = await requestUrl({
160: url: "https://api.github.com/repos/brianpetro/obsidian-smart-connections/releases/latest",
161: method: "GET",
162: headers: {
163: "Content-Type": "application/json",
164: },
165: contentType: "application/json",
166: });
167: const latest_release = response.tag_name;
168: if (latest_release !== this.manifest.version) {
169: if (!this.update_available || this.latest_release_version !== latest_release) {文字生成器 · src/default-settings.ts · Q15
4: const DEFAULT_SETTINGS: TextGeneratorSettings = {
5: version: pkg.version as any,
6: endpoint: "https://api.openai.com/v1",
7: models: [],
8: api_key: "",
9: encrypt_keys: false,
10: selectedProvider: "OpenAI Chat (Langchain)",
11: max_tokens: 5000,
12: temperature: 0.7,
13: frequency_penalty: 0.5,
14: showStatusBar: true,
15: outputToBlockQuote: false,
16: freeCursorOnStreaming: false,
17: allowJavascriptRun: false,
18: experiment: false,
19: promptsPath: "textgenerator/templates",
20: textGenPath: "textgenerator/",
21: prefix: "\n\n",
22: tgSelectionLimiter: "^\\*\\*\\*",
23: stream: true,
24: context: {
25: customInstructEnabled: true,
26: includeClipboard: true,
27: customInstruct: `Title: {{title}}
28:
29: Starred Blocks: {{starredBlocks}}
30:
31: {{tg_selection}}`,
32:
33: contextTemplate: `Title: {{title}}
34:
35: Starred Blocks: {{starredBlocks}}
36:
37: {{tg_selection}}`,
38: },
39: requestTimeout: 300000,
40: options: {文字生成器 · src/scope/context-manager.ts · Q17
355: {},
356: this.getFrontmatter(this.getMetaData(templatePath)),
357: contextObj.frontmatter
358: );
359:
360: if (contextOptions.includeClipboard)
361: try {
362: blocks["clipboard"] = await this.getClipboard();
363: } catch {
364: // empty
365: }
366:
367: const options = {
368: selection,
369: selections,
370: ...blocks["frontmatter"],
371: ...blocks["headings"],
372: content: ctnt,
373: context,
374: ...blocks,文字生成器 · src/main.ts · Q20
664: encryptAllKeys() {
665: // check if user have LLMProviderOptionsKeysHashed object (upgrading from older version)
666: this.settings.LLMProviderOptionsKeysHashed ??= {};
667:
668: const keyList: string[] = [];
669:
670: this.settings.api_key_encrypted = this.getEncryptedKey(
671: this.settings.api_key
672: );
673:
674: // get all secret keys
675: Object.entries(this.settings?.LLMProviderOptions).forEach(([key1, l1]) => {
676: if (typeof l1 != "object") return;
677: Object.entries(l1).forEach(([key2, l2]) => {
678: if (key2.toLowerCase().includes("key") && typeof l2 == "string") {
679: keyList.push(`${key1}.${key2}`);
680: }
681: });
682: });
683:
684: keyList.forEach((pth) => {
685: const keyval =
686: (get(this.settings?.LLMProviderOptions, pth) as never as string) || "";
687:
688: const encrypted = this.getEncryptedKey(keyval);
689: this.settings.LLMProviderOptionsKeysHashed[pth] = encrypted;
690: });
691: }
692:
693: removeApikeys(settings: typeof this.settings): typeof this.settings {
694: const LLMProviderOptions = JSON.parse(
695: JSON.stringify(settings?.LLMProviderOptions)
696: ) as typeof this.settings.LLMProviderOptions;
697:
698: // get all secret keys
699: Object.entries(LLMProviderOptions).forEach(([key1, l1]) => {
700: if (typeof l1 != "object") return;
701: Object.entries(l1).forEach(([key2, l2]) => {
702: if (key2.toLowerCase().includes("key") && typeof l2 == "string") {
703: set(LLMProviderOptions, `${key1}.${key2}`, "");
704: }
705: });
706: });
707:
708: return {
709: ...settings,
710: api_key: "",
711: LLMProviderOptions,
712: };文字生成器 · src/main.ts · Q21
742: getEncryptedKey(apiKey: string) {
743: if (!safeStorage?.isEncryptionAvailable() || !this.settings.encrypt_keys) {
744: return `${DecryptKeyPrefix}${apiKey}`;
745: }
746:
747: return safeStorage.encryptString(apiKey) as Buffer;
748: }
749: 文字生成器 · src/constants.ts · Q22
35: custom_header: true,
36: };
37:
38: export const DecryptKeyPrefix = "__@#key_prefix#@__";
39: 透過這個比較沒有確認的事情
外掛的安裝、啟用、設定GUI、生成、對模型/API的呼叫、實鍵、傳送packet、依賴整體的network audit、provider backend的保留、學習、刪除方針的遵守沒有確認。 SimpleMemo的輸入、配送、AI標籤、同步、不同終端的行為、速度、生產力、流入、AI引用的效果也不適用。
寫作是SimpleMemo Developer。 在YURIKA, K.K.運營的本網站的資料比較中,不是Obsidian官方的認證和各外掛的privacy認證。