ข้ามไปยังเนื้อหาหลัก
  1. เอกสารประกอบ/

Agent Server

หัวข้อเนื้อหา

PocketHook Agent Server คืออะไร?
#

Agent server เปลี่ยน PocketHook เป็นผู้ช่วย AI เต็มรูปแบบ แทนที่จะเขียนลอจิกการตอบกลับเอง คุณเชื่อมต่อ LLM (Claude, GPT, Gemini ฯลฯ) ที่ประมวลผลข้อความ เรียกใช้เครื่องมือ และส่งคืนการตอบกลับ PocketHook แบบมีโครงสร้าง — รวมถึงตัวเรียก Shortcut

เซิร์ฟเวอร์ทำงานบนเครื่องของคุณเอง ข้อมูลของคุณอยู่กับคุณ

นี่คือจุดเริ่มต้น เซิร์ฟเวอร์มาพร้อมชุดเครื่องมือหลักและออกแบบมาให้คุณขยายเพิ่มเติม เพิ่มการเชื่อมต่อของคุณเอง — อีเมล ปฏิทิน เอกสาร API — และทำให้เป็นของคุณ

คุณสมบัติ
#

  • LLM หลายผู้ให้บริการ — Anthropic, OpenAI, GitHub Copilot, Google, Mistral, Groq, xAI, OpenRouter, Ollama (ในเครื่อง), LM Studio (ในเครื่อง)
  • การยืนยันตัวตน OAuth — GitHub Copilot และ OpenAI Codex ผ่าน device code / browser flow
  • เครื่องมือ agent — คำสั่ง shell, อ่าน/เขียนไฟล์, รายการไดเรกทอรี, ค้นหาเว็บ, web scraping, จัดการ dev server
  • การแยก framework / ผู้ใช้ — ไฟล์ framework (skills/, custom-tools/, config/) เป็นแบบอ่านอย่างเดียว การปรับแต่งของคุณอยู่ภายใต้ data/user/ (ทักษะ เครื่องมือที่กำหนดเอง คำสั่ง prefs แบบมีประเภท) การอัปเดต framework จะติดตั้งอย่างเรียบร้อยโดยไม่เขียนทับงานของคุณ
  • Prefs ผู้ใช้แบบมีประเภท — เก็บค่าเช่น แอปแผนที่ที่คุณชอบหรือโดเมน tunnel ใน data/user/prefs.json อ้างอิงในทักษะด้วย {{prefs.key}} แล้วเซิร์ฟเวอร์จะแทนค่าขณะโหลด
  • งานการเขียนโปรแกรมในคำสั่งเดียว — เครื่องมือเมตา run_code_job สร้างงานเบื้องหลังประเภท prompt (ทำงานโดย LLM ที่คุณกำหนดค่า) และส่งการตอบรับแก่ผู้ใช้ในขั้นตอนเดียว แทนที่รูปแบบ “respond + create-job” ที่มักเกิดข้อผิดพลาด
  • เครื่องมือโปรโตคอลแบบมีประเภท — เครื่องมือ respond_* เฉพาะหกรายการ (respond_text, respond_image, respond_buttons, respond_shortcut, respond_html, respond_sequence) พร้อมเครื่องมืองานแบบมีประเภท (create_once_job, create_cron_job) และเครื่องมือ workspace แบบมีประเภท (create_project, list_projects, delete_project) Schema จะปฏิเสธ URL ที่มีรูปแบบไม่ถูกต้อง ไวยากรณ์ปุ่ม และการรวม type/schedule ก่อนที่จะถึงอุปกรณ์
  • เครื่องมือเขียนแบบมีประเภทสำหรับการปรับแต่งcreate_user_skill และ create_custom_tool สร้าง markdown ชั้นผู้ใช้พร้อม frontmatter ที่ถูกต้อง ดังนั้นตัวโหลดจะวิเคราะห์ได้เสมอและ agent ไม่ต้องเขียนไฟล์เหล่านี้ด้วยมือ
  • งานเบื้องหลัง — งานครั้งเดียวหรือแบบซ้ำด้วยนิพจน์ cron หรือช่วงเวลาอย่างง่าย
  • ทักษะแบบไดนามิก — กำหนด shortcut และกฎพฤติกรรมเป็นไฟล์ .md มีเพียงดัชนีย่อที่ถูกโหลดเข้าสู่ prompt; เนื้อหาเต็มถูกดึงตามความต้องการผ่านเครื่องมือ load_skill
  • ทักษะจัดการตัวเอง — Agent สามารถสร้าง แก้ไข และลบคำจำกัดความทักษะ (การเขียนจะลงในชั้นผู้ใช้เสมอ)
  • หน่วยความจำเชิงความหมาย — การค้นหาแบบ vector ด้วย embedding (Ollama, LM Studio หรือ OpenAI) หน่วยความจำถูกจำแนกอัตโนมัติเข้าสู่มิติ wing/room/hall/status โดย LLM
  • กราฟความรู้ — ที่เก็บ triple แบบชั่วคราวสำหรับข้อเท็จจริงที่คงทนพร้อมการยกเลิกอัตโนมัติ ความสัมพันธ์หลายค่าอยู่ร่วมกัน; ข้อเท็จจริงค่าเดียวถูกแทนที่อัตโนมัติ
  • วิธี PARA พร้อม cascade สิ้นสุดโปรเจกต์ — หน่วยความจำทุกรายการถูกแท็กด้วยสถานะ (Project, Area, Resource, Archive) เมื่อโปรเจกต์สิ้นสุด การเรียก complete_project เพียงครั้งเดียวจะจัดเก็บ vector ของโปรเจกต์ ยกเลิก triple การวางแผนทุกอันที่ผูกกับ slug ของมัน และบันทึกการเสร็จสิ้น — หนึ่งครั้งแทนสามครั้ง
  • การเรียกคืนแบบผสม — รวมการค้นหาคำสำคัญ FTS5 กับการค้นหาเชิงความหมายแบบ vector โดยใช้ reciprocal rank fusion
  • หน่วยความจำระยะยาว — SQLite + การค้นหาข้อความเต็ม FTS5 เป็นทางเลือกเมื่อหน่วยความจำเชิงความหมายถูกปิด
  • การจัดการ dev server พร้อมสัญญา tunnel — เริ่ม หยุด และรายการ dev server เมื่อมีการร้องขอ tunnel: true เซิร์ฟเวอร์จะบังคับใช้ทั้งก่อนเริ่มและหลัง spawn — เซิร์ฟเวอร์ localhost ที่เข้าถึงไม่ได้จะไม่ถูกปล่อยให้ทำงานต่ออย่างเงียบ ๆ
  • การทำความสะอาด URL อัตโนมัติ — หาก agent ทิ้ง URL localhost ไว้ในคำตอบ เครื่องมือ respond_* จะเขียนใหม่เป็น URL tunnel ที่ตรงกันเพื่อให้โทรศัพท์ของคุณได้รับลิงก์ที่เข้าถึงได้เสมอ
  • เครื่องมือที่กำหนดเอง — Agent สามารถติดตั้งเครื่องมือ CLI และลงทะเบียนเป็นความสามารถใหม่
  • การจัดการเวอร์ชัน — การจัดการเวอร์ชัน git อัตโนมัติสำหรับไฟล์ workspace; สำรองข้อมูลการกำหนดค่าสำหรับทักษะและสิทธิ์
  • แดชบอร์ดเว็บ — ภาพรวมสดของงานเบื้องหลัง ปรับแต่งได้ตามผู้ใช้ /dashboard และ /api/jobs ไม่มีการยืนยันตัวตนตามการออกแบบ — จำกัดการเข้าถึงที่ระดับเครือข่าย (Tailscale ACL, ไฟร์วอลล์, reverse proxy พร้อม basic auth) หรือตั้ง DASHBOARD=false หากคุณไม่ต้องการ
  • อุโมงค์ HTTPS — รองรับ Tailscale, ngrok และ Cloudflare Tunnel ในตัว
  • บริการระบบ — ติดตั้งเป็นบริการถาวรบน macOS, Linux หรือ Windows
  • การจำกัดอัตรา — จำกัดคำขอต่อ token ด้วยเกณฑ์ที่กำหนดค่าได้

ข้อกำหนด
#

  • Runtime Bun
  • API key หรือข้อมูลรับรอง OAuth สำหรับผู้ให้บริการ LLM ของคุณ
  • (ตัวเลือก) Tailscale, ngrok หรือ cloudflared สำหรับอุโมงค์ HTTPS

เริ่มต้นอย่างรวดเร็ว
#

git clone https://github.com/pockethook-app/pockethook-agent-server.git
cd pockethook-agent-server
bun install

# การตั้งค่าแบบโต้ตอบ — เลือก provider, model, token ยืนยัน, port
bun run setup

# เริ่มเซิร์ฟเวอร์ + อุโมงค์ HTTPS
bun run dev:tunnel

วิซาร์ดการตั้งค่าจะแนะนำคุณผ่านการเลือกผู้ให้บริการ LLM, การกำหนดค่าการยืนยันตัวตน และการตั้งค่าสิทธิ์เครื่องมือ

หลังจากทำงาน ให้คัดลอก URL ที่แสดงไปยังการตั้งค่า PocketHook:

การตั้งค่า PocketHookURL
Server URLhttps://your-host
Health Check URLhttps://your-host/health
Polling URLhttps://your-host/jobs

วิธีการทำงาน
#

  1. คุณส่งข้อความใน PocketHook
  2. เซิร์ฟเวอร์ส่งต่อไปยัง LLM ที่คุณเลือกพร้อมประวัติการสนทนา หน่วยความจำที่เรียกคืน และเครื่องมือที่มี
  3. LLM ประมวลผลข้อความ — สามารถรันคำสั่ง shell อ่าน/เขียนไฟล์ ค้นหาเว็บ ตั้งเวลางานเบื้องหลัง จำข้อเท็จจริง หรือเริ่ม dev server
  4. การตอบกลับถูกส่งคืนในรูปแบบ PocketHook (msg + shortcut + data + url)
  5. PocketHook แสดงข้อความและรัน Shortcuts บนอุปกรณ์ของคุณ

ผู้ให้บริการ LLM ที่รองรับ
#

ผู้ให้บริการการยืนยันโมเดลเริ่มต้น
AnthropicAPI keyclaude-sonnet-4-20250514
OpenAIAPI keygpt-4.1-mini
OpenAI CodexOAuthgpt-5.1-codex-mini
GitHub CopilotOAuthclaude-sonnet-4
Google (Gemini)API keygemini-2.5-flash
MistralAPI keymistral-medium-latest
GroqAPI keyllama-3.3-70b-versatile
xAI (Grok)API keygrok-3-mini-fast
OpenRouterAPI keyanthropic/claude-sonnet-4
Ollama (ในเครื่อง)ไม่มีllama3.2
LM Studio (ในเครื่อง)ไม่มีqwen3.5-4b-mlx

เปลี่ยนผู้ให้บริการเมื่อไหร่ก็ได้ด้วย bun run switch Ollama และ LM Studio ทำงานบนเครื่องของคุณทั้งหมด — ไม่ต้องใช้ API key ข้อมูลไม่ออกจากเครือข่ายของคุณ

หน่วยความจำ
#

ระบบหน่วยความจำมีสามชั้น แต่ละชั้นรับใช้วัตถุประสงค์ที่แตกต่างกัน

การออกแบบหน่วยความจำเชิงความหมายรวมแนวคิดจาก MemPalace (สถาปัตยกรรมพระราชวังความจำที่จัดระเบียบหน่วยความจำเป็น wing, hall และ room) และวิธี PARA ของ Tiago Forte (Projects, Areas, Resources, Archive) สำหรับการจัดการวงจรชีวิตความรู้

หน่วยความจำการสนทนา
#

SQLite พร้อมการค้นหาข้อความเต็ม FTS5 ข้อความทั้งหมดถูกเก็บพร้อม timestamp และ ID เซสชัน

  • ระยะสั้นMAX_HISTORY ข้อความล่าสุดถูกเก็บในหน่วยความจำต่อเซสชัน
  • ระยะยาว — ข้อความทั้งหมดถูกบันทึกใน SQLite ค้นหาได้ผ่านการจับคู่คำสำคัญ FTS5
  • การเรียกคืนต่อรอบ — เมื่อหน่วยความจำเชิงความหมายเปิดอยู่ MAX_RECALL ควบคุมจำนวนหน่วยความจำที่เกี่ยวข้องที่ถูกฉีดเข้าสู่ prompt ในแต่ละรอบ
  • เซสชันหมดอายุหลัง SESSION_TTL_MINUTES แต่หน่วยความจำระยะยาวคงอยู่ตลอดไป

ปรับค่าเหล่านี้แบบโต้ตอบด้วย bun run memory

หน่วยความจำเชิงความหมาย
#

ต้องใช้ VECTOR_MEMORY=true และผู้ให้บริการ embedding (Ollama, LM Studio หรือ OpenAI)

หน่วยความจำแต่ละรายการถูกฝังเป็น vector และจำแนกอัตโนมัติโดย LLM เป็นสี่มิติ:

  • Wing — เอนทิตี: user, person:john, project:blog, place:london
  • Room — ประเภท: facts, preferences, events, decisions, requests
  • Hall — หัวข้อ: personal, tech, health, travel, food, work
  • Status — การจำแนก PARA: project, area, resource, archive

เมื่อคุณถามคำถาม การสกัดเอนทิตีจะมุ่งเน้นการค้นหา vector ไปที่ wing ที่เกี่ยวข้องมากที่สุด ผลลัพธ์ถูกรวมกับผลลัพธ์คำสำคัญ FTS5 โดยใช้ reciprocal rank fusion — เพื่อให้คุณได้สิ่งที่ดีที่สุดจากทั้งการจับคู่คำสำคัญและเชิงความหมาย

กราฟความรู้
#

ที่เก็บ triple แบบชั่วคราวสำหรับข้อเท็จจริงที่มีโครงสร้างและคงทน:

  • Triple: (subject, predicate, object) พร้อม timestamp valid_from / valid_until
  • predicate ค่าเดียว (lives_in, partner) ยกเลิกค่าเก่าอัตโนมัติเมื่ออัปเดต
  • predicate หลายค่า (child, friend, hobby) อยู่ร่วมกันโดยไม่ถูกยกเลิก
  • ข้อเท็จจริงกราฟความรู้ถูกฉีดพร้อมหน่วยความจำที่เรียกคืนในทุกการสนทนา

เมื่อคุณบอก agent ว่า “ผมย้ายไปเบอร์ลิน” มันจะยกเลิก triple lives_in เก่าและสร้างใหม่ — โดยอัตโนมัติ

วงจรชีวิต PARA
#

หน่วยความจำทุกรายการถูกแท็กด้วยสถานะ PARA:

  • Project — งานที่กำลังดำเนินการ มีกำหนดเวลา
  • Area — ความรับผิดชอบที่ต่อเนื่อง
  • Resource — เอกสารอ้างอิง (รายการ คำแนะนำ วิธีการ)
  • Archive — โปรเจกต์ที่เสร็จสิ้นหรือยกเลิก

เมื่อโปรเจกต์เสร็จสมบูรณ์ agent ใช้ความคล้ายคลึงเชิงความหมายเพื่อจัดเก็บเฉพาะหน่วยความจำของโปรเจกต์นั้นในขณะที่รักษาเอกสารอ้างอิงไว้สำหรับใช้ในอนาคต

Cascade สิ้นสุดโปรเจกต์
#

พูดว่า “ฉันกำลังยกเลิกทริปไปบาร์เซโลนา” แล้วการเรียกเครื่องมือเพียงครั้งเดียวจัดการทุกอย่าง:

  1. จัดเก็บ vector ของโปรเจกต์ (events, decisions, requests ที่ผูกกับบาร์เซโลนา)
  2. ยกเลิก triple ของกราฟความรู้ที่กำลังทำงานทุกอันที่ predicate ตรงกับ slug ของโปรเจกต์ (scheduled_visit_barcelona, planning_visit_barcelona, confirmed_visit_barcelona)
  3. บันทึกการเสร็จสิ้นเป็น triple ใหม่: (user, "cancelled_visit_barcelona", "2026-04-15")

การจับคู่คำนึงถึงขอบเขต — โปรเจกต์อื่นชื่อ revisit_barcelona ยังคงอยู่โดยไม่ถูกแตะ Agent ไม่จำเป็นต้องประสานการเรียกสามครั้งแยกกันในลำดับที่ถูกต้องอีกต่อไป ดังนั้นโมเดลขนาดเล็กก็ทำได้ถูกต้องเช่นกัน

หาก VECTOR_MEMORY ถูกปิดหรือผู้ให้บริการ embedding ไม่สามารถเข้าถึงได้ ระบบจะใช้ FTS5 เท่านั้นโดยไม่มีข้อผิดพลาด

ทักษะ
#

ทักษะคือไฟล์ .md ใน skills/ ที่กำหนด iOS Shortcuts ที่ agent สามารถเรียกใช้และ/หรือกฎพฤติกรรม ใช้ การโหลดแบบไดนามิก: มีเพียงดัชนีย่อ (ชื่อ คำอธิบาย รายการ shortcut) ที่ถูกฉีดเข้าสู่ prompt ระบบ Agent โหลดเนื้อหาเต็มตามความต้องการผ่านเครื่องมือ load_skill ทำให้การใช้ token ต่ำเมื่อคุณเพิ่มทักษะมากขึ้น

ไฟล์ทักษะแต่ละไฟล์ใช้ frontmatter YAML:

---
title: Notes
description: Create notes on the user's device with a title and body
shortcuts: [newNote]
target: mac
sync_app: Notes
---

### New Note

Shortcut name: `newNote`

Creates a new note on the user's device.

Data fields:
- title (string, required): Note title
- content (string, required): Note body

ฟิลด์ frontmatter
#

ฟิลด์จำเป็นคำอธิบาย
titleใช่ชื่อที่มนุษย์อ่านได้
descriptionใช่ประโยคเดียวที่ใช้ในดัชนีทักษะซึ่งแสดงให้ agent เห็น
shortcutsใช่อาร์เรย์ของชื่อ shortcut ที่กำหนดไว้ในไฟล์ ใช้ [] สำหรับทักษะที่มีแต่กฎพฤติกรรม
targetไม่ตำแหน่งที่ shortcut จะทำงาน: device (ค่าเริ่มต้น ส่งไปยัง iOS) หรือ mac (รันบนเซิร์ฟเวอร์)
sync_appไม่แอปที่จะกระตุ้นในเบื้องหลังหลังจากการทำงานฝั่งเซิร์ฟเวอร์เพื่อเรียกการซิงค์ iCloud (เช่น Notes, Calendar, Reminders) ละเว้นหรือใช้ none เพื่อข้าม

ทักษะยังสามารถเป็น กฎพฤติกรรม โดยไม่มี shortcut (เช่น “วิธีวางแผนทริปครอบครัว”) ใช้ shortcuts: [] สำหรับกรณีเหล่านี้

Agent สามารถสร้างและจัดการทักษะเมื่อถูกขอ — ขอให้มัน “สร้างทักษะสำหรับควบคุมไฟ” และมันจะเขียนไฟล์ .md ให้คุณ ทักษะใหม่และที่แก้ไขแล้วจะลงในชั้นผู้ใช้ (data/user/skills/) เสมอ ดังนั้นการอัปเดต framework จะไม่เขียนทับ ดูส่วน การปรับแต่ง agent ของคุณ ด้านล่าง

การรัน shortcut บนเซิร์ฟเวอร์ Mac
#

เมื่อทักษะมี target: mac shortcut จะ รันอย่างเงียบ ๆ บนเซิร์ฟเวอร์ Mac ผ่าน CLI shortcuts run แทนที่จะถูกส่งไปยังอุปกรณ์ iOS ซึ่งเหมาะอย่างยิ่งสำหรับการกระทำที่สร้างเนื้อหาที่ซิงค์กับ iCloud — โน้ต การแจ้งเตือน กิจกรรมในปฏิทิน — เนื่องจากผลลัพธ์จะซิงค์ไปยังทุกอุปกรณ์ของคุณโดยอัตโนมัติ โดยที่แอป PocketHook ไม่ต้องทำอะไรเลย

วิธีการทำงาน:

  1. Agent ตัดสินใจว่าควรรัน shortcut (เช่น “สร้างโน้ตด้วยโน้ตการประชุมของวันนี้”)
  2. เซิร์ฟเวอร์เรียกใช้ shortcuts run "shortcutName" โดยส่งข้อมูลเป็น JSON ผ่าน stdin ในรูปแบบ wrapper เดียวกับที่ PocketHook iOS ใช้
  3. หากตั้งค่า sync_app เซิร์ฟเวอร์จะเปิดแอปนั้นในเบื้องหลังชั่วครู่ (open -gj -a Notes) เพื่อบังคับให้ซิงค์ iCloud แล้วปิดหลังจาก 5 วินาที
  4. ผู้ใช้จะได้รับข้อความยืนยันในแชต ส่วน shortcut เองไม่ถูกส่งไปยังอุปกรณ์

ข้อกำหนด:

  • เซิร์ฟเวอร์ต้องรันบน macOSshortcuts run ใช้ได้เฉพาะ macOS เท่านั้น บนแพลตฟอร์มอื่น เซิร์ฟเวอร์จะบันทึกคำเตือนและย้อนกลับไปรันบนอุปกรณ์แทน
  • Shortcut ต้องถูกติดตั้งใน Shortcuts.app บน Mac ของเซิร์ฟเวอร์
  • Shortcut ควรรองรับ Dictionary เป็น input (PocketHook ห่อข้อมูลใน { context, timestamp, app, data })

เมื่อใดที่ควรใช้ target: mac:

  • การกระทำที่ซิงค์กับ iCloud (Notes, Reminders, Calendar) — ผลลัพธ์จะไปถึงทุกอุปกรณ์อยู่แล้ว
  • การประมวลผลที่ใช้เวลานานและคุณต้องการให้ไม่รันบนอุปกรณ์ iOS
  • Shortcut ใดก็ตามที่ไม่จำเป็นต้องโต้ตอบกับ UI ของ iPhone

เมื่อใดที่ควรคง target: device (ค่าเริ่มต้น):

  • Shortcut ที่ต้องการคุณสมบัติเฉพาะของ iPhone (กล้อง ตำแหน่งที่แม่นยำ การอัตโนมัติของแอปในเครื่อง)
  • Shortcut ที่ขอข้อมูลนำเข้าแบบโต้ตอบจากผู้ใช้
  • Shortcut ที่ใช้ App Intents จากแอปเฉพาะ iOS

งานเบื้องหลัง
#

ขอให้ agent ตั้งเวลางานและมันจะจัดการส่วนที่เหลือ:

  • “ตรวจสอบสภาพอากาศทุกเช้า 8 โมงและสร้างโน้ต”
  • “รันสคริปต์นี้ทุกชั่วโมง”
  • “เตือนฉันเช็คอีเมลใน 30 นาที”

งานรองรับนิพจน์ cron (0 8 * * *) และช่วงเวลาอย่างง่าย (30m, 1h, 2d) ผลลัพธ์ถูกส่งไปยัง PocketHook เมื่อตรวจสอบ endpoint /jobs

สองประเภทการดำเนินการ:

  • Shell — รันคำสั่ง bash จับผลลัพธ์ สามารถเรียก Shortcut เมื่อเสร็จสิ้น
  • Prompt — ถูกประมวลผลโดย agent AI พร้อมสิทธิ์เข้าถึงเครื่องมือเต็มรูปแบบ เก็บการตอบกลับ PocketHook ที่สมบูรณ์

Dev Server
#

เมื่อ agent สร้างโปรเจกต์เว็บใน workspace (Hugo, Astro, Next.js, Flask, Go ฯลฯ) มันจะเสนอให้บริการอย่างเชิงรุก:

  • Preview — เริ่ม dev server ในเครื่องที่พอร์ตที่กำหนดอัตโนมัติเพื่อดูอย่างรวดเร็ว
  • Public — เริ่มเซิร์ฟเวอร์และเปิดเผยผ่านอุโมงค์ HTTPS เพื่อให้เข้าถึงได้จากทุกที่

Agent จัดการวงจรชีวิต: เริ่ม หยุด และรายการเซิร์ฟเวอร์ที่ทำงานอยู่ เซิร์ฟเวอร์ทั้งหมดถูกล้างเมื่อเซิร์ฟเวอร์หลักหยุด

สัญญา tunnel
#

เมื่อ agent เริ่มเซิร์ฟเวอร์พร้อมการเปิดเผยผ่าน tunnel รันไทม์จะบังคับใช้: หากไม่มีเครื่องมือ tunnel (Tailscale, ngrok, cloudflared) ติดตั้งอยู่ เซิร์ฟเวอร์จะปฏิเสธที่จะเริ่ม หากการตั้งค่า tunnel ล้มเหลวหลังจาก spawn กระบวนการที่ไม่มีที่พึ่งจะถูกหยุดและ agent จะถูกแจ้งอย่างชัดเจน — เพื่อให้มันสามารถย้อนกลับไปใช้โหมด preview หรือขอให้คุณติดตั้ง tunnel URL ที่ส่งกลับจะเป็น URL ของ tunnel เสมอเมื่อเปิด tunneling พร้อมหมายเหตุว่า URL ท้องถิ่นใช้ได้เฉพาะในเครื่องเท่านั้น

ในฐานะตาข่ายนิรภัย เครื่องมือ respond_* ทุกตัวจะประมวลผลข้อความของมันภายหลัง: URL localhost หรือ 127.0.0.1 ใด ๆ ที่หลุดเข้าไปในคำตอบจะถูกเขียนใหม่เป็น URL tunnel ที่ตรงกันอัตโนมัติเมื่อเซิร์ฟเวอร์ที่ถูกจัดการมี URL นั้น เมื่อไม่สามารถเขียนใหม่ได้ คุณจะได้รับคำเตือนในบันทึกแทนลิงก์ที่เสียบนโทรศัพท์

แดชบอร์ด
#

แดชบอร์ดเว็บในตัวที่ /dashboard แสดงภาพรวมสดของงานเบื้องหลัง

ไม่มีการยืนยันตัวตนตามการออกแบบ ทั้ง /dashboard และ /api/jobs เป็น endpoint GET แบบเปิด — ใครก็ตามที่สามารถเข้าถึงโฮสต์ก็สามารถแสดงรายการงานได้ จำกัดการเข้าถึงที่ระดับเครือข่าย (Tailscale ACL, ไฟร์วอลล์, reverse proxy พร้อม basic auth) หรือตั้ง DASHBOARD=false หากคุณไม่ต้องการ แอป PocketHook iOS ไม่ใช้ endpoint เหล่านี้

ปรับแต่งได้เต็มที่:

  • แก้ไขด่วน — วาง dashboard.html ใน workspace/dashboard/ สำหรับการปรับแต่งง่าย ๆ
  • โปรเจกต์เต็มรูปแบบ — สร้างโปรเจกต์ framework (Svelte, React, Vue ฯลฯ) ใน workspace/dashboard/ พร้อมเอาต์พุต build ไปยัง dist/

ขอให้ agent ปรับแต่งแดชบอร์ดของคุณและมันจะจัดการส่วนที่เหลือ — ผู้ใช้แต่ละคนจะได้แดชบอร์ดที่ไม่ซ้ำกันและเป็นส่วนตัว

เครื่องมือที่กำหนดเอง
#

Agent สามารถติดตั้งเครื่องมือ CLI และลงทะเบียนเป็นความสามารถใหม่ — ขยายตัวเองโดยไม่ต้องแก้ไขโค้ดเซิร์ฟเวอร์

ตัวอย่างเช่น พูดว่า “ติดตั้ง Playwright และใช้มันจับภาพหน้าจอ” Agent จะ:

  1. ติดตั้ง dependency
  2. สร้างคำจำกัดความเครื่องมือ (ไฟล์ .md ง่าย ๆ)
  3. ใช้เครื่องมือใหม่ในการสนทนาครั้งต่อไป

เครื่องมือที่กำหนดเองถูกโหลดใหม่แบบ hot-reload — ไม่ต้องรีสตาร์ท ลบไฟล์ .md เพื่อลบเครื่องมือ

การจัดการเวอร์ชัน
#

ข้อมูลผู้ใช้ทั้งหมดถูกจัดการเวอร์ชันอัตโนมัติ:

  • ไฟล์ workspace — ถูกติดตามด้วย repo git ในเครื่องภายใน workspace/ ทุกการเขียนสร้าง auto-commit ขอให้ agent “ยกเลิกการเปลี่ยนแปลงล่าสุด” หรือใช้ git revert HEAD ด้วยตนเอง
  • ไฟล์การกำหนดค่าconfig/agent-instructions.md, config/personality.md, skills/ และ permissions.json ถูกสำรองก่อนทุกการแก้ไข สูงสุด 20 เวอร์ชันต่อไฟล์

Git เป็นตัวเลือก — หากไม่ได้ติดตั้ง การเปลี่ยนแปลง workspace จะไม่ถูกจัดการเวอร์ชัน การสำรองข้อมูลการกำหนดค่าใช้งานได้เสมอ

การปรับแต่ง agent ของคุณ
#

Agent server มาพร้อมกับ framework base ขั้นต่ำและคาดหวังให้คุณวางการปรับแต่งของคุณเองทับลงไป รันไทม์แยกทั้งสองออกจากกัน เพื่อให้การอัปเดต framework ไม่ทำลายงานของคุณ

Framework กับผู้ใช้
#

pockethook-agent-server/
├── skills/                      # ทักษะที่มาจาก framework (อ่านอย่างเดียว)
├── custom-tools/                # สงวนไว้สำหรับเครื่องมือที่มาจาก framework (อ่านอย่างเดียว)
├── config/
│   ├── agent-instructions.md    # คำสั่ง agent ของ framework (อ่านอย่างเดียว)
│   └── personality.md           # บุคลิกของ framework (อ่านอย่างเดียว)
└── data/user/                   # การปรับแต่งของคุณอยู่ที่นี่ (ถูก git-ignore)
    ├── skills/                  # ทักษะของคุณเอง (จะทับ base ตามชื่อไฟล์)
    ├── custom-tools/            # เครื่องมือที่กำหนดเองที่คุณติดตั้ง
    ├── instructions.md          # ส่วนเพิ่มเติมของคุณต่อคำสั่ง agent
    └── prefs.json               # ค่าแบบมีประเภทที่อ้างอิงเป็น {{prefs.key}}

การปรับแต่งของผู้ใช้ถูกเขียนผ่านเครื่องมือแบบมีประเภทเฉพาะ (create_user_skill, create_custom_tool) เพื่อให้ไฟล์ที่ได้ตรงกับรูปแบบของตัวโหลดเสมอ เครื่องมือ write ยังปฏิเสธเส้นทางใด ๆ ที่อยู่ภายใต้ skills/, custom-tools/ หรือ config/ และเปลี่ยนเส้นทาง agent ไปยัง data/user/* — ดังนั้นแม้แต่การแก้ไขไฟล์โดยตรงก็จะไปจบที่ชั้นผู้ใช้

หมายเหตุเกี่ยวกับไดเรกทอรี custom-tools/ ของ base ปัจจุบันเก็บไว้เพียงเทมเพลต (_example.md) ที่ตัวโหลดมองข้าม — เครื่องมือทุกอย่างที่ agent ติดตั้งให้คุณจะไปที่ data/user/custom-tools/ ไดเรกทอรีนี้ถูกสงวนไว้เพื่อให้ framework รุ่นอนาคตสามารถส่งเครื่องมือในตัวแบบเลือกใช้ได้โดยไม่ทับการติดตั้งของคุณ เมื่อถึงเวลานั้น ไฟล์ชั้นผู้ใช้ของคุณยังคงชนะในกรณีชื่อเครื่องมือซ้ำกัน ดังนั้นไม่มีอะไรต้องย้าย

สี่วิธีในการปรับแต่ง
#

สิ่งที่คุณอยากเปลี่ยนที่อยู่ของมันตัวอย่าง
ทักษะ shortcut หรือพฤติกรรมdata/user/skills/<name>.md“สร้างทักษะเพื่อบันทึกการออกกำลังกาย”
เครื่องมือ CLI ที่ห่อเป็นความสามารถของ agentdata/user/custom-tools/<name>.md“ติดตั้ง ffmpeg แล้วให้ฉันใช้สำหรับแปลงไฟล์”
กฎรวม (“ตอบเป็นภาษาอังกฤษเสมอ”, “อย่าใช้ตาราง”)data/user/instructions.md“ต่อจากนี้ สรุปบทความใน 3 bullet เสมอ”
ค่าเริ่มต้นแบบมีประเภทที่ทักษะอ้างอิงdata/user/prefs.json“จุดเริ่มต้นเส้นทางเริ่มต้นของฉันคือมาดริด”{"routeOrigin": "Madrid"}

คุณไม่จำเป็นต้องเขียนไฟล์เหล่านี้ด้วยมือ เพียงบอก agent ว่าคุณต้องการอะไร แล้วมันจะเลือกชั้นที่ถูกต้องโดยอัตโนมัติ

Prefs แบบมีประเภทด้วย {{prefs.*}}
#

สมมติว่าคุณเขียนทักษะวางแผนเส้นทางที่ต้องรู้จุดเริ่มต้นเริ่มต้นของคุณ แทนที่จะฝัง “มาดริด” ไว้ในทักษะ ให้อ้างอิง pref แทน:

- **จุดเริ่มต้น**: {{prefs.routeOrigin}} ยกเว้นว่าผู้ใช้ระบุจุดเริ่มต้นอื่น

และเก็บค่าไว้ใน data/user/prefs.json:

{
  "routeOrigin": "Madrid, Spain",
  "preferredMapsApp": "apple",
  "tunnel": { "domain": "my-host.ts.net" }
}

เซิร์ฟเวอร์แทนที่ placeholder เมื่อโหลดทักษะ คีย์ซ้อน ({{prefs.tunnel.domain}}) ก็ใช้ได้ คีย์ที่ไม่รู้จักจะไม่ถูกแตะเพื่อให้พิมพ์ผิดมองเห็นได้

การแก้ไข framework base โดยตรง
#

ถ้าคุณโฮสต์เองและต้องการปรับแต่ง framework เอง คุณสามารถแก้ไข config/agent-instructions.md, config/personality.md, skills/ หรือ custom-tools/ โดยตรง — เซิร์ฟเวอร์ไม่ห้ามคุณเมื่อใช้เครื่องมือแก้ไขไฟล์ แต่ agent จะไม่เขียนลงในเส้นทางเหล่านั้นจากการสนทนา และการอัปเดต framework จะเขียนทับการแก้ไขของคุณ ให้เลือกใช้ชั้นผู้ใช้สำหรับทุกอย่างที่คุณอยากเก็บไว้

การขยายเซิร์ฟเวอร์
#

  • เครื่องมือที่กำหนดเอง — ขอให้ agent ติดตั้งเครื่องมือ CLI; พวกมันจะไปอยู่ที่ data/user/custom-tools/ โดยอัตโนมัติ
  • เพิ่มทักษะ — ขอให้ agent สร้างทักษะ; ไฟล์จะไปที่ data/user/skills/
  • เปลี่ยนพฤติกรรม — ขอให้ agent ใช้กฎรวม; มันจะต่อท้ายไปยัง data/user/instructions.md
  • กำหนดค่าสิทธิ์ — รัน bun run permissions เพื่อควบคุมเครื่องมือที่ agent สามารถใช้ได้
  • เพิ่มเครื่องมือในตัว — ใช้งานฟังก์ชันเครื่องมือใหม่ใน src/tools.ts สำหรับการเชื่อมต่อที่ลึกขึ้น (ต้อง fork เซิร์ฟเวอร์)

การกำหนดค่า
#

การตั้งค่าทั้งหมดถูกเก็บใน .env (สร้างโดย bun run setup) ตัวเลือกหลัก:

ตัวแปรค่าเริ่มต้นคำอธิบาย
AUTH_TOKEN(จำเป็น)รหัสลับที่ใช้ร่วมกับ PocketHook
LLM_API_KEY(จำเป็น)API key ผู้ให้บริการ LLM
LLM_PROVIDERanthropicชื่อผู้ให้บริการ
LLM_MODELclaude-sonnet-4-20250514ID โมเดล
LLM_REASONINGoffระดับการให้เหตุผล: off, minimal, low, medium, high, xhigh ระดับสูงขึ้นจะเพิ่ม token การคิดที่ซ่อนอยู่ (ช้าลง + แพงขึ้น) ถูกเพิกเฉยโดยโมเดลที่ไม่รองรับ
PORT3000พอร์ตเซิร์ฟเวอร์
AGENT_NAMEPocketHook Assistantชื่อแสดงของ agent
MAX_HISTORY50ข้อความในหน่วยความจำระยะสั้น
MAX_RECALL5หน่วยความจำที่ส่งกลับต่อรอบโดยการเรียกคืนเชิงความหมาย (เฉพาะเมื่อ VECTOR_MEMORY=true)
SESSION_TTL_MINUTES60การหมดอายุเซสชัน
VECTOR_MEMORYfalseเปิดใช้หน่วยความจำเชิงความหมาย (ต้องใช้ผู้ให้บริการ embedding)
EMBEDDING_PROVIDERollamaผู้ให้บริการ embedding: ollama, lm-studio หรือ openai
EMBEDDING_MODELnomic-embed-textชื่อโมเดล embedding
EMBEDDING_URL(อัตโนมัติ)URL API embedding
EMBEDDING_API_KEYAPI key สำหรับ OpenAI embeddings
LOG_LEVELinfoระดับ log: debug, info, warn, error
RATE_LIMIT_MAX30คำขอสูงสุดต่อหน้าต่าง
DASHBOARDtrueเปิดใช้แดชบอร์ดเว็บ (route /dashboard)
INSTANCE_NAME(basename ของไดเรกทอรีโปรเจกต์ โดยตัด pockethook- ออก)คำต่อท้ายที่ใช้สำหรับ label ของบริการระบบ ไดเรกทอรีบันทึก และการจับคู่กระบวนการ ตั้งค่าอย่างชัดเจนเมื่อรันหลาย checkout บนเครื่องเดียวกัน

ดูข้อมูลอ้างอิงการกำหนดค่าฉบับเต็มใน GitHub repository

การทำงานเป็นบริการ
#

ติดตั้งเป็นบริการถาวรที่เริ่มต้นอัตโนมัติ:

bun run service install
แพลตฟอร์มBackendตำแหน่งของบริการ
macOSlaunchd~/Library/LaunchAgents/com.pockethook.${INSTANCE_NAME}.plist
Linuxsystemd (user)~/.config/systemd/user/pockethook-${INSTANCE_NAME}.service
WindowsNSSMPocketHook-${PascalCase(INSTANCE_NAME)} ใน Windows Service Manager

INSTANCE_NAME มีค่าเริ่มต้นเป็น basename ของไดเรกทอรีโปรเจกต์โดยตัด pockethook- ออก (เช่น checkout ใน pockethook-agent-server/ จะกลายเป็น agent-server) ตั้งค่าอย่างชัดเจนเพื่อรันหลาย checkout บนเครื่องเดียวกันโดยไม่ชนกัน — แต่ละ instance จะเก็บ data/ และ log ของตัวเอง

จัดการด้วย bun run service status, restart, stop หรือ uninstall

ความปลอดภัย
#

  • ต้องใช้ HTTPS — PocketHook บังคับใช้ HTTPS สำหรับ URL ทั้งหมด
  • การยืนยัน bearer token — รหัสลับที่ใช้ร่วมระหว่างแอปและเซิร์ฟเวอร์
  • การจำกัดอัตรา — การจำกัดต่อ token ป้องกันการใช้ในทางที่ผิด
  • เครื่องมือแบบ sandbox — คำสั่ง shell และการเข้าถึงไฟล์ถูกจำกัดโดยสิทธิ์
  • รูปแบบที่ถูกบล็อก — คำสั่งอันตราย (sudo, rm -rf /) ถูกบล็อกโดยค่าเริ่มต้น
  • ขอบเขตไดเรกทอรีทำงาน — Agent ไม่สามารถหลุดออกจากไดเรกทอรีที่กำหนด
  • ไฟล์ที่ละเอียดอ่อนถูกป้องกัน.env, .git, *.key, *.pem ถูกบล็อกจากการเข้าถึงของ agent
  • การจัดการเวอร์ชันอัตโนมัติ — การเปลี่ยนแปลง workspace ทั้งหมดถูกติดตามด้วย git เพื่อการย้อนกลับอย่างง่าย