Files
LLM-Wiki-for-n8n/workflows/LLM_wiki.json
T
Leo 3f2db62850 Initial commit: n8n 版 LLM Wiki
Karpathy 的 LLM Wiki 觀念,用 n8n + Google Docs + Google Sheets 實作。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 18:21:44 +08:00

614 lines
20 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"name": "LLM_wiki",
"nodes": [
{
"parameters": {
"formTitle": "上傳文件",
"formDescription": "上傳你的知識文件",
"formFields": {
"values": [
{
"fieldLabel": "文件",
"fieldType": "file",
"fieldName": "doc",
"acceptFileTypes": ".md, .txt"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.formTrigger",
"typeVersion": 2.5,
"position": [
0,
112
],
"id": "57e78e69-c698-4fbe-963a-1e43d3e1dc81",
"name": "On form submission",
"webhookId": "75dd9d9f-182b-44a7-8295-ef33d55aa4d2"
},
{
"parameters": {
"promptType": "define",
"text": "=以下是用戶上傳的文件內容,請整理後寫入 Wiki\n{{ $json.doc }}",
"options": {
"systemMessage": "你是 Wiki 知識寫入助手。\n你的唯一任務是將收到的文件內容整理後,完整寫入 Wiki 知識庫。\n\n## 工具說明\n\n- get_indexs:讀取 index sheet,回傳所有條目的 topic、doc_id、keywords、summary\n- create_wiki_page:新建 Wiki Doc,輸入 topic 名稱,回傳 doc_id\n- write_wiki:在 Wiki Doc 末尾 Append 新內容,輸入 doc_id + content\n- write_index:在 index sheet 新增一行,用於全新條目,輸入 topic、doc_id、keywords、summary\n- update_wiki:更新 index sheet 既有條目的 keywords 和 summary,輸入 topic + 新值\n\n## 執行流程\n\n### 第一步:讀取 index(必須)\n呼叫 get_indexs,取得所有現有條目。\n在做任何其他動作之前,必須先完成這一步。\n\n### 第二步:分析文件\n將文件內容拆解為一個或多個主題。\n每個主題獨立處理。\n\n### 第三步:對每個主題執行以下判斷\n\n**如果主題已存在於 index**\n1. 呼叫 write_wiki(帶入既有 doc_id),將新知識 Append 到文件末尾\n2. 呼叫 update_wiki,更新該條目的 keywords 和 summary\n→ update_wiki 是這個分支的最後一步,未呼叫代表此主題尚未完成\n\n**如果主題不存在於 index**\n1. 呼叫 create_wiki_page(輸入 topic),取得新 doc_id\n2. 呼叫 write_wiki(帶入新 doc_id),寫入初始內容\n3. 呼叫 write_index,將新條目寫入 index sheet\n→ write_index 是這個分支的最後一步,未呼叫代表此主題尚未完成\n\n### 第四步:確認收尾(必須)\n在回報任何結果給用戶之前,檢查每個主題是否都已完成最後一步:\n- 既有主題:update_wiki 已呼叫 ✓\n- 新主題:write_index 已呼叫 ✓\n\n如果有任何主題還沒完成最後一步,必須先補完,才能回報結果。\n\n### 第五步:回報結果\n格式如下:\n\n✅ 已更新的主題:[topic 名稱]doc_id: xxx\n🆕 已新建的頁面:[topic 名稱]doc_id: xxx\n\n## 寫入格式規範\n\n- 語言:繁體中文\n- 結構:條列核心概念,每點一行\n- 末尾固定附上:來源:上傳文件|日期:{{$now}}\n- 模式:Append,絕對不刪除或覆蓋舊內容\n\n## 鐵律\n\n- 沒有呼叫 get_indexs 之前,不得執行任何其他工具\n- 沒有更新 index 之前,不得回報任務完成\n- write_wiki 永遠不是最後一步\n你必須透過工具呼叫(function call)執行所有操作。\n絕對不可以用文字描述「我將要呼叫 XXX」或「Calling XXX with input」。\n描述行動不等於執行行動。只有實際呼叫工具才算完成任務。"
}
},
"type": "@n8n/n8n-nodes-langchain.agent",
"typeVersion": 3.1,
"position": [
704,
0
],
"id": "1a52474b-dc56-409f-b9f5-76655dd842f5",
"name": "AI Agent"
},
{
"parameters": {
"operation": "text",
"binaryPropertyName": "doc",
"destinationKey": "doc",
"options": {}
},
"type": "n8n-nodes-base.extractFromFile",
"typeVersion": 1.1,
"position": [
224,
112
],
"id": "b35641d7-1830-4951-9007-f1d5870fc223",
"name": "Extract from File"
},
{
"parameters": {
"descriptionType": "manual",
"toolDescription": "讀取 Wiki index sheet,取得所有現有條目。\n\n回傳每筆條目的:topic、doc_id、keywords、summary、last_updated\n\n這是每次流程的第一步,必須先呼叫才能判斷主題是否已存在。",
"authentication": "serviceAccount",
"documentId": {
"__rl": true,
"value": "1Zgs3o1sJxzWdpN_JbDHCcPECXvrxlj7QnYZKcu5u0ho",
"mode": "list",
"cachedResultName": "index",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1Zgs3o1sJxzWdpN_JbDHCcPECXvrxlj7QnYZKcu5u0ho/edit?usp=drivesdk"
},
"sheetName": {
"__rl": true,
"value": "gid=0",
"mode": "list",
"cachedResultName": "工作表1",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1Zgs3o1sJxzWdpN_JbDHCcPECXvrxlj7QnYZKcu5u0ho/edit#gid=0"
},
"options": {}
},
"type": "n8n-nodes-base.googleSheetsTool",
"typeVersion": 4.7,
"position": [
576,
224
],
"id": "71b93dc0-d918-42dd-88ca-30a75b807130",
"name": "get_indexs",
"credentials": {
"googleApi": {
"id": "jiemOwKMFTLhtSli",
"name": "Service_Account_Richblack"
}
}
},
{
"parameters": {
"toolDescription": "=建立一個新的 Google Docs Wiki 頁面。\n\n輸入:\n- doc_title:頁面標題(主題名稱)\n\n回傳:\n- doc_id:新建頁面的 Google Doc ID(後續 write_wiki 和 write_index 都需要這個值)\n\n注意:建立後必須繼續呼叫 write_wiki 寫入內容,再呼叫 write_index 更新索引,任務才算完成。",
"method": "POST",
"url": "https://YOUR-N8N-HOST/webhook/YOUR-CREATE-WIKI-PAGE-WEBHOOK-ID",
"sendBody": true,
"bodyParameters": {
"parameters": [
{
"name": "doc_title",
"value": "={{ $fromAI('doc_title') }}"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.httpRequestTool",
"typeVersion": 4.4,
"position": [
704,
224
],
"id": "8e9efcaa-e434-444a-98bc-347fc0c9b989",
"name": "create_wiki_page"
},
{
"parameters": {
"modelName": "models/gemini-flash-latest",
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"typeVersion": 1.1,
"position": [
448,
224
],
"id": "7cb78f89-1c14-435d-90aa-1f2dcb3bd07d",
"name": "Gemini",
"credentials": {
"googlePalmApi": {
"id": "kT9HBbdgSzqMyxem",
"name": "Google Gemini Leo 自家用"
}
}
},
{
"parameters": {
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.chatTrigger",
"typeVersion": 1.4,
"position": [
240,
464
],
"id": "d437ecd9-f215-4e9e-850b-9f041ef9168e",
"name": "When chat message received",
"webhookId": "2215100f-da5f-4c4d-a25c-c5e480d8c54c"
},
{
"parameters": {
"descriptionType": "manual",
"toolDescription": "讀取指定 Wiki Google Doc 的完整內容。\n\n輸入:\n- doc_id:目標 Google Doc 的 ID(從 get_indexs 取得)\n\n回傳:該頁面的全文內容,用於回答用戶問題。",
"operation": "get",
"documentURL": "={{ $fromAI('doc_id') }}"
},
"type": "n8n-nodes-base.googleDocsTool",
"typeVersion": 2,
"position": [
720,
688
],
"id": "bc9be3ed-9db6-4efa-b517-ea06c56b0c8d",
"name": "read_wiki",
"credentials": {
"googleDocsOAuth2Api": {
"id": "pgd50DD52VYwX6IC",
"name": "Leo_personal_n8n_test"
}
}
},
{
"parameters": {
"options": {
"systemMessage": "你是 Wiki 知識查詢助手。\n你的任務是根據用戶的問題,從 Wiki 知識庫找到答案後回答。\n\n工具說明:\n- get_indexs:讀取 index sheet,回傳所有條目的 topic、doc_id、keywords、summary\n- read_wiki:讀取指定 Wiki Doc 的內容,輸入 doc_id,回傳全文\n\n執行順序:\n1. 呼叫 get_indexs,瀏覽所有條目的 keywords 和 summary\n2. 判斷哪個(或哪幾個)doc_id 與問題最相關\n3. 呼叫 read_wiki(帶入 doc_id)讀取內容\n4. 根據讀到的內容回答用戶\n\n注意:\n- 只讀不寫,不要修改任何 Wiki 內容\n- 如果 index 裡找不到相關主題,直接告知用戶「Wiki 尚未收錄此主題」\n- 回答要根據 Wiki 內容,不要自己發明答案"
}
},
"type": "@n8n/n8n-nodes-langchain.agent",
"typeVersion": 3.1,
"position": [
592,
464
],
"id": "2b77a40c-e0b7-477f-aac1-50d80fe4deec",
"name": "AI Agent1"
},
{
"parameters": {
"modelName": "models/gemma-4-31b-it",
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"typeVersion": 1.1,
"position": [
464,
688
],
"id": "e32a353a-adb9-4821-8308-784af0c93129",
"name": "Gemini1",
"credentials": {
"googlePalmApi": {
"id": "kT9HBbdgSzqMyxem",
"name": "Google Gemini Leo 自家用"
}
}
},
{
"parameters": {
"descriptionType": "manual",
"toolDescription": "在 index sheet 新增或更新一筆條目。這是每次寫入流程的最後一步,沒有呼叫這個工具代表任務尚未完成。\n\n輸入:\n- topic:主題名稱\n- doc_id:對應的 Google Doc ID(從 create_wiki_page 取得,或從 get_indexs 讀出)\n- keywords:逗號分隔的關鍵詞列表\n- summary:這篇 Wiki 目前涵蓋內容的一句話摘要\n- last_updated:今天日期,格式 YYYY-MM-DD\n\n行為:doc_id 已存在則更新該行,不存在則新增一行。",
"authentication": "serviceAccount",
"operation": "appendOrUpdate",
"documentId": {
"__rl": true,
"value": "1Zgs3o1sJxzWdpN_JbDHCcPECXvrxlj7QnYZKcu5u0ho",
"mode": "list",
"cachedResultName": "index",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1Zgs3o1sJxzWdpN_JbDHCcPECXvrxlj7QnYZKcu5u0ho/edit?usp=drivesdk"
},
"sheetName": {
"__rl": true,
"value": "gid=0",
"mode": "list",
"cachedResultName": "工作表1",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1Zgs3o1sJxzWdpN_JbDHCcPECXvrxlj7QnYZKcu5u0ho/edit#gid=0"
},
"columns": {
"mappingMode": "defineBelow",
"value": {
"doc_id": "={{ $fromAI('doc_id') }}",
"topic": "={{ $fromAI('topic') }}",
"keywords": "={{ $fromAI('keywords') }}",
"summary": "={{ $fromAI('summary') }}",
"last_updated": "={{ $fromAI('last_updated') }}"
},
"matchingColumns": [
"doc_id"
],
"schema": [
{
"id": "topic",
"displayName": "topic",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "doc_id",
"displayName": "doc_id",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true,
"removed": false
},
{
"id": "keywords",
"displayName": "keywords",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "summary",
"displayName": "summary",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
},
{
"id": "last_updated",
"displayName": "last_updated",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"canBeUsedToMatch": true
}
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {}
},
"type": "n8n-nodes-base.googleSheetsTool",
"typeVersion": 4.7,
"position": [
832,
224
],
"id": "6091001d-c6e3-478d-bdbd-6ab4afededc2",
"name": "write_index",
"credentials": {
"googleApi": {
"id": "jiemOwKMFTLhtSli",
"name": "Service_Account_Richblack"
}
}
},
{
"parameters": {
"descriptionType": "manual",
"toolDescription": "讀取指定 Wiki Google Doc 的完整內容。\n\n輸入:\n- doc_id:目標 Google Doc 的 ID(從 get_indexs 取得)\n\n回傳:該頁面的全文內容,用於回答用戶問題。",
"authentication": "serviceAccount",
"documentId": {
"__rl": true,
"value": "1Zgs3o1sJxzWdpN_JbDHCcPECXvrxlj7QnYZKcu5u0ho",
"mode": "list",
"cachedResultName": "index",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1Zgs3o1sJxzWdpN_JbDHCcPECXvrxlj7QnYZKcu5u0ho/edit?usp=drivesdk"
},
"sheetName": {
"__rl": true,
"value": "gid=0",
"mode": "list",
"cachedResultName": "工作表1",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1Zgs3o1sJxzWdpN_JbDHCcPECXvrxlj7QnYZKcu5u0ho/edit#gid=0"
},
"options": {}
},
"type": "n8n-nodes-base.googleSheetsTool",
"typeVersion": 4.7,
"position": [
848,
688
],
"id": "d9edd457-07a4-46d6-810b-c1c988ac9525",
"name": "get_indexs1",
"credentials": {
"googleApi": {
"id": "jiemOwKMFTLhtSli",
"name": "Service_Account_Richblack"
}
}
},
{
"parameters": {},
"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
"typeVersion": 1.4,
"position": [
592,
688
],
"id": "48c22e61-9260-4c77-b782-cf3cd049e371",
"name": "Simple Memory"
},
{
"parameters": {
"descriptionType": "manual",
"toolDescription": "取代指定 Wiki Google Doc 中的特定文字段落。用於修改或更正既有頁面中的內容。\n\n輸入:\n- doc_id:目標 Google Doc 的 ID\n- old_text:要被取代的原始文字\n- new_text:取代後的新文字\n\n注意:呼叫完畢後必須繼續呼叫 write_index 更新索引中的 keywords 和 summary。",
"operation": "update",
"documentURL": "={{ $fromAI('doc_id') }}",
"actionsUi": {
"actionFields": [
{
"action": "replaceAll",
"text": "={{ $fromAI('old_text') }}",
"replaceText": "={{ $fromAI('new_text') }}"
}
]
}
},
"type": "n8n-nodes-base.googleDocsTool",
"typeVersion": 2,
"position": [
960,
224
],
"id": "811d333c-2d32-4238-a03a-bf35e2d7bd82",
"name": "update_wiki",
"credentials": {
"googleDocsOAuth2Api": {
"id": "pgd50DD52VYwX6IC",
"name": "Leo_personal_n8n_test"
}
}
},
{
"parameters": {
"descriptionType": "manual",
"toolDescription": "將新內容 Append(插入)到指定的 Wiki Google Doc 末尾。用於寫入全新頁面的初始內容,或在既有頁面末尾新增知識。\n\n輸入:\n- doc_id:目標 Google Doc 的 ID\n- text:要寫入的內容\n\n注意:這是新增內容,不會刪除原有內容。呼叫完畢後必須繼續呼叫 write_index 更新索引。",
"operation": "update",
"documentURL": "={{ $fromAI('doc_id') }}",
"actionsUi": {
"actionFields": [
{
"action": "insert",
"text": "={{ $fromAI('text') }}"
}
]
}
},
"type": "n8n-nodes-base.googleDocsTool",
"typeVersion": 2,
"position": [
1088,
224
],
"id": "64891a23-95d7-4d9f-a8ff-a0e74798737e",
"name": "write_wiki",
"credentials": {
"googleDocsOAuth2Api": {
"id": "pgd50DD52VYwX6IC",
"name": "Leo_personal_n8n_test"
}
}
},
{
"parameters": {
"content": "## 1. 資料入庫",
"height": 448,
"width": 1328,
"color": 2
},
"type": "n8n-nodes-base.stickyNote",
"position": [
-96,
-80
],
"typeVersion": 1,
"id": "e6626b8e-1717-40f1-9094-e95d3455eec8",
"name": "Sticky Note"
},
{
"parameters": {
"content": "## 2. 資料查詢",
"height": 448,
"width": 1328,
"color": 4
},
"type": "n8n-nodes-base.stickyNote",
"position": [
-96,
384
],
"typeVersion": 1,
"id": "35370a11-27e8-4b58-97db-725cf7af1319",
"name": "Sticky Note1"
}
],
"pinData": {},
"connections": {
"On form submission": {
"main": [
[
{
"node": "Extract from File",
"type": "main",
"index": 0
}
]
]
},
"Extract from File": {
"main": [
[
{
"node": "AI Agent",
"type": "main",
"index": 0
}
]
]
},
"get_indexs": {
"ai_tool": [
[
{
"node": "AI Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"create_wiki_page": {
"ai_tool": [
[
{
"node": "AI Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Gemini": {
"ai_languageModel": [
[
{
"node": "AI Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"When chat message received": {
"main": [
[
{
"node": "AI Agent1",
"type": "main",
"index": 0
}
]
]
},
"read_wiki": {
"ai_tool": [
[
{
"node": "AI Agent1",
"type": "ai_tool",
"index": 0
}
]
]
},
"Gemini1": {
"ai_languageModel": [
[
{
"node": "AI Agent1",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"write_index": {
"ai_tool": [
[
{
"node": "AI Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"get_indexs1": {
"ai_tool": [
[
{
"node": "AI Agent1",
"type": "ai_tool",
"index": 0
}
]
]
},
"Simple Memory": {
"ai_memory": [
[
{
"node": "AI Agent1",
"type": "ai_memory",
"index": 0
}
]
]
},
"update_wiki": {
"ai_tool": [
[
{
"node": "AI Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"write_wiki": {
"ai_tool": [
[
{
"node": "AI Agent",
"type": "ai_tool",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1",
"binaryMode": "separate"
},
"versionId": "e749498e-7a54-4cf8-95da-11b5a53cdd29",
"meta": {
"templateCredsSetupCompleted": true,
"instanceId": "4b0d44081b86641724941387a3a04b51a305f7e1a5c57b8feea64b401216b1f0"
},
"id": "eIbQFUBI8Q8bRRPn",
"tags": []
}