สะพานแชท
สะพานแชททำให้ผลิตภัณฑ์แชทภายนอก — วันนี้คือ Slack — เป็นช่องทางระดับแรกสู่ เวิร์กสเปซของ Control Center กล่าวถึงบอทแล้วเอเจนต์ก็ตื่นขึ้น ตอบกลับในเธรด Slack แล้วบทสนทนาก็ดำเนินต่อ พิมพ์คำสั่งสแลชแล้วตั๋วงานก็ถูกเปิด เบื้องหลังคือสเปซ ทรานสคริปต์ ตั๋วงาน และการระบุที่มา ชุดเดียวกับที่แอปเดสก์ท็อปใช้ แชทคือ พื้นผิว บนเวิร์กสเปซ ไม่ใช่สำเนาของมัน
Slack เป็นผู้ให้บริการรายเดียวที่พร้อมส่งมอบ ไม่มีการใช้งาน Discord, Telegram, Teams หรือ Matrix ที่ไหนในผลิตภัณฑ์นี้ ฟีเจอร์นี้เขียนแบบไม่ผูกกับผู้ให้บริการ โดยเจตนา — การเพิ่มผลิตภัณฑ์ตัวที่สองคือค่า enum หนึ่งค่า อะแดปเตอร์หนึ่งตัว และ ปลั๊กอินหนึ่งตัว — แต่วันนี้ “แชท” หมายถึง Slack
มีสองพื้นผิวที่ครอบคลุมเรื่องนี้ และมันเป็นของคนละกลุ่มคน การเชื่อมเวิร์กสเปซกับ Slack และการปรับแต่งบอทเป็นงานของ แอดมิน ภายใต้ การตั้งค่า → เวิร์กสเปซ → ทั่วไป การลิงก์บัญชีแชทของคุณเองเข้ากับตัวตน Control Center ของคุณเป็นงานของ สมาชิก ภายใต้ การตั้งค่า → เวิร์กสเปซ → โปรไฟล์และตัวตน
สามการตัดสินใจกำหนดรูปร่างของฟีเจอร์ทั้งหมด: การเชื่อมต่อวิ่งไปในทิศทางใด, อะไรเป็นตัวให้สิทธิ์กับข้อความที่มาจากภายนอก และ ความรู้เฉพาะผลิตภัณฑ์ ได้รับอนุญาตให้อยู่ที่ใด
ขาออกโดยเจตนา
หัวข้อที่มีชื่อว่า “ขาออกโดยเจตนา”สะพานไม่เคยรอรับจากผู้ให้บริการเลย Slack ถูกเข้าถึงผ่าน Socket Mode: เซิร์ฟเวอร์ ขอ socket URL จาก Slack แล้วเชื่อมออกไป จากนั้นจึงรับการกล่าวถึง ข้อความส่วนตัว และคำสั่งสแลชผ่านการเชื่อมต่อนั้น
ผลที่ตามมาคือประเด็นสำคัญ แล็ปท็อปที่อยู่หลัง NAT เซิร์ฟเวอร์ที่บ้านที่ไม่มีโดเมน เครื่องที่ย้ายไปมาระหว่างเครือข่าย — ทั้งหมดรันสะพานได้โดยไม่มีพอร์ตขาเข้า ไม่มีทันเนล ไม่มีใบรับรอง TLS และไม่มี URL สาธารณะให้หมุนเมื่อมันเปลี่ยน ไม่มีปลายทาง webhook ให้ต้องรักษาความปลอดภัย เพราะไม่มีปลายทาง webhook อยู่เลย เมื่อ Control Center ประกอบนิยามของแอป มันบังคับใช้ Socket Mode และตัด request URL ใด ๆ ออก เพราะแอปที่ตั้งค่าไว้สำหรับทั้งสองอย่างจะเป็นแอปที่ทำงานได้ครึ่งเดียว
ราคาที่ต้องจ่ายคือการเชื่อมต่อที่ต้องรักษาให้มีชีวิต ซึ่งเป็นงานของเซิร์ฟเวอร์: การเชื่อมต่อใหม่คือ exponential backoff พร้อม jitter ที่จำกัดไว้ที่ 30 วินาที การหมุน socket ที่ผู้ให้บริการเป็นฝ่ายเริ่มจะเชื่อมต่อใหม่โดยไม่ทำให้ backoff นั้นเพิ่มระดับ และ ข้อมูลรับรองที่ถูกปฏิเสธ ถือเป็นจุดสิ้นสุด — การลองโทเคน ที่ถูกเพิกถอนซ้ำไม่รู้จบมีแต่จะได้ขีดจำกัดอัตรากลับมา สะพานจึงหยุดและรอโทเคนใหม่ พร้อมรายงานข้อผิดพลาดของผู้ให้บริการเองตามตัวอักษรในหน้าตั้งค่า
เวิร์กสเปซที่ไม่มีแอปแชทไม่มีค่าใช้จ่ายใด ๆ เลย: ไม่มี socket ไม่มีตัวจับเวลา ไม่มีการรับส่งข้อมูล และทั้งหมดเริ่มทำงาน หลัง แบนเนอร์พร้อมใช้งานของเซิร์ฟเวอร์ เพราะแอปแชทที่ตอบช้าต้องไม่ทำให้การบูตล่าช้าเด็ดขาด
สมาชิกภาพให้สิทธิ์ ไม่ใช่การถือโทเคน
หัวข้อที่มีชื่อว่า “สมาชิกภาพให้สิทธิ์ ไม่ใช่การถือโทเคน”คนที่ติดตั้งแอปไม่ใช่คนที่ส่งข้อความ ดังนั้นทุกเหตุการณ์ขาเข้าจะแปลงเป็น Principal ก่อนที่อะไรจะเกิดขึ้น และมันจะปฏิเสธไว้ก่อนพร้อมคำอธิบาย:
- บัญชีแชทที่ยังไม่ได้ลิงก์ จะได้รับคำบอกวิธีลิงก์ ในเธรด Slack ที่มันเขียนเข้ามา
- บัญชีที่ลิงก์แล้วซึ่งผู้ใช้ไม่ใช่สมาชิก ของเวิร์กสเปซนี้ จะได้รับคำบอกให้ ขอคำเชิญจากแอดมิน
- สมาชิกที่มีบทบาทอ่านอย่างเดียว (
viewer,guest) จะได้รับคำบอกว่าบทบาท ของตนเริ่มงานไม่ได้
ไม่มีกรณีใดในนี้ที่ดำเนินต่อ ข้อความแชทไม่เคยถูกระบุที่มาให้กับคนที่ไม่ได้ส่งมัน — นั่นคือสิ่งที่ทำให้ร่องรอยการตรวจสอบ ขีดจำกัดอัตราต่อ Principal และผู้รายงานตั๋วงาน ซื่อสัตย์ ดูการทำงานร่วมกันแบบหลายคน — ตัวตน สมาชิกภาพ และการปรากฏตัว สำหรับโมเดลสมาชิกภาพที่สิ่งนี้อาศัยอยู่
การลิงก์คือการระบุตัวตน ไม่ใช่ การให้สิทธิ์เข้าถึง สมาชิกภาพถูกตรวจซ้ำใน ทุกเหตุการณ์ ลิงก์ของคนที่ถูกนำออกไปแล้วจึงแปลงเป็นการปฏิเสธ แทนที่จะเป็น สิทธิพิเศษเดิมของเขา มีสองเส้นทางที่สร้างลิงก์ได้: รหัสใช้ครั้งเดียวอายุสั้น ที่สมาชิกพิมพ์ในแชท หรือการจับคู่อัตโนมัติกับอีเมล ที่ผ่านการยืนยัน ของ ผู้ให้บริการ — และเส้นทางอีเมลยังต้องให้ผู้ใช้ที่ถูกจับคู่เป็นสมาชิกอยู่แล้ว คนแปลกหน้าที่ที่อยู่ของเขาบังเอิญมีอยู่บนเซิร์ฟเวอร์จึงลิงก์กับอะไรไม่ได้เลย
รหัสเหล่านี้ถูกเก็บไว้ในหน่วยความจำโดยเจตนา โดยมีอายุ 15 นาที การเก็บมันไว้ อย่างถาวรจะสร้างแถวคงทนที่รูปร่างเหมือนข้อมูลรับรองให้กับสิ่งที่ตั้งใจให้ระเหยหาย และการรีสตาร์ตเซิร์ฟเวอร์ที่ทำให้รหัสที่ค้างอยู่ทั้งหมดใช้ไม่ได้คือพฤติกรรม ที่ถูกต้อง ไม่ใช่การถดถอย — สมาชิกก็กด “ลิงก์” อีกครั้ง
การปฏิเสธจะถูกตอบกลับ ในเธรด Slack ที่ข้อความนั้นเปิดขึ้น ในฐานะคำตอบจริง คำตอบในเธรดจะติดป้ายให้ข้อความที่มันตอบ ไปถึงคนคนเดียวที่ต้องการมัน และยังกัน ข้อความ “คุณยังไม่ได้ลิงก์” ออกจากช่องเองด้วย การโพสต์ข้อความเป็นความสามารถเดียว ที่ผู้ให้บริการทุกรายมี คำอธิบายจึงไม่ขึ้นอยู่กับฟีเจอร์ที่แอปอาจไม่มี
ที่มาและปัญหาเสียงสะท้อน
หัวข้อที่มีชื่อว่า “ที่มาและปัญหาเสียงสะท้อน”สะพานที่สะท้อนทั้งสองทางจะวนกลับไม่รู้จบ เว้นแต่มีอะไรสักอย่างแยกสองทิศทาง
ออกจากกัน ข้อความทุกฉบับที่สะพานนำเข้ามาจะถูกประทับด้วย metadata['chat'] —
ผู้ให้บริการ ทีม บทสนทนา เธรด ข้อความ และผู้ส่ง การสะท้อนขาออกจะข้ามข้อความใด ๆ
ที่มีการประทับนั้น
กฎข้อเดียวนี้คือสิ่งที่ทำให้การสะท้อนสองทางปลอดภัย: ข้อความของมนุษย์ที่พิมพ์ใน Control Center จะถูกส่งต่อไปยังเธรดที่ลิงก์ไว้ (นำหน้าด้วยชื่อผู้เขียน) ส่วนข้อความ ที่ มาจาก แชทจะหยุดอยู่ตรงที่มันเข้ามา
สิ่งที่ข้ามออกไปนั้นแคบโดยเจตนา คำตอบ ของเอเจนต์ถูกส่งต่อเป็นข้อความแชท
ธรรมดา ความคิดสั้น ๆ อาจปรากฏบนแถว Thinking… ของการ์ด เอาต์พุตของเครื่องมือ
เป็นกำแพง diff และอยู่ใน Control Center ซึ่งเป็นที่ที่คำตอบที่ถูกตัดทอนชี้ไปด้วย
การ์ดรายงานงาน ส่วนข้อความยังคงเป็นข้อความ
หัวข้อที่มีชื่อว่า “การ์ดรายงานงาน ส่วนข้อความยังคงเป็นข้อความ”ในที่ที่ผู้ให้บริการเรนเดอร์มันได้ หนึ่งเทิร์นจะพก การ์ดงานหนึ่งใบ ที่ถูกแก้ไข ในที่ตลอดเวลาที่เทิร์นนั้นรันอยู่ และวางอยู่เหนือคำตอบที่มันอธิบาย
การ์ดคือแผนเดียวที่จัดกลุ่มไว้ ไม่ใช่ย่อหน้าที่บดรวมกัน Slack ต่อ details และ
output บนงานเดียวกัน รายละเอียดของแถวจึงถูกส่งครั้งเดียว (ความคิดบน Thinking…)
และ output จะไม่ถูกสตรีมเลย การตั้งค่าเป็นแถวเดียวที่ชื่อถูกแทนที่
(Working on it…, Cloning …) การใช้เหตุผลเพิ่มแถว Thinking… เครื่องมือ
แต่ละตัวมีแถวของตัวเอง (Read lib/main.dart) คำตอบเป็นข้อความธรรมดาใต้การ์ด —
มุมมองแผนของ Slack อ่านมันจาก markdown ที่ผนวกเข้ามาทีหลัง ไม่ใช่จากก้อนที่ปน
เข้าไปในงาน ไม่มีอะไรอื่นอีก: ไม่มีเอาต์พุตของเครื่องมือ และมีแค่อาร์กิวเมนต์ของ
เครื่องมือจากรายการที่อนุญาตสั้น ๆ เพราะอาร์กิวเมนต์ของเครื่องมือที่ไม่รู้จัก
อาจเป็นเนื้อไฟล์ทั้งไฟล์ และแถวหนึ่งแถวก็ยาวแค่หนึ่งบรรทัด
การ์ดยังครอบคลุมช่วงรอ ก่อน เทิร์นด้วย การกล่าวถึงครั้งแรกสร้างบทสนทนา และ
การสร้างมันโคลนทุกรีโปที่เอเจนต์จะทำงานด้วย — ซึ่งบนรีโปจริงคือหลายนาทีที่เอเจนต์
ยังไม่ถูกถามอะไรเลย และเธรดก็ดูเหมือนบอทเพิกเฉยต่อคำขอ การ์ดจึงเปิดทันทีที่
การกล่าวถึงนั้นถูกตอบรับ (Working on it…) จากนั้นแถวการตั้งค่านั้นอัปเดตด้วย
คำเดียวกับที่เดสก์ท็อปแสดง — Cloning acme/widgets…, Setting up Reviewer…,
Starting the agent… — แล้วจึงมีแถว Thinking… ทันทีที่เอเจนต์เริ่มใช้เหตุผล
ตามด้วยหนึ่งแถวต่อเครื่องมือหนึ่งตัว การ์ดเดียว ข้อความเดียว ตั้งแต่ “ฉันได้ยินคุณ”
ไปจนถึงคำตอบที่เป็นข้อความธรรมดาอยู่ข้างใต้ การตั้งค่าจะถูกรายงานเฉพาะที่ที่มีคน
ในแชทกำลังรออยู่เท่านั้น: บทสนทนาที่กำลังเตรียมอยู่ในแอป หรือบทสนทนาที่ค้างอยู่
และถูกรื้อฟื้นตอนเซิร์ฟเวอร์บูต จะจัดเตรียมโดยไม่มีการ์ดเลย
มันพกสิ่งเดียวที่แชทให้ผู้อ่านไม่ได้: ลิงก์ View in Control Center ไปยัง
บทสนทนาที่อยู่เบื้องหลังคำตอบ ผลิตภัณฑ์แชทยอมรับ http(s) ในลิงก์และไม่รับ
อย่างอื่น ปุ่มจึงชี้ไปยังหน้าเล็ก ๆ ที่เซิร์ฟเวอร์นี้ให้บริการ ซึ่งพาเบราว์เซอร์
เด้งไปยังลิงก์ control-center:// ของแอปเดสก์ท็อป หน้านั้นอ่านอะไรไม่และแปลง
อะไรไม่ — id ใน URL ของมันถูกสะท้อนเข้าไปใน deep link และที่อื่นเท่านั้น — และ
เซิร์ฟเวอร์ที่ไม่มี URL สาธารณะที่เข้าถึงได้ก็แค่สร้างการ์ดที่ไม่มีปุ่ม แทนที่จะ
เป็นการ์ดที่พัง
การ์ดเป็นความสามารถเหมือนอย่างอื่น ผู้ให้บริการที่ไม่มีการ์ดก็ทำงานเหมือนเดิม
ทุกประการ คือมีแต่ข้อความ และผู้ให้บริการที่ปฏิเสธการ์ดตอนเรียกใช้ก็ยังคงสตรีม
ของมันไว้: คำตอบมีศักดิ์สูงกว่าการ์ดที่บรรยายมันเสมอ เมื่อปิดสตรีมทั้งหมด การ์ด
ที่เสร็จแล้วจะไปกับข้อความเดียวที่โพสต์แทน ตั๋วงานที่ถูกเปิดก็ได้รับการดูแล
แบบเดียวกัน — การยืนยันจาก /cc ticket คือการ์ดที่เสร็จสมบูรณ์ซึ่งเหตุผล
ในการมีอยู่คือลิงก์ไปยังตั๋วงานที่เพิ่งสร้าง
ความสามารถถูกเจรจา แล้วจึงถูกจดจำ
หัวข้อที่มีชื่อว่า “ความสามารถถูกเจรจา แล้วจึงถูกจดจำ”ผลิตภัณฑ์แชทต่างกันที่สิ่งที่เรนเดอร์ได้ สะพานจึงเขียนขึ้นโดยอิงพื้นผิวที่สมบูรณ์ ที่สุด — คำตอบที่ค่อย ๆ งอกขึ้นสด ๆ ในเธรด สถานะ “is thinking…” ที่อยู่ชั่วครู่ เธรดที่มีชื่อ และคำตอบชั่วคราวต่อคำสั่งสแลช — แล้วลดระดับลงทีละความสามารถ ผู้ให้บริการที่ไม่มีสิ่งเหล่านี้เลยก็ยังทำงานได้ คำตอบก็แค่มาเป็นข้อความเดียว
การโฆษณาความสามารถไม่ใช่การให้สัญญา คำตอบแบบสตรีมของ Slack ต้องใช้ฟีเจอร์ ของแพ็กเกจแบบเสียเงิน และ Slack ปฏิเสธตอนเรียกใช้เท่านั้น การปฏิเสธที่ถูกทำ เครื่องหมายว่าถาวรจะถูกจดจำไว้ ตลอดอายุการเชื่อมต่อ: สะพานหยุดขอและโพสต์ คำตอบแบบเต็มตั้งแต่นั้นเป็นต้นไป และหน้าตั้งค่าก็บอกไว้ตรง ๆ เพราะคำถาม “คำตอบของฉันหยุดสตรีม” ควรตอบได้โดยไม่ต้องอ่านบันทึก การ์ดงานก็ถูกทิ้ง แบบเดียวกันหาก Slack ปฏิเสธ
ขีดจำกัดทุกข้อเป็นของผู้ให้บริการ ไม่ใช่ของรีเลย์: เพดานข้อความ เพดานก้อนสตรีม และว่าสตรีมต้องมีจุดยึดเธรดหรือไม่ ล้วนถูกประกาศโดยอะแดปเตอร์ และคำตอบยาว จะถูกแบ่งที่ขอบย่อหน้า บรรทัด หรือคำ แทนที่จะแบ่งกลางคำ
สะพานเดียว หนึ่งอะแดปเตอร์ต่อหนึ่งผลิตภัณฑ์
หัวข้อที่มีชื่อว่า “สะพานเดียว หนึ่งอะแดปเตอร์ต่อหนึ่งผลิตภัณฑ์”ทุกสิ่งที่มีรูปร่างเป็นผลิตภัณฑ์อาศัยอยู่หลังพอร์ต แกนกลางทั่วไปรู้จัก markdown
บทสนทนาแชท เธรดแชท และสมาชิก แต่มันไม่รู้อะไรเกี่ยวกับซองข้อมูลของ Slack,
mrkdwn หรือ gateway intents สามชิ้นส่วนทำให้สิ่งนี้ทำงานได้:
- อะแดปเตอร์ ทำให้ผลิตภัณฑ์หนึ่งเข้าสู่รูปแบบมาตรฐาน: ทรานสปอร์ตของมัน
การเรียก API ของมัน โคเดกข้อความของมัน และความประหลาดของซองข้อมูลของมัน
ของ Slack ให้บทเรียนที่ดี — การกล่าวถึงในช่องมาถึงสองครั้ง (เป็น
app_mentionและ เป็นmessage) และชนิดย่อยของข้อความส่วนใหญ่เป็นส่วนประดับมากกว่า จะเป็นคำขอใหม่ ทั้งสองอย่างถูกแปลงในอะแดปเตอร์ แกนกลางจึงไม่เคยรู้ว่า Slack ส่งซ้ำ - เดสคริปเตอร์ คือรูปร่างสาธารณะของผู้ให้บริการ: ต้องใช้ข้อมูลรับรองอะไร รูปแบบของมันเป็นอย่างไร URL ใดช่วยให้ผู้ใช้หามันเจอ ทำอะไรได้บ้าง และแอปของมัน สร้างหรือแก้ไขจากที่นี่ได้หรือไม่ การ์ดการตั้งค่า ไดอะล็อกเชื่อมต่อ และ การตรวจสอบอาร์กิวเมนต์ ล้วน ถูกสร้าง ขึ้นจากมัน — ไคลเอนต์ส่งกลับผู้ให้บริการ หนึ่งรายพร้อมแมปที่ใช้ field id เป็นคีย์
- ปลั๊กอิน คือการประกอบฝั่งเซิร์ฟเวอร์: ข้อมูลรับรองกลายเป็นการเชื่อมต่อ ที่ผ่านการยืนยันได้อย่างไร อะแดปเตอร์ถูกสร้างขึ้นอย่างไร และแอปฝั่งผู้ให้บริการ ถูกจัดการอย่างไร
การเพิ่มผลิตภัณฑ์หนึ่งตัวจึงเป็นค่า enum หนึ่งค่า อะแดปเตอร์หนึ่งตัว และปลั๊กอิน หนึ่งตัว ไม่มี op RPC ใหม่ ไม่มีการเปลี่ยนสคีมา ไม่มีการเปลี่ยนไคลเอนต์ — และ ไคลเอนต์ยังซื่อสัตย์ เพราะฟิลด์ที่มันไม่เคยได้ยินชื่อก็ยังเรนเดอร์ด้วยป้ายชื่อ ที่เซิร์ฟเวอร์ส่งมา
สองรายละเอียดกันไม่ให้สิ่งนามธรรมนี้รั่วขึ้นไปด้านบน ขั้นตอนการจัดการแอปที่ ผู้ให้บริการไม่มี API ให้ (สร้างโทเคน ติดตั้งแอป ติดตั้งใหม่หลังเปลี่ยนสิทธิ์) ถูกส่งกลับเป็น ขั้นตอนที่มีชื่อพร้อมลิงก์ของตัวเอง หน้าจอตั้งค่าให้เสร็จจึง แสดงมันได้โดยไม่ต้องรู้ว่าเป็นผู้ให้บริการรายใด และทุกคำแนะนำที่สะพานเขียน จะระบุชื่อผู้ให้บริการและคำสั่งที่แอปใช้จริง คำสั่งที่ถูกเปลี่ยนชื่อหรือผู้ให้บริการ รายที่สองจึงอ่านได้ถูกต้องโดยไม่ต้องมีสตริงใหม่
ข้อมูลรับรองอยู่ที่ไหน
หัวข้อที่มีชื่อว่า “ข้อมูลรับรองอยู่ที่ไหน”โทเคนแชทของเวิร์กสเปซหนึ่งอยู่ใน ไดเรกทอรีของเวิร์กสเปซนั้นเอง ข้าง ๆ ฐานข้อมูล
ของมัน — เป็น JSON ธรรมดาที่ <dataDir>/<workspaceId>/chat_credentials/<provider>.json
ไม่ได้อยู่ในฐานข้อมูล และจงใจไม่ให้อยู่ในคีย์เชนของระบบปฏิบัติการ ผลที่ตามมาสองข้อ
ที่หลงลืมได้ง่ายในภายหลัง: การลบเวิร์กสเปซจะลบไดเรกทอรีนั้นทิ้ง และโทเคนของมัน
ก็ไปด้วย และการนำออกหรือสำรองเวิร์กสเปซจะคัดลอก workspace.db ดังนั้นเวิร์กสเปซ
ที่ส่งต่อให้คนอื่นจะไม่มีโทเคนบอทที่ยังใช้งานได้อยู่ข้างใน ไฟล์นี้สืบทอดขอบเขต
ความเชื่อถือของระบบไฟล์ของโฮสต์ที่รันเซิร์ฟเวอร์ — อะไรก็ตามที่อ่านไดเรกทอรีข้อมูล
ได้ก็อ่านโทเคนบอทได้ ซึ่งเป็นขอบเขตเดียวกับที่ฐานข้อมูลทั้งหลายตั้งอยู่ข้างหลัง
หนึ่งไฟล์ต่อหนึ่งผู้ให้บริการ เขียนแบบอะตอมมิกและอ่านได้เฉพาะเจ้าของ: แอปที่ถูก เพิกถอนถูกลบด้วยการลบไฟล์เพียงไฟล์เดียว และไฟล์ที่เสียหายทำให้เสียผู้ให้บริการ รายเดียว ไม่ใช่ทั้งหมด ข้อมูลรับรองเดินทาง เข้า ผ่านการดำเนินการเชื่อมต่อ และไม่เคยออกมา — การอ่านสถานะตอบกลับด้วยเมทาดาทาของการเชื่อมต่อเท่านั้น
สิ่งที่จงใจไม่นำเสนอ
หัวข้อที่มีชื่อว่า “สิ่งที่จงใจไม่นำเสนอ”- การตั้งค่าแอปเชิงโครงสร้าง ทรานสปอร์ต, scopes และการสมัครรับเหตุการณ์ ถูกบังคับใช้ ไม่ได้เปิดให้ตั้งค่า แอปที่ปรับตั้งจนเงียบได้จากหน้าจอตั้งค่า คือตั๋วงานสนับสนุน ไม่ใช่ฟีเจอร์
- บทสนทนาบวกคำสั่งสแลช พื้นผิวของ Slack คือข้อความ คำตอบในเธรด และ คำสั่งสแลช
- แหล่งความจริงแหล่งที่สอง แชทไม่ใช่ที่ที่งานถูกเก็บ เธรด Slack คือสเปซ คำตอบคือทรานสคริปต์ ตั๋วงานคือตั๋วงาน — ทั้งหมดอยู่ในเวิร์กสเปซ เข้าถึงได้ จากทุกไคลเอนต์
ดูเพิ่มเติม
หัวข้อที่มีชื่อว่า “ดูเพิ่มเติม”- การทำงานร่วมกันแบบหลายคน — ตัวตน สมาชิกภาพ และการปรากฏตัว: เหล่า Principal และบทบาทที่สะพานแปลงผ่าน
- เวิร์กสเปซและการแยกโดเมน: เหตุใดลิงก์และข้อมูลรับรองจึงแยกตามเวิร์กสเปซ
- โมเดลเอเจนต์: อะไรตื่นขึ้นเมื่อมีการกล่าวถึงเข้ามา
- ตั๋วงานและการมอบหมาย:
/cc ticketเปิดอะไร - สถาปัตยกรรม: สะพานตั้งอยู่ตรงไหนระหว่างเซิร์ฟเวอร์กับไคลเอนต์
- เชื่อม Slack เข้ากับเวิร์กสเปซ
- ตั้งค่าการผสาน Slack
- เชื่อมบัญชี Slack ของคุณ
- ปรับแต่งแชทบอต
- การสนทนาบน PR: สามการตัดสินใจเดียวกัน ที่ทำขึ้นสำหรับ forge