Hermes Agent
NousResearch ทำเอเจนต์มาให้แล้ว เหลือแค่หาที่รัน
Hermes Agent เป็นโอเพนซอร์ส ใช้งานได้จริง และส่วนที่ยากไม่ใช่ตัวเอเจนต์ แต่คือเครื่อง: ที่อยู่เว็บ ใบรับรอง พื้นที่เก็บข้อมูลที่ไม่หายตอนรีสตาร์ต และที่เก็บคีย์สี่ตัวที่ไม่ควรผ่านหน้าต่างแชตเลย บทนี้คือครึ่งนั้น และโค้ดที่คุณต้องเขียนมีเท่ากับศูนย์
1. สิ่งที่กำลังจะขึ้นระบบคืออะไร
NousResearch/hermes-agent ปล่อยอิมเมจคอนเทนเนอร์ออกมาให้ ข้างในนั้นนอกจากตัวเอเจนต์ยังมีอะแดปเตอร์ LINE ที่เป็นแพลตฟอร์มชั้นหนึ่ง อยู่ชั้นเดียวกับ Telegram, Discord, Slack, WhatsApp, Teams, SMS และ WeCom มันตรวจลายเซ็นของเว็บฮุกเอง ตัดข้อความยาวให้พอดีกับห้าบับเบิลของ LINE ส่งรูปและเสียงได้ มีรายชื่อผู้ใช้และกลุ่มที่อนุญาต และตัดข้อความซ้ำที่ LINE ส่งมาสองรอบทิ้ง
เรื่องนี้สำคัญ เพราะท่าแรกที่ทุกคนคิดถึงคือเขียนเว็บฮุกของตัวเองมารับข้อความแล้วเรียกเอเจนต์ต่อ เราเขียนแบบนั้นจริง 160 บรรทัด แล้วเอาไปเทียบกับอิมเมจ และลบทิ้งทั้งหมด ทุกบรรทัดคือของที่มีอยู่แล้วข้างใน เขียนใหม่ให้แย่ลง
บทนี้จึงไม่มีโค้ดเลย มีสองไฟล์ และไม่มีไฟล์ไหนเป็นโปรแกรม
2. สองไฟล์นั้น
อิมเมจนี้ไม่ประกาศทั้ง ENTRYPOINT และ CMD — อ่านจากตัวอิมเมจ ไม่ใช่จากเอกสาร — Dockerfile ที่ไม่บอกคำสั่งจึงรันอะไรไม่ได้เลย และ gateway ไม่ใช่โปรแกรม แต่เป็นซับคอมมานด์ของไบนารี สั่ง gateway run เฉย ๆ จะได้ sh: gateway: not found
FROM nousresearch/hermes-agent:v2026.9.7
# เว็บฮุกฟังที่พอร์ต 8646 ที่พาธ /line/webhook และปลั๊กอิน LINE
# จะเปิดตัวเองเมื่อมีคีย์ทั้งสองตัวอยู่ใน environment
# ไม่ต้องเขียนไฟล์ config และไม่ต้องเลือกแพลตฟอร์ม
ENV LINE_PORT=8646
# แดชบอร์ดคือที่ตัดสินใจว่าเอเจนต์ทำอะไรได้บ้าง — เทอร์มินัล การรันโค้ด
# การใช้คอมพิวเตอร์ และเบราว์เซอร์ เปิดไว้หมดตั้งแต่ต้น
# นั่นเป็นการตัดสินใจของเจ้าของ จึงเสิร์ฟหน้านี้ออกมา ไม่ใช่เดาแทนตอน deploy
ENV HERMES_DASHBOARD=1 \
HERMES_DASHBOARD_PORT=9119
EXPOSE 8646 9119
CMD ["/opt/hermes/bin/hermes", "gateway", "run"]อีกไฟล์คือ manifest access: owner ปิดแอปไม่ให้ใครเข้าถึงนอกจากบัญชีคุณ ส่วนพาธเดียวที่ LINE ต้องเข้าถึงได้จะเปิดคืนตอน deploy เพราะ LINE ยิงเข้ามาโดยไม่มีเซสชัน และไม่มีทางเข้าสู่ระบบ
version: 1
access: owner
components:
web:
path: .
port: 8646
public: true
# แดชบอร์ด บนชื่อของตัวเอง คอนเทนเนอร์เดียวกัน HERMES_HOME เดียวกัน
# ถ้าแยกเป็นสอง component จะแชร์ดิสก์ก้อนนี้ไม่ได้
ports:
9119: hermes-admin
# เซสชันและความจำ HERMES_HOME ชี้มาที่นี่ในคำสั่งข้างล่าง
disk: true
# ประกาศไว้ แต่ไม่ถูกส่งผ่าน: deploy จะหยุดรอให้คุณกรอกเองในหน้าแอป
# ไม่มีคีย์ไหนผ่านมือเอไอ
secrets:
[
LINE_CHANNEL_ACCESS_TOKEN,
LINE_CHANNEL_SECRET,
OPENROUTER_API_KEY,
HERMES_DASHBOARD_BASIC_AUTH_PASSWORD,
]
resources:
requests: {memory: 512Mi, cpu: 250m}
limits: {memory: 2048Mi, cpu: 1000m}3. สั่งขึ้นระบบ
HERMES_HOME คือตัวแปรเดียวที่ตัดสินว่านี่เป็นของเล่นหรือของจริง มันคือที่อยู่ของเซสชันและความจำ — ถูกอ้างถึงในอิมเมจ 138 จุด มากกว่าตัวแปรอื่นทั้งหมด — ถ้าไม่ชี้มาที่ดิสก์ บทสนทนาทั้งหมดจะหายทุกครั้งที่ deploy ใหม่
4. คีย์ไม่ได้อยู่ในคำสั่ง
deploy จะหยุดก่อนเริ่มอะไรทั้งนั้น แล้วพิมพ์ลิงก์ออกมา มีสี่คีย์ที่ประกาศไว้ใน manifest และไม่มีตัวไหนผ่านเอไอที่กำลังทำ deploy ให้ หรือผ่านประวัติคำสั่งในเทอร์มินัลของคุณ
คีย์ | เอามาจากไหน |
|---|---|
LINE_CHANNEL_ACCESS_TOKEN | LINE Developers console |
LINE_CHANNEL_SECRET | LINE Developers console |
OPENROUTER_API_KEY | ผู้ให้บริการโมเดลที่คุณจ่ายเงิน |
HERMES_DASHBOARD_BASIC_AUTH_PASSWORD | คุณตั้งเอง |
เปิดลิงก์ กรอกในหน้าแอปของตัวเอง แล้ว deploy จะไปต่อ ตัวสุดท้ายถูกประกาศไว้ด้วยเหตุผล: Hermes ไม่ยอมเปิดแดชบอร์ดออกนอก loopback ถ้าไม่มีระบบยืนยันตัวตน และแดชบอร์ดคือหน้าที่ตัดสินว่า เอเจนต์ทำอะไรได้บ้าง อ่านเรื่องการเก็บคีย์ต่อได้ที่นี่
5. คอนเทนเนอร์เดียว ได้สองที่อยู่
ที่อยู่ | คืออะไร |
|---|---|
NAME.erawan.app/line/webhook | เอาไปวางใน LINE Developers |
hermes-admin.erawan.app | แดชบอร์ด มีหน้าล็อกอินของตัวเอง |
จากนั้นตั้ง webhook URL ใน LINE Developers console แล้วกด Verify ทักไปหาบัญชีนั้นหนึ่งข้อความ เท่านี้จบ
6. ราคา และสิ่งที่เรารู้เพราะรันเอง
ขนาดนี้อยู่ในแพ็ก Hobby — ฿99 ต่อเดือน เพดานใน manifest คือหนึ่งคอร์ ซึ่งคือสิ่งที่ Hobby ให้ ส่วนที่จองไว้คือ 250m เอเจนต์ที่นั่งรออยู่จึงแทบไม่กินอะไรเลย และตัวที่ทำงานหนักจะถูกหน่วง ไม่ใช่ถูกปฏิเสธ ขยับแพ็กขึ้นคือสิ่งที่ซื้อคอร์ที่สอง
เราเดินเรื่องนี้จริงบน production ด้วยบัญชีจริงและช่อง LINE จริง และใช้ไปสาม deploy ทุกความล้มเหลวเป็นของเรา ไม่ใช่ของ template และไม่มีอันไหนหาเจอได้โดยไม่ลงมือรัน: worker ที่ไม่มีวันพร้อมเพราะทุก workload ถูกตรวจสุขภาพ รวมถึงตัวที่ไม่ได้ฟังพอร์ตไหนเลย; ชื่อพอร์ตที่ถูกจองและถูกคืนในวินาทีเดียวกัน ทำให้แดชบอร์ดตอบ 404 ทั้งที่ข้างใต้ถูกทุกอย่าง; และแอปที่ใช้ manifest แล้วพาธสาธารณะหายไปเงียบ ๆ ทำให้เว็บฮุกตอบหน้าเข้าสู่ระบบแทน อันสุดท้ายเกิดกับแอปที่ใช้ manifest ทุกตัว ที่มีเว็บฮุกหรือ callback การชำระเงิน และคนที่รู้ก่อนคือ LINE หรือ Stripe ไม่ใช่เจ้าของแอป
ทั้งสามเรื่องแก้แล้ว ที่เล่าให้ฟังเพราะหน้าที่บอกว่า deploy แรกผ่านฉลุย คือหน้าที่เขียนโดยคนที่ไม่ได้ลงมือทำ