-
gooliya.papa - 13 Apr, 2026
用 Vibe Coding 打造台灣國定假日 API,沒有寫任何一行程式碼
這是什麼? Taiwan Holidays API 是一個台灣國定假日的 JSON API 服務,提供:完整日曆資料(每日上班 / 放假狀態) 國定假日清單(中英雙語) 補班日查詢 農民曆支援(農曆日期、傳統節慶、二十四節氣) 透過 jsDelivr CDN 免費存取,支援 2017 ~ 2026 年聽起來很正常,對吧? 但這整個專案,我沒有寫任何一行程式碼。什麼是 Vibe Coding? Vibe Coding 是一種新的開發方式:你只負責描述「你想要什麼」,AI 幫你把程式碼寫出來。你不需要懂每一行在做什麼,只需要知道你想要的結果,然後不斷對話、調整、驗證。 這個詞由 Andrej Karpathy 提出,概念很簡單:程式碼是 AI 的事,你只需要有想法。怎麼做出來的? 整個過程大概是這樣:告訴 AI「我想要一個台灣假日的 JSON API,資料來自政府開放資料」 AI 生成資料解析腳本、目錄結構、資料格式設計 繼續描述需求:「我要農民曆」、「我要中英雙語」、「我要補班日」 AI 補上 GitHub Actions,讓資料自動定期更新 設定 jsDelivr CDN,讓任何人都能免費呼叫API 長這樣 所有資料都可以直接透過 CDN 取得,以 2026 年為例: # 完整日曆 https://cdn.jsdelivr.net/gh/imsyuan/taiwan-holidays/data/2026.json# 國定假日 https://cdn.jsdelivr.net/gh/imsyuan/taiwan-holidays/data/2026/holidays.json# 補班日 https://cdn.jsdelivr.net/gh/imsyuan/taiwan-holidays/data/2026/makeup-workdays.json回傳格式長這樣: { "date": "20260101", "week": "三", "isHoliday": true, "description": "開國紀念日", "lunar": { "date": "十二月初二", "festivals": [], "solarTerm": null } }簡單、乾淨,可以直接接進任何系統。用 JavaScript 呼叫 const holidays = await fetch( 'https://cdn.jsdelivr.net/gh/imsyuan/taiwan-holidays/data/2026/holidays.json' ).then(r => r.json());console.log(holidays); // [{ date: "20260101", week: "三", isHoliday: true, description: "開國紀念日" }, ...]心得 Vibe Coding 不是偷懶,是一種新的生產力。 工程師的核心價值從來不是「會打程式碼」,而是能解決問題、能設計系統、能判斷品質。 AI 幫我打字,但架構是我設計的、需求是我定義的、品質是我驗收的。 這個專案從想法到上線,只花了幾個小時,換以前可能要花幾天。 省下來的時間,可以多陪小孩一點。原始碼開放在 GitHub:imsyuan/taiwan-holidays
-
gooliya.papa - 22 Dec, 2025
如何使用 N8N 搭配 Google Drive + RAG 建立屬於企業自己的 Line 客服 AI 機器人
最近看了許多文章、影片,都在探討 RAG 的應用,所以研究了一下 N8N 如何建立自己的 RAG 系統, 並且結合 Line 來打造一個客服 AI 機器人,這篇文章就來分享一下整個流程和步驟。 由於 AI 領域的更新,可能是以天或者甚至以小時為單位在變化,參考了很多影片後,會發現不一定時做得出來你想要的需求 總共會使用到的服務有 N8N、Line OA、Gemini AI、Pinecone、Google Drive,這些服務大部分都有免費額度可以使用 建立 Line 帳號 首先進入到 Line OA 管理後台,建立自己一個新的官方帳號 Line OA 管理取得 Channel Access Token 和 Webhook 以及點擊下方的 LINE Developers Console 可以找到 Channel Secret 這 3 個資訊在後續 N8N 的設定中會用到。RAG 介紹RAG (Retrieval-Augmented Generation) 是一種結合檢索和生成的技術,主要用於提升自然語言處理模型的性能。 在大語言模型中經常會出現「幻覺」(Hallucination) 的問題,RAG 透過引入外部知識庫來減少這種現象。 主要分成三個部分:檢索 (Retrieval):從外部知識庫中檢索相關資訊,這些資訊可以是文件、文章、數據等。 增強 (Augmentation):將檢索到的資訊與輸入的查詢結合起來,形成一個更豐富的上下文。 生成 (Generation):使用自然語言生成模型來產生回答。RAG 與 生成式 AI (Generative AI) 的主要區別於 RAG 透過資料庫中的資訊來輔助回答問題, 而生成式 AI (例如 GPT 等)則主要依賴於模型本身的訓練數據來產生內容,但不一定保證內容正確性 N8N 設定 這次總共會使用到兩個 Flow,一個是用來建立 RAG 的流程,另外一個是用來處理 Line 的訊息, RAG Flow 將資料切片放入 Pinecone主要是將資料放於 Google Drive 透過 N8N 裡面的 Google drive 節點來讀取檔案內容,接下來就要使用 Pinecone 來建立向量資料庫申請 Pinecone 帳號 建立一個 Index,選擇一個 model 作為向量模型根據圖中拉取 Search files and folders 節點來讀取 Google Drive 的檔案 Download file 節點來下載檔案內容 Pinecone Vector Store 節點來將檔案內容上傳至 Pinecone 向量資料庫 建立 Pinecone Credential,輸入 API Key 和 Environment Pinecone Index 選擇剛剛在 Pinecone 建立的 IndexEmbedding Model 選擇 Google Gemini EmbeddingsData Loader下方要加上一個 Recursive Character Text Splitter 這邊就是要選擇要切割的方式,可以根據文件的特性來選擇適合的切割器,以及大小執行後就會將 Google Drive 裡面的檔案內容上傳至 Pinecone 向量資料庫整合 Line & AI & RAG FlowWebhook 節點,設定 Method 為 POST,這邊的網址就是要放在 Line OA 裡的 Messaging API Webhook URL 裡面 AI Agent 節點,設定主要的 System Prompt,這邊可以根據自己的需求來設定AI Agent 下方的 Chat model 我是選用 OpenRouter Chat Model 中的 Gemini-2.0-flash-001 AI Agent 的 Tools 下要新增一個 Pinecone Vector Store,這邊要設定剛剛建立的 Pinecone Credential 以及 Index下方的 Embedding Model 也是選用 Google Gemini Embeddings 最後一個節點是 Line 節點,這邊要設定剛剛取得的 Channel Access Token 和 Channel Secret URL : https://api.line.me/v2/bot/message/reply Method : POST Generic Auth Type : Bearer Token Send Body Body Content Type : JSON Body Parameters : replyToken :{ "replyToken":"{{ $('Webhook').item.json.body.events[0].replyToken }}", "messages":[ { "type":"text", "text": {{ JSON.stringify($json.output) }} } ] }
-
gooliya.papa - 18 Jun, 2025
如何在 Hugo 中安裝 Disqus 系統,以 PaperMod 主題為例
這邊記錄一下如何在 Hugo 中安裝 Disqus 評論系統,佈景主題為 PaperMod。 安裝步驟在 Disqus 註冊帳號並創建一個新的網站。在 Disqus 的網站設定中,找到 Shortname,這是用來識別你的網站的。在你的 Hugo 網站的 config.toml 或 config.yaml 中添加以下配置: [params] disqusShortname = "your_disqus_shortname" comments = true或者如果你使用的是 YAML 格式: params: disqusShortname: your_disqus_shortname comments: true確保你的 Hugo 佈景主題支持 Disqus。PaperMod 佈景主題已經內建支持 Disqus,所以只需要確保上述配置正確即可。複製 themes/PaperMod/layouts/partials/comments.html 到 layouts/partials/comments.html 確認 Disqus 的代碼已經包含在內。 如果沒有,你可以手動添加以下代碼到你的 layouts/partials/comments.html: {{- /* Comments area start */ -}} <div class="disqus markdown"> {{ partial "disqus.html" . }} </div> {{- /* Comments area end */ -}}建立 layouts/partials/disqus.html 檔案,並添加以下內容: {{ if .Site.Params.disqusShortname }} <div id="disqus_thread"></div> <script> var disqus_config = function () { this.page.url = '{{ .Permalink }}'; // Replace PAGE_URL with your page's canonical URL variable this.page.identifier = '{{ .File.Path }}'; // Replace PAGE_IDENTIFIER with your page's unique identifier variable }; (function() { // DON'T EDIT BELOW THIS LINE var d = document, s = d.createElement('script'); s.src = 'https://{{ .Site.Params.disqusShortname }}.disqus.com/embed.js'; s.setAttribute('data-timestamp', +new Date()); (d.head || d.body).appendChild(s); })(); </script> <noscript>Please enable JavaScript to view the <a href="https://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript> {{ end }}在 local 確認是否有完成
-
gooliya.papa - 17 Jun, 2025
如何在 FilamentPHP 中使用 Spatie Setting 插件
在 Filamentphp 開發過程中,使用 Spatie Setting 插件,一開始一直卡關,所以寫這篇文章記錄一下。 安裝 Spatie Setting 插件 插件 filament-spatie-settings 安裝 spatie-laravel-settings-plugin composer require filament/spatie-laravel-settings-plugin:"^3.2" -W安裝相關 migration 和 class 用 spatie/laravel-settings 這個套件,所以需要根據 installation 來安裝相關 migration 和 class安裝 migrationphp artisan vendor:publish --provider="Spatie\LaravelSettings\LaravelSettingsServiceProvider" --tag="migrations" php artisan migrate你會取得 migration 如下,並且執行 migrate use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema;return new class extends Migration { public function up() { Schema::create('settings', function (Blueprint $table): void { $table->id(); $table->string('group'); $table->string('name'); $table->boolean('locked')->default(false); $table->json('payload'); $table->timestamps(); $table->unique(['group', 'name']); }); } };安裝 classpublish setting 的 class,位置 app/Settings php artisan vendor:publish --provider="Spatie\LaravelSettings\LaravelSettingsServiceProvider" --tag="config"製作 setting class# php artisan make:setting SettingName --group=groupName php artisan make:filament-settings-page ManageGeneras GeneralSettings這樣就會在 app/Settings 目錄下產生一個 GeneralSettings.php 的檔案。 use Spatie\LaravelSettings\Settings;class GeneralSettings extends Settings { public string $site_name; public bool $site_active; public static function group(): string { return 'general'; } }新增你的 setting class 到你的 /config/settings.php /* * Each settings class used in your application must be registered, you can * add them (manually) here. */ 'settings' => [ GeneralSettings::class ],產生需要的 properties php artisan make:settings-migration CreateGeneralSettings這樣會在 database/database/settings 目錄下產生一個 ...create_general_settings.php 的檔案。 use Spatie\LaravelSettings\Migrations\SettingsMigration;return new class extends SettingsMigration { public function up(): void { $this->migrator->add('general.site_name', 'Spatie'); $this->migrator->add('general.site_active', true); } }php artisan migrate這樣就完成 spatie/laravel-settings 基礎設定 準備 filament setting Resource php artisan make:filament-settings-page ManageGeneras GeneralSettings 這樣會在 app/Filament/Pages 下產生一個 ManageGenerals.php,確認 $settings 是不是剛剛的 Setting class protected static string $settings = GeneralSettings::class;輸入在自己的 Resource 裡面,然後在 form() 方法裡面新增欄位。 use Filament\Forms\Components\Repeater; use Filament\Forms\Components\TextInput; use Filament\Forms\Form;public function form(Form $form): Form { return $form ->schema([ TextInput::make('copyright') ->label('Copyright notice') ->required(), Repeater::make('links') ->schema([ TextInput::make('label')->required(), TextInput::make('url') ->url() ->required(), ]), ]); }結果如下
-
gooliya.papa - 21 May, 2025
Google 重磅推出 Jules AI 對決 OpenAI 的 Codex
Google 在 2025 年 5 月 21 日宣布推出其最新的 AI 編程助手 Jules,旨在與 OpenAI 的 Codex 競爭。Jules 是一個強大的 AI 編程助手,專為開發者設計,能夠理解自然語言指令並生成高質量的程式碼。 以下就來試試看,如何透過 Jules 來幫我的一個 Filament 專案,加上我想要的功能。 我已經安裝 spatie-laravel-settings-plugin Plugin,我想讓 EmployeeResource.php 這個檔案裡面的其中一個欄位,能夠透過設定檔來控制。 開啟 Jules 並且連結 Github開啟 Google Jules選擇 Repo根據我的 prompt 生成我需要的程式碼 feat: assign config value $hr_base_salary to Employee resource's base_salary過程中會出現一些 error,Jules 嘗試自動修復環境問題。最後成功生成了我需要的程式碼,並且詢問要不要開新分支在我的 Github Repo 中可以看到 Jules 自動生成的分支總結 整體來說算是一個不錯的體驗,Jules 能夠快速理解我的需求並生成相應的程式碼。雖然在過程中遇到了一些錯誤,但它能夠自動修復並繼續進行。這對於開發者來說是一個很大的幫助,特別是在處理複雜的專案時。 我相信一個好的且明確的 prompt 可能會影響到 AI 執行的結果。這或許是我們需要多加學習如何當一個好的 prompt engineer。