2 คะแนน โดย GN⁺ 2023-10-17 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • Letta เป็นโครงการสำหรับสร้าง AI ที่ใช้ หน่วยความจำขั้นสูง ซึ่งสามารถเรียนรู้และพัฒนาตนเองได้เมื่อเวลาผ่านไป
  • วิธีใช้งานแบ่งเป็น Letta Code สำหรับรันเอเจนต์ในเทอร์มินัลบนเครื่อง และ Letta API สำหรับผสานเอเจนต์เข้ากับแอปพลิเคชัน
  • CLI ต้องการ Node.js 18+ และติดตั้งด้วย npm install -g @letta-ai/letta-code จากนั้นรัน letta เพื่อใช้งานเอเจนต์ที่มีหน่วยความจำบนคอมพิวเตอร์ของคุณ
  • เอเจนต์ Letta Code ช่วยงานด้านการเขียนโค้ดและงานที่ทำได้บนคอมพิวเตอร์ รองรับ skills และ subagents พร้อมบันเดิล skills/subagents ที่สร้างไว้ล่วงหน้าสำหรับหน่วยความจำขั้นสูงและการเรียนรู้อย่างต่อเนื่อง
  • Letta ไม่ยึดติดกับโมเดลใดโมเดลหนึ่ง โดย README แนะนำ Opus 4.5 และ GPT-5.2 เพื่อประสิทธิภาพสูงสุด และลิงก์ model leaderboard ไว้เป็นข้อมูลอ้างอิงด้านอันดับ
  • Letta API ใช้สำหรับผสานเอเจนต์แบบมีสถานะเข้ากับแอปพลิเคชัน โดยมี agents API แบบฟีเจอร์ครบถ้วน รวมถึง SDK สำหรับ Python และ TypeScript
    • แพ็กเกจ TypeScript/Node.js: @letta-ai/letta-client
    • แพ็กเกจ Python: letta-client
    • ตัวอย่างแสดงขั้นตอนการสร้างเอเจนต์และส่งข้อความโดยใช้ LETTA_API_KEY และ Letta API key
  • การใช้งาน Letta และบริการ Letta ที่เกี่ยวข้องอยู่ภายใต้เงื่อนไขการยอมรับ privacy policy และ terms of service

1 ความคิดเห็น

 
GN⁺ 2023-10-17
ความคิดเห็นจาก Hacker News
  • พวกเราเป็นผู้เขียน MemGPT ถ้ามี คำถามเกี่ยวกับการใช้งาน/การ implement ก็ถามมาได้เลย
    ถ้าอยากลองใช้เอง สามารถดูการแก้ไขหน่วยความจำทำงานได้ในบอต Discord บนเซิร์ฟเวอร์ MemGPT Discord (https://discord.gg/9GEQrxmVyE) เมื่อคุยกับบอต จะเห็นกระบวนการที่ MemGPT แก้ไขหน่วยความจำเพื่ออัปเดตโปรไฟล์เกี่ยวกับผู้ใช้และตัวมันเอง
    ทั้งหมดเป็นโอเพนซอร์ส จึงรันในเครื่องได้จากโค้ดที่ https://github.com/cpacker/MemGPT ใน repository ยังมี ตัวอย่างที่เน้นเอกสาร สำหรับคุยกับ MemGPT เกี่ยวกับเอกสาร API ของ LlamaIndex ด้วย

  • สงสัยว่าทำไมถึงจัดการทุกอย่างใน context window เดียว เมื่อไม่กี่เดือนก่อนตอนทดลองสิ่งที่คล้ายกัน ผม parallelize ด้วยหลาย agent ในขั้นตอน preprocessing/postprocessing
    เช่น context window หลักไม่รู้เลยว่ามีการสร้างหรือค้นคืนหน่วยความจำ postprocessor จะสร้างหน่วยความจำจากบทสนทนาโดยอัตโนมัติแล้วบันทึกไว้ และเก็บบทสนทนาทั้งหมดใน vector database ด้วย preprocessor จะฉีดหน่วยความจำและบริบทที่เกี่ยวข้องให้เข้ากับบทสนทนาโดยอัตโนมัติ แถมยังเขียน history ใหม่ให้จากมุมมองของ context window หลักเหมือนกับว่าหน่วยความจำนั้นมีมาตั้งแต่แรก
    วิธีนี้ช่วยประหยัดพื้นที่ใน context window หลักที่ต้องใช้กับ system prompt ที่ไม่จำเป็นและอื่น ๆ ได้มาก

    • เป็นประเด็นที่ดี ในบริบทของแชตบอต การจะมอบหมายการจัดการหน่วยความจำให้ใครเป็นทางเลือกในการออกแบบ และผมมองว่ามีอยู่สองแนวทางใหญ่ ๆ คือ การจัดการหน่วยความจำแบบโดยนัย และ การจัดการหน่วยความจำแบบชัดแจ้ง
      แนวทางโดยนัยคือ “LLM หลัก” หรือในแชตคือ “เธรดสนทนา” จะไม่รู้เรื่องการจัดการหน่วยความจำที่อยู่เบื้องหลัง การจัดการนี้อาจทำโดย “LLM สำหรับหน่วยความจำ”, สคริปต์แบบ rule-based, neural network ขนาดเล็ก ฯลฯ
      แนวทางแบบชัดแจ้งคือแบบของ MemGPT ซึ่งใช้ LLM ตัวเดียวจัดการทั้งหมด งานวิจัยเดิมเกี่ยวกับการแชตหลาย session/ระยะยาวมักเป็นแนวทางโดยนัยที่มีขั้นตอนสร้างหน่วยความจำแยกต่างหาก และ memory store ของแชตบอตสำหรับผู้บริโภคก็น่าจะเป็นแบบโดยนัยเป็นส่วนใหญ่
      การจัดการหน่วยความจำแบบชัดแจ้งต้องการการทำตามคำสั่งที่ซับซ้อน จึงคิดว่ายากสำหรับ LLM สาธารณะส่วนใหญ่ในตอนนี้ กำลังดูวิธีแก้ เช่น การ fine-tune โมเดลเปิด
      trade-off ก็เป็นอย่างที่คุณพูด แนวทางโดยนัยไม่จำเป็นต้องใส่คำสั่งการจัดการหน่วยความจำทั้งหมดไว้ใน pre-prompt ของ LLM ข้อความระบบทั้งหมดของ MemGPT มีประมาณ 1,000 token ในทางกลับกัน เมื่อ LLM ทำงานได้ถูกต้อง การจัดการหน่วยความจำแบบชัดแจ้งทำให้ระบบโดยรวมเรียบง่ายกว่ามาก เพราะไม่มี overhead ในการจัดการ LLM หลายโมเดลบนเธรดแบบขนาน
    • เป็นแนวทางที่น่าสนใจ ผมกำลังทำสิ่งที่คล้ายกัน โดยใส่ ข้อมูลธุรกรรม เข้าไปใน context window เป็นส่วนหนึ่งของ feedback loop เพื่อเขียน history ใหม่
      ผมมองว่า LLM และการประมวลผลภาษาธรรมชาติอาจกลายเป็นอินเทอร์เฟซที่เป็นไปได้มากขึ้นสำหรับข้อมูลแบบมีโครงสร้าง เมื่อมีการสร้างข้อมูลในบริบททางธุรกิจเฉพาะ ก็จะดึงข้อมูล สร้าง embedding และสร้าง vector database
      ใน postprocessing หลังจากโมเดลหลักตอบแล้ว postprocessor จะสร้างหน่วยความจำจากบทสนทนาโดยอัตโนมัติและบันทึกไว้ โดยเก็บบริบทสำคัญไว้แต่ไม่เพิ่มภาระงานนี้ให้โมเดลหลัก ส่วนหนึ่งของคำขอยังรัน business logic ที่เกี่ยวข้อง แล้วป้อนกลับเข้าระบบ
      ใน preprocessing ก่อนส่งอินพุตใหม่ไปยังโมเดลหลัก จะตรวจสอบหน่วยความจำที่บันทึกไว้ ฉีดบริบทที่เกี่ยวข้อง และรัน logic ด้วย กล่าวคือ preprocessor จะให้ “การทบทวน” บทสนทนาก่อนหน้าแก่โมเดลหลัก เพื่อเตรียมให้ตอบได้สอดคล้องและมีข้อมูลมากขึ้น
    • multi-agent มีศักยภาพอยู่ไม่น้อย ผมคิดว่าการตอบของ agent มี entropy ในระดับหนึ่ง ทำให้ยิ่งคุ้มที่จะลอง
  • เกี่ยวกับสิ่งที่เขียนไว้ในข้อจำกัด หาก variant ของ Llama 2 70B แม้จะ fine-tune มาเพื่อการเรียกฟังก์ชันแล้ว แต่ยังสร้างการเรียกฟังก์ชันผิด หรือ hallucinate ฟังก์ชันที่อยู่นอก schema ที่ให้มา ก็สามารถใช้ grammar-based sampling ได้
    อย่างน้อยก็รับประกันได้ว่าการเรียกฟังก์ชันจะถูกต้องทางไวยากรณ์
    [0] https://github.com/ggerganov/llama.cpp/tree/master/grammars

    • grammar-based sampling เป็นไอเดียที่ดีและเหมาะมากกับอะไรอย่าง MemGPT ตอนทดลอง MemGPT กับโมเดลที่ไม่ใช่ gpt-4 ปัญหาที่ส่งผลต่อประสิทธิภาพมากที่สุดคือ การใช้ argument ของฟังก์ชันผิด และ การ hallucinate ฟังก์ชัน
      ตัวอย่างเช่น โมเดลขนาดใหญ่ที่ fine-tune ด้วยข้อมูลการเรียกฟังก์ชัน (https://huggingface.co/jondurbin/airoboros-l2-70b-2.1#agentf...) โดยทั่วไปก็ output JSON ที่ parse ได้ แต่ argument หรือชื่อฟังก์ชันผิด
      เช่น ตอนพยายามเขียนข้อมูล แทนที่จะเรียก working_context.append ที่ถูกต้องตามที่ระบุไว้ใน pre-prompt กลับ output การเรียก personal_diary.add ซึ่งไม่ได้กำหนดไว้เลย
  • เห็นแค่ชื่อเรื่องแล้วนึกว่าเป็นเทคนิคแก้ไขหน่วยความจำของ neural memory ใน LLM คือการเปลี่ยน หน่วยความจำระดับ weight ระหว่างสนทนา ไม่ใช่ context เช่นแนวทางอย่าง ROME [1]
    พอรู้ว่าจริง ๆ แล้วเป็นงาน RAG ที่เจ๋งก็ดีใจ และอีกไม่นานผมจะทำ MemEditGPT เวอร์ชันของตัวเอง
    [1] https://arxiv.org/abs/2202.05262

    • ถ้าอยาก contribute ก็เปิด issue หรือ PR ใน repository ได้เลย ทั้งหมดเป็นโอเพนซอร์สและใช้ Apache 2.0 และเรากำลังพิจารณาอย่างจริงจังเรื่องการผนวก workflow ทั่วไปเข้ากับ CLI
      อย่างที่เข้าใจถูกแล้ว MemGPT ไม่ได้แก้ไข weight ของ LLM แบบ ROME “หน่วยความจำ” ที่พูดถึงใน MemGPT อยู่ระดับข้อความ/token ไม่ใช่ระดับ weight
      แนวคิดหลักคือให้ LLM มีความสามารถในการแก้ไข scratchpad ของ working memory ที่คงอยู่ภายใน context และอ่าน/เขียน context ภายนอกผ่านฟังก์ชัน รายละเอียดสำคัญคือ เพื่อรับมือกับข้อจำกัดของ context ที่มีขนาดจำกัด การอ่านจึงทำเป็นหน้าเสมอ หรือก็คือเป็น chunk
      MemGPT สามารถ chain ฟังก์ชันต่อกันเพื่ออ่านและเขียนซ้ำหลายครั้งจากอินพุตผู้ใช้เดียวได้ ดังนั้นจึงสามารถค้นหา database เอกสารขนาดใหญ่และรวบรวมข้อมูลจากหลายแหล่งเพื่อส่งคำตอบกลับมาได้ เหมือนตัวอย่างเอกสาร API ของ LlamaIndex ใน README
  • อยู่พักหนึ่งผมสงสัยว่า ChatGPT เวอร์ชันเว็บ (chat.openai.com ไม่ใช่ API) อาจทำงานแบบนี้ในการสนทนา แม้ในประวัติแชตที่ยาวมาก ก็รู้สึกว่าคุณภาพค่อย ๆ ลดลง มากกว่าจะลืมทุกอย่างไปในทันที
    แน่นอนว่าในบริบทอาจมีเบาะแสมากกว่าที่ผมคิดก็ได้
    ไม่ว่าอย่างไร ผมคิดว่าไอเดียแบบนี้มีโอกาสสูงที่จะกลายเป็น ฟีเจอร์พื้นฐาน ของแชตบอตทุกตัวในอนาคต

    • การสรุปแบบเรียกซ้ำ เป็นวิธีที่เรียบง่ายและเป็นที่นิยมในการให้ภาพลวงตาของบริบทไม่จำกัด เมื่อจำเป็นต้องเคลียร์พื้นที่ ก็แค่อัดข้อความที่เก่าที่สุด N ข้อความให้เป็นข้อความสรุปเดียว
      มันมีการสูญเสียข้อมูล และสุดท้ายก็จะเสียข้อมูลสำคัญไป แต่ประสิทธิภาพอาจค่อย ๆ ลดลงได้ค่อนข้างนุ่มนวล ใน MemGPT ยังใช้การสรุปแบบเรียกซ้ำโดยนัยทับบนการจัดการหน่วยความจำแบบชัดเจนทั้งหมดด้วย
    • มีเบาะแสเหลืออยู่มากกว่าที่คิดมาก ยิ่งไปกว่านั้น หน้าต่างบริบทมีขนาดราว 12 หน้าตามข้อความภาษาอังกฤษมาตรฐาน และพื้นที่ที่เสียไปกับ system prompt ก็ไม่ได้มากนัก
      ถ้าเคยทำงานที่น่าสนใจแม้เพียงเล็กน้อย เอาต์พุตจะถูกโน้มเอียงอย่างแรงโดยพรอมป์ต์ เนื่องจากมีเพียงตัวอย่างเดียวคือเอาต์พุต/ประวัติก่อนหน้า จึงสูญเสียข้อมูลบางส่วนแทนที่จะได้การแจกแจงความน่าจะเป็นที่ราบรื่น และเพราะอินพุตหลายแบบอาจแมปไปยังเอาต์พุตเดียวกันได้ จึงสูญเสียข้อมูลอีกบางส่วน
      แต่พรอมป์ต์ในโลกจริงมักเป็นถ้อยคำที่ง่ายและสั้นที่สุดเท่าที่นึกออกเพื่อให้ได้ผลลัพธ์ที่ต้องการ ดังนั้นถ้า LLM ประเมินพรอมป์ต์นั้นได้ การตีความบริบทที่ขาดหายไปก็น่าจะถูกต้องพอสมควร กล่าวคือ ข้อมูลจำนวนมากที่ดูเหมือนหายไปยังคงอยู่ในเอาต์พุตของ LLM และแม้บริบทเก่าจะถูกดันออกไป ปริมาณข้อมูลที่สูญเสียในครั้งเดียวก็ไม่ได้มากเกินไป
    • เหตุผลที่ ChatGPT มีประสิทธิภาพลดลงคือมันไม่ได้ทำอะไรเป็นพิเศษเพื่อขยายหน่วยความจำออกนอกความยาวบริบท
      มีเทคนิคง่าย ๆ มากมายในการทำหน่วยความจำแบบสูญเสียข้อมูล ตัวอย่างเช่น วิธี average pooling โทเคนแบบที่ sentence transformers ใช้ ผมไม่ค่อยแน่ใจว่าทำไมวิธีนี้ถึงไม่ค่อยถูกใช้ในการบีบบริบทจำนวนมากให้เป็นพรอมป์ต์ ที่จริงมันทำหน้าที่เป็น หน่วยความจำระยะกลาง ได้
    • ไม่มีใครรู้ว่าโมเดลปิดจริง ๆ แล้วทำอะไร แต่จาก prompt attack บางอย่าง ดูเหมือนว่าพวกมันจะใช้ การสรุปแบบเรียกซ้ำ นอกเหนือจากสิ่งที่กล่าวถึงในเธรดนี้ด้วย
    • ตามความรู้สึกของผม เหมือนมันจะตัดโทเคนที่เก่าที่สุดในการสนทนาออกเท่าที่จำเป็นขั้นต่ำ เพื่อให้อยู่ใต้ขีดจำกัดโทเคน การเสื่อมลงไม่ได้เหมือนกับว่าการสนทนามี หน่วยความจำระยะกลาง
  • จำชื่อไม่ได้ แต่มี ภาษาโปรแกรมเชิงลึกลับ อยู่แล้วที่สั่งคำสั่งได้แบบไม่เสถียร ถ้าออกแบบโปรแกรมอย่างระมัดระวัง ก็ทำให้ลำดับคำสั่งถูกรันด้วยความน่าเชื่อถืออย่าง 99%, 99.9% ได้

    • น่าจะเป็น Java2000
      อีก 20 ปีต่อมา แนวทางเดียวกันนี้ถูกทำให้แพร่หลายในสายโครงสร้างพื้นฐานโดยไม่ประชดประชัน ภายใต้ชื่อ “chaos engineering
    • คล้าย Malbolge อยู่บ้าง แต่ดูเหมือนจะไม่เหมือนกันเสียทีเดียว https://en.m.wikipedia.org/wiki/Malbolge
  • อัปเดต: เพิ่งเปิดตัว แชตบอต Discord แบบถาวร ที่สร้างบน MemGPT ลองใช้ได้ที่นี่: https://discord.gg/9GEQrxmVyE
    จากโค้ดบน GitHub สามารถรันเดโมแชตบอตในเครื่องได้ รวมถึงเดโมบอตถาม-ตอบเอกสารที่ให้ถาม MemGPT เกี่ยวกับเอกสาร API ได้ด้วย

  • ผมคิดว่าข้อจำกัดใหญ่ที่สุดของ LLM คือ หน้าต่างบริบท ความสามารถในการให้เหตุผลที่ยอดเยี่ยมก็มักติดข้อจำกัดของหน้าต่างบริบทในกรณีใช้งานจริง

    • ใช่ หวังว่าเทคนิคที่แนะนำที่นี่จะช่วยให้คิดแนวทางออกแบบ แชตบอตแบบถาวร ได้
  • เห็นด้วยกับคำอธิบายที่ว่า การสรุปแบบเรียกซ้ำเป็นวิธีง่าย ๆ ในการจัดการหน้าต่างบริบทที่ล้น แต่โดยเนื้อแท้แล้วมีการสูญเสียข้อมูล และสุดท้ายจะสร้างช่องโหว่ใหญ่ในหน่วยความจำของระบบ
    แต่ MemGPT ก็ทำสิ่งเดียวกันและมีปัญหาเดียวกัน ต่างกันแค่นิดหน่อยตรงที่แทนที่จะสรุปทุกอย่างแบบเรียกซ้ำ มันเลือกค้นประวัติแล้วสร้างขึ้นมาใหม่ในแต่ละคำขอ ไอเดียนี้เจ๋ง
    แต่ผมยังสงสัย แนวทางนี้พึ่งพาสมมติฐานพื้นฐานว่า บริบทเดิมเป็น บริบทที่สรุปได้ด้วยเอนโทรปีต่ำ และคำถามขึ้นอยู่กับประวัติเพียงบางส่วน
    สำหรับแชตหรือกรณีอย่าง “ตอบคำถามจากชุดเอกสารขนาดใหญ่” อาจจะถูกต้อง แต่ในกรณีอย่างการสร้างโค้ด ซึ่งบริบทอัดแน่นด้วยข้อมูลที่ทิ้งไม่ได้ เช่น คำนิยาม API บางอย่าง และต้องใช้บริบทกว้าง ๆ อย่างคำนิยาม API จำนวนมาก สมมติฐานทั้งสองข้อล้วนผิด
    โครงสร้างและการใช้งานน่าสนใจ และเดโมก็ยอดเยี่ยม แต่เสียดายที่งานวิจัยเกี่ยวกับการสรุปเหล่านี้ไม่ยอมรับข้อจำกัดพื้นฐานของแนวทางนี้

    • ขอบคุณที่อ่านบทความ เพื่อไม่ให้เกิดความเข้าใจผิด ขอชี้แจงว่า การสรุปแบบเรียกซ้ำเป็นเพียงส่วนหนึ่งของการจัดการหน่วยความจำของ MemGPT เท่านั้น
      อย่างที่บอก คิวการสนทนาของ MemGPT ถูกจัดการด้วยการสรุปแบบเรียกซ้ำ เช่นเดียวกับงานวิจัยก่อนหน้าและการใช้งานแชตบอตจำนวนมาก แต่ยังมี หน่วยความจำของ LLM ในพื้นที่ “คงที่” ที่อ่าน/เขียนได้ ซึ่งไม่เกี่ยวกับการสรุปแบบเรียกซ้ำ และในบทความเรียกสิ่งนี้ว่า “บริบทการทำงาน”
      ดังนั้น MemGPT จึงเข้าถึงได้ทั้งสรุปแบบเรียกซ้ำที่สร้างอัตโนมัติ และบริบทการทำงานที่ MemGPT ดูแลให้อัปเดตอยู่เสมออย่างจริงจัง
      ทั้งสองอย่างนี้ยังแยกจากบริบทภายนอกของ MemGPT ที่ถูกนำเข้ามาในคิวการสนทนาด้วยการเรียกฟังก์ชันด้วย ในทุกตัวอย่าง การอ่านบริบทภายนอกไม่ได้ถูกบีบอัด และทำเป็นรายหน้าโดยไม่มีการสรุป
      เมื่อการสรุปคิวถูกทริกเกอร์ MemGPT จะได้รับการแจ้งเตือนจากระบบ ดังนั้นถ้าต้องรักษารายละเอียดบางอย่างจากคิวการสนทนาไว้ ก็สามารถเขียนลงในบริบทการทำงานก่อนที่จะถูกลบหรือถูกสรุปได้
      ในตัวอย่างเอเจนต์สนทนา บริบทการทำงานใช้เก็บข้อเท็จจริงสำคัญเกี่ยวกับผู้ใช้และเอเจนต์ เพื่อรักษาบทสนทนาให้สอดคล้องกัน บริบทการทำงานจะถูก LLM เห็นอยู่เสมอ จึงไม่จำเป็นต้องค้นหาแยกต่างหาก
      ในงานถาม-ตอบเอกสาร บริบทการทำงานสามารถใช้ติดตามงาน/คำถามปัจจุบันและความคืบหน้าได้ สำหรับคำถามที่ซับซ้อน มันช่วยให้ MemGPT ติดตามรายละเอียดอย่างการค้นหาก่อนหน้าและคำขอหน้าก่อนหน้าได้