Bỏ qua đến nội dung chính

Skill Issue: How We Used AI to Make Agents Actually Good at Supabase — Pedro Rodrigues, Supabase

TL;DR

  • "Kỹ năng" (skills) cung cấp một phương pháp có cấu trúc để các tác nhân AI truy cập thông tin tùy chỉnh và thực thi các quy trình làm việc lặp đi lặp lại, đặc biệt trong các nền tảng như Superbase, nhằm nâng cao hiệu suất hoạt động của chúng.
  • Chúng sử dụng khái niệm "tiết lộ dần dần" (progressive disclosure), cho phép tác nhân chỉ tải thông tin cần thiết ban đầu và trì hoãn việc tải ngữ cảnh sâu hơn cho đến khi thực sự cần, tối ưu hóa việc sử dụng tài nguyên và ra quyết định.
  • Kiểm thử "kỹ năng" được thực hiện thông qua "hệ thống đánh giá tự động" (evaluations hay eVals), một phương pháp không xác định (nondeterministic) để đánh giá hành vi và đầu ra của tác nhân, thường tuân theo các nguyên tắc phát triển dựa trên đánh giá (eval-driven development) như đề xuất của OpenAI.

progressive disclosure

feedback

refine skill

Agent

Skill — structured workflow

Surface info — load on demand

Deep context — load only when needed

Eval-driven dev — non-deterministic tests

Better agent behavior

Điểm chính

  • Cấu trúc Kỹ năng (Skills): Một "kỹ năng" là một thư mục bao gồm tệp skill.md (với front matter chứa namedescription bắt buộc) và các tệp tham chiếu tùy chọn (markdown, scripts như Bash/Python) để hỗ trợ các quy trình làm việc hoặc thông tin tùy chỉnh.
  • Tiết Lộ Dần Dần (Progressive Disclosure): Front matter của skill.md được tải vào ngữ cảnh của tác nhân trước tiên. Tác nhân sau đó quyết định có nên tải toàn bộ nội dung hoặc các tệp tham chiếu hay không, giúp quản lý ngữ cảnh hiệu quả.
  • So sánh Skills và MCP Tools: "Kỹ năng" cung cấp thêm ngữ cảnh và định nghĩa các quy trình làm việc cho tác nhân, đồng thời chạy scripts trong môi trường cục bộ. MCP tools phù hợp hơn cho các tích hợp với dịch vụ bên ngoài và thực thi ở server-side, không phụ thuộc vào môi trường cục bộ.
  • Kiểm thử Tự động với Hệ thống Đánh giá (Evaluations): "Kỹ năng" được kiểm thử bằng các evaluations (eVals), đây là các khung kiểm thử không xác định để đánh giá hành vi của LLM hoặc tác nhân, thường bao gồm input, expected output và phân tích lý luận cùng các lệnh gọi công cụ.
  • Khung Phát triển Dựa trên Đánh giá của OpenAI: Tuân theo quy trình có hệ thống: định nghĩa các số liệu/thước đo thành công, xây dựng kỹ năng, chạy các hệ thống đánh giá tự động, chấm điểm hiệu suất của tác nhân và lặp lại dựa trên kết quả.
  • Công cụ Khả năng Quan sát (Observability Tools): Các nền tảng như Brain Trust cải thiện khả năng quan sát bằng cách chạy eVals một cách có hệ thống và cung cấp cái nhìn toàn diện về hành vi của tác nhân trong các kịch bản đánh giá có kiểm soát.
  • Ứng dụng Thực tế: Buổi workshop sẽ trình bày cách xây dựng một kỹ năng để hướng dẫn tác nhân sửa lỗi cơ sở dữ liệu trong một ứng dụng đánh giá hiệu suất được xây dựng trên Supabase, sau đó là kiểm thử tự động bằng eVals.

Từ vựng

  • skill — kỹ năng (trong ngữ cảnh tác nhân AI)
  • AI tooling — công cụ AI
  • agent — tác nhân (AI)
  • DAX — trải nghiệm của tác nhân (tương tự DX nhưng cho AI agents)
  • evaluations (eVals) — hệ thống đánh giá tự động
  • progressive disclosure — tiết lộ dần dần
  • front matter — dữ liệu tiền xử lý (metadata ở đầu file markdown)
  • context — ngữ cảnh
  • nondeterministic — không xác định
  • observability tool — công cụ khả năng quan sát

Nội dung chi tiết

Giới thiệu Workshop và Diễn giả

Xin chào mọi người. Mọi người có hào hứng với hội nghị không? Tuyệt vời! Chúng ta có một khán phòng đầy ắp người ở đây. Tôi rất vui và vinh dự được trình bày buổi workshop khai mạc, hoặc một trong những buổi workshop khai mạc, hôm nay. Nếu mọi người đã để ý, tiêu đề có hơi khác một chút so với lịch trình. Về cơ bản, tôi đã đổi thương hiệu, nhưng chủ đề của buổi workshop vẫn giữ nguyên. Chúng ta đã chuyển từ "vấn đề kỹ năng" (skill issue) sang "nâng cao kỹ năng của bạn" (level up your skills). Tôi đã quyết định chuyển tiêu đề "vấn đề kỹ năng" sang bài phát biểu chính mà tôi sẽ trình bày vào ngày mai, nếu bạn có thời gian để tìm hiểu thêm về nội dung của bài phát biểu đó. Nhưng chủ yếu, buổi workshop này là những gì tôi đã làm trong hai tháng qua tại Superbase: viết các kỹ năng của riêng chúng tôi. Và ngày mai, tôi sẽ trình bày cách chúng tôi đưa điều này vào sản xuất thực tế và những bài học chúng tôi đã học được.

Đối với những ai đã chú ý kỹ hơn, có lẽ bạn đã nhận thấy rằng tôi đang chạy bộ slide này trên localhost. Một số bạn đã nhận ra điều này. Đây hoàn toàn không phải là sự trùng hợp ngẫu nhiên. Về cơ bản, tôi đã vip coded (mã hóa nhanh) bài thuyết trình. Vì vậy, nếu bạn thấy điều gì đó không ổn, đó không phải lỗi của tôi mà là do clo (từ nghe không rõ, có thể là "code" hoặc "cloned"). Nhưng để bạn tin tôi, bạn có thể thấy rằng – hoặc bạn sẽ phải là một "phù thủy Google Slides" thực sự để bật được dark mode. Thật lòng mà nói, tôi thích bố cục này hơn. Vì vậy, tôi nghĩ chúng ta sẽ sử dụng dark mode ở đây. Nếu có bất kỳ người hâm mộ light mode nào hoặc đa số phòng thích light mode, tôi rất sẵn lòng chuyển lại, nhưng bây giờ, hãy để nó như thế này.

Trước khi bắt đầu workshop, tôi xin tự giới thiệu một chút. Tên tôi là Pedro. Tôi đến từ Lisbon, Bồ Đào Nha, và tôi làm việc tại Superbase với tư cách là kỹ sư AI tooling. Về cơ bản, công việc hàng ngày của tôi là suy nghĩ về cách chúng tôi có thể làm cho Superbase trở nên thân thiện với tác nhân nhất có thể và cải thiện trải nghiệm của tác nhân. Chắc hẳn bạn đã nghe nói về trải nghiệm của nhà phát triển (developer experience - DX). Chúng tôi tập trung nhiều hơn vào DAX, là điều tương tự nhưng dành cho các tác nhân. Trong workshop này, chúng ta sẽ nói một chút về kỹ năng (skills), bởi vì về cơ bản, đó là cách chúng tôi đã cải thiện hiệu suất của các tác nhân xung quanh một sản phẩm như Superbase, hoặc một công ty như Superbase có nhiều sản phẩm. "Bí quyết" (secret sauce) của chúng tôi về cơ bản là kỹ năng. Vì vậy, chúng ta sẽ đi sâu vào cách viết một kỹ năng, cách kiểm thử nó trước tiên thủ công và sau đó là cách tự động hóa kiểm thử bằng các hệ thống đánh giá tự động (evaluations).

Kỹ năng: Khái niệm và Cấu trúc

Để bắt đầu, bao nhiêu bạn đã nghe nói về kỹ năng? Tuyệt vời, gần như tất cả mọi người. Vì vậy, những gì tôi sắp nói có lẽ không phải là tin tức mới đối với bạn. Kỹ năng về cơ bản là các thư mục chứa lời nhắc và các tệp để bạn chạy các quy trình làm việc lặp đi lặp lại hoặc cung cấp thông tin tùy chỉnh, về cơ bản là thông tin tùy chỉnh, cho tác nhân của bạn hoặc cung cấp một bộ công cụ mới, dưới dạng scripts. Vì vậy, có một chút hiểu lầm về kỹ năng. Thông thường, tệp skill.md – tệp chính – chiếm spotlight. Nhưng kỹ năng thực sự có thể hơn là chỉ một tệp chính, phải không? Tệp chính về cơ bản là một tệp markdown có tên skill.md, nơi về cơ bản chứa thông tin chính về kỹ năng. Nó được cấu tạo bởi front matter ở phía trên, về cơ bản có thể có nhiều trường nhưng hai trường bắt buộc là name (tên), về cơ bản xác định kỹ năng, và sau đó là description (mô tả), cho tác nhân biết kỹ năng đó làm gì.

skill.md và Khái niệm Progressive Disclosure

Điều chính mà kỹ năng mang lại, mà các công cụ như MCP không có, là khái niệm progressive disclosure (tiết lộ dần dần). Progressive disclosure về cơ bản là khi tác nhân, hoặc tất cả thông tin về một chủ đề, không được tải trực tiếp vào ngữ cảnh. Thay vào đó, bạn chỉ tải chính xác lượng thông tin cho phép tác nhân chọn tải phần còn lại của thông tin khi nó thực sự cần. Vì vậy, trong trường hợp này, tệp skill.md được thiết kế như vậy. Front matter sẽ được tải trước vào ngữ cảnh của tác nhân, chứ không phải nội dung của tệp. Điều này hoạt động như một phong bì. Vì vậy, tác nhân biết từ description kỹ năng đó làm gì và khi nào nó nên tải phần còn lại của thông tin. Bên trong tệp này, bạn cũng có thể tham chiếu các tệp khác. Thông thường, các tệp khác này có thể là tệp markdown hoặc scripts (Bash, Python, bất cứ thứ gì bạn muốn tham chiếu).

Về các tệp tham chiếu, bạn thường đặt chúng bên trong một thư mục reference. Và chúng cung cấp thêm thông tin. Bạn có thể nghĩ về một kỹ năng ở định dạng này như một cuốn sách. Tệp skill.md bạn có thể nghĩ nó như một mục lục nâng cao (index on steroids) bởi vì ngoài việc có các liên kết đến các tệp khác, bạn có thể coi chúng là các trang của cuốn sách hoặc các chương khác. Bạn sẽ có thông tin tùy chỉnh và sau đó cũng tham chiếu đến các tệp khác. Các tệp tham chiếu không có gì đặc biệt. Chúng về cơ bản giống như một tệp markdown thông thường. Bạn có thể nghĩ nó tương tự như tệp skill.md nhưng thay vì là tệp chính, nó là tệp được tham chiếu. Bạn cũng có thể, thú vị thay, tham chiếu các tệp bên trong các tệp tham chiếu. Vì vậy, bạn về cơ bản có thể tạo một đồ thị (graph) từ một kỹ năng.

So sánh SkillsMCP Tools

Và đối với scripts, tôi thực sự đã nói về cách MCPkỹ năng khác nhau. Và chúng ta về cơ bản đang so sánh "táo với cam" khi nói đến MCPkỹ năng. Một trong những hiểu lầm, hiện tại có lẽ đã được làm rõ (cuộc tranh luận bây giờ là về MCP so với CLI), nhưng khi các kỹ năng được phát hành vào khoảng tháng 11 hoặc tháng 10 năm ngoái, chúng về cơ bản đã bắt đầu cuộc tranh luận này về việc: "Chúng ta có nên sử dụng chúng thay vì MCP không, bởi vì nếu tôi có thể cung cấp thêm thông tin, nhiều ngữ cảnh hơn cho tác nhân mà không cần tải mọi công cụ vào ngữ cảnh như MCP, và tôi cũng có thể có scripts, để tôi có thể có actions (hành động) giống như tôi có trên MCP tools, thì chúng ta có nên sử dụng chúng không?" Và câu trả lời là, bạn nên sử dụng cả hai, thành thật mà nói. Nếu bạn đang xây dựng bất cứ thứ gì là một tích hợp (integration), bạn nên sử dụng MCP, phải không? Bất cứ điều gì mà nếu tác nhân của bạn không có quyền truy cập vào bash, bạn nên sử dụng MCP để tích hợp với dịch vụ của mình. Kỹ năng thực sự chỉ cung cấp thêm ngữ cảnh cho tác nhân của bạn, phải không? Và bạn có thể định nghĩa các quy trình làm việc – mọi thứ mà bạn không có chỗ để định nghĩa trên các mô tả MCP tools, bạn có thể định nghĩa chúng trên kỹ năng.

Cũng liên quan đến sự so sánh, cuộc tranh luận giữa skills scriptsMCP tools, sự khác biệt chính là tools không cần một môi trường để chạy. Tác nhân có thể chỉ cần gọi một tool, biết cách gọi một tool, đặc biệt nếu MCP server là từ xa, và tool sẽ chạy ở server-side (phía máy chủ), trong khi các scripts – chúng về cơ bản được tải vào máy của bạn, chúng chạy trong môi trường cục bộ của bạn, và chúng gắn liền với bất kỳ môi trường nào bạn có. Vì vậy, nếu bạn đang chạy trên Linux, chúng phải tương thích với Linux. Nếu bạn đang chạy trên macOS, tương tự. Windows, tôi thậm chí sẽ không bắt đầu nói về nó. Nhưng về cơ bản, đó là những khác biệt chính giữa MCP toolsscripts. Hy vọng mọi thứ đã rõ ràng. Nếu bạn có bất kỳ thắc mắc nào, đừng ngần ngại hỏi. Tôi sẽ có một bản demo nhỏ. Buổi workshop này sẽ giống như một walkthrough (hướng dẫn từng bước) hơn là một buổi code along (cùng code), nhưng bạn cứ thoải mái tham gia. Tôi đã chuẩn bị một GitHub repo, vì vậy bạn có thể truy cập và khám phá nó. Nhưng nếu bạn có bất kỳ thắc mắc nào vào bất kỳ thời điểm nào của workshop, đừng ngần ngại ngắt lời tôi hoặc giơ tay.

Kiểm thử Kỹ năng (Skills)

Vậy, làm thế nào để bạn kiểm thử các kỹ năng của mình? Nếu đây chỉ là markdown, làm thế nào bạn kiểm thử các tệp markdown của mình? Về cơ bản, để kiểm thử một ứng dụng, một đoạn mã, thì đã khá dễ hiểu, phải không? Chúng ta đã biết bạn có tất cả các loại test types (loại kiểm thử): bạn có unit tests (kiểm thử đơn vị), integration tests (kiểm thử tích hợp), hoặc bạn có thể kiểm thử toàn bộ workflow, hoặc những gì chúng ta gọi là end-to-end testing (kiểm thử từ đầu đến cuối). Về cơ bản, khi bạn kiểm thử một tệp markdown, bạn có thể làm chính xác điều tương tự. Bạn có thể chi tiết đến mức bạn muốn. Nhưng thông thường, vì chúng ta có một Mô hình Ngôn ngữ Lớn (LLM) trong vòng lặp, bạn sẽ có một thứ gọi là evaluations (hệ thống đánh giá). Vì vậy, đối với những ai chưa nghe nói về evaluations hoặc eVals viết tắt, chúng về cơ bản là một cách nondeterministic (không xác định) hơn để kiểm thử đầu ra hoặc hành vi của một tác nhân hoặc một mô hình. Bạn có thể kiểm thử cả LLM hoặc tác nhân bằng eVals.

Về cơ bản, bạn là cấu trúc phổ biến nhất, tôi sẽ trình bày cho bạn ở cuối một khung làm việc (framework) để bạn kiểm thử eVals của mình, giống như một khung làm việc rất đơn giản nơi bạn có thể bắt đầu. Và tôi sẽ đi sâu hơn vào các evaluations ở đó. Nhưng về cơ bản, chúng thường bao gồm một input (đầu vào), một expected output (đầu ra mong đợi) giống như một kiểm thử thông thường, và ở giữa, bạn có thể đánh giá các bước mà tác nhân đã thực hiện, lý luận (reasoning), các công cụ mà nó đã gọi (thought), điều này thường thú vị và dễ đánh giá hơn là chỉ sử dụng regex trên đầu ra chính xác vì điều này là nondeterministic.

Khung làm việc đánh giá Agent Skills của OpenAI

Vì vậy, về cơ bản có một khung làm việc mà bạn có thể tuân theo để kiểm thử kỹ năng của mình. Khung này được OpenAI đề xuất trên bài viết blog của họ có tên "Systematically Evaluate Agent Skills". Tôi nghĩ họ đã phát hành nó vào khoảng tháng 1 hoặc tháng 2. Vì vậy, không quá lâu trước đây, nhưng tất cả điều này khá mới, vì vậy đây về cơ bản là "tiền sử".

Vì vậy, bạn bắt đầu bằng cách định nghĩa các số liệu/thước đo (metrics) của mình: bạn muốn đánh giá điều gì trên các kỹ năng của mình. Nếu bạn đang xây dựng một kỹ năng cho sản phẩm của mình, ví dụ, bạn muốn kỹ năng đó làm nổi bật điều gì cho tác nhân của mình? Nó sẽ chuyển hướng đến tài liệu? Bạn có đưa ra một lời nhắc cụ thể, một quy trình làm việc cụ thể không? Vì vậy, tùy thuộc vào những gì bạn muốn đánh giá, bạn bắt đầu eval-driven development (phát triển dựa trên đánh giá) này (tức là test-driven development - phát triển dựa trên kiểm thử). Bạn bắt đầu bằng cách định nghĩa các số liệu/thước đo, chính xác "tốt" có nghĩa là gì khi nói đến kỹ năng. Sau đó, bạn tạo kỹ năng đó, phải không? Vì vậy, bạn viết tệp skill.md, bạn viết tệp skill.md, bất kỳ scripts nào đi kèm, các reference files (tệp tham chiếu) – nếu bạn muốn. Tất cả đều là tùy chọn. Thứ duy nhất bắt buộc là tệp skill.md. Và sau đó bạn chuyển sang phần kiểm thử. Vì vậy, bạn chạy các hệ thống đánh giá tự động hoặc bạn chạy thủ công.

Brain Trust và Khả năng quan sát (Observability) cho Tác nhân

Tôi gần đây đã nghe Giám đốc điều hành của Brain Trust trong một podcast. Một podcast. Tôi không biết có bao nhiêu bạn biết Brain Trust. Được rồi. Không nhiều bằng, không phổ biến bằng kỹ năng. Nhưng, Brain Trust, đối với những bạn chưa biết, Brain Trust là một nền tảng cho phép bạn chạy eVals một cách có hệ thống và cung cấp cho bạn bức tranh toàn cảnh về hành vi của tác nhân trong suốt kịch bản đánh giá, phải không? Cố gắng nghĩ về một nền tảng khác để so sánh nhưng cái này khá mới, thành thật mà nói. Vì vậy, bạn có thể nghĩ nó giống như một công cụ khả năng quan sát (observability tool) để kiểm tra hành vi của các tác nhân của bạn trong một kịch bản có kiểm soát cụ thể, đó là các hệ thống đánh giá tự động. Vì vậy, bạn chuyển sang phần kiểm thử. Về cơ bản, bạn chạy một bộ kịch bản đánh giá (evaluations scenarios) – cách bạn định nghĩa chúng bằng inputexpected output, các công cụ nên được gọi. Vì vậy, về cơ bản, cách bạn mong đợi tác nhân của mình hành xử. Và sau đó, bạn chuyển sang phần grading (chấm điểm). Vậy tác nhân đã làm thế nào? Về cơ bản, điều này rất giống với một testing cycle (chu trình kiểm thử), phải không? Nhưng bây giờ, thay vì có một đầu ra deterministic (xác định), bạn có thể có, nó là nondeterministic (không xác định). Đó là một Mô hình Ngôn ngữ Lớn (LLM) ở giữa.

Giới thiệu về Workshop và Supabase

Nhưng bạn vẫn có thể có các phần xác định để đánh giá, và sau đó bạn sẽ lặp lại và lặp đi lặp lại. Đây là lý do tại sao nó là một chu trình khá tương tự như bất kỳ chu trình phát triển thử nghiệm nào mà chúng ta hiện có. Được rồi. Vậy, chúng ta hãy đi thẳng vào những gì chúng ta sẽ làm trong workshop này. Chúng ta sẽ viết một skill. Tôi đã chuẩn bị một ứng dụng minh họa nhỏ, một demo app. Nó sẽ là một ứng dụng performance review application với, tôi tin là, bốn nhân viên: một nhân viên, hai quản lý và một đại diện HR. Và về cơ bản, chúng ta sẽ tìm và sửa một số lỗi ở phía cơ sở dữ liệu. Chúng ta sẽ xây dựng một skill để giúp hướng dẫn các tác nhân sửa chúng. Được rồi. Và sau đó, ở cuối, như tôi đã nói, tôi có một framework để tự động kiểm tra cùng một scenario mà chúng ta sẽ kiểm tra thủ công bằng cách sử dụng eVals. Trước khi chuyển sang phần trình diễn, có bao nhiêu bạn đã từng nghe hoặc sử dụng Supabase? Được rồi. Gần như mọi người đều biết hoặc đã sử dụng Supabase. Tôi đã thấy một vài cánh tay hạ xuống. Vì vậy, tôi vẫn sẽ giới thiệu ngắn gọn cho bạn. Supabase về cơ bản là một backend as a service. Bạn có thể coi nó là phiên bản mã nguồn mở của... [speaker tìm kiếm sự giúp đỡ] ...cảm ơn, Firebase. Tôi chỉ nghĩ đến từ "Fire" thôi. Xin lỗi, Firebase. Và nếu bạn không biết Firebase, có lẽ bạn đang sống dưới một tảng đá. Không, nhưng về cơ bản, nó là một backend as a service. Bạn có thể sử dụng nó để xây dựng bất kỳ backend nào bạn muốn. Ngay lập tức, chúng tôi cung cấp một cơ sở dữ liệu để bạn chỉ cần cắm vào ứng dụng của mình và chạy trên PostgreSQL, một trong những giải pháp mã nguồn mở phổ biến nhất, nếu không muốn nói là phổ biến nhất hiện có cho các cơ sở dữ liệu. Bạn có thể dễ dàng tích hợp, bao gồm authentication vào ứng dụng của mình, chạy storage để lưu tệp, và nhiều thứ khác như edge functions, đó là các lambda functions dành cho những bạn đến từ môi trường AWS, v.v. Vì vậy, ứng dụng demo mà tôi đã xây dựng tất nhiên được xây dựng trên Supabase. Và bạn có thể làm theo.

Truy cập Mã nguồn Demo

Đây là các mã QR. Ở phía sau, mọi người có thể scanQR không, hay tôi nên phóng to nó hơn? Lớn hơn. Được rồi. Thế này. Ok, để mọi người đều có thể nhìn thấy, tôi đang chỉnh sửa bài thuyết trình ngay lúc này. Hãy xem Claude có gì để cung cấp cho chúng ta. [Phóng to nội dung]. Đây là điều thú vị của việc web coding bài thuyết trình của bạn. Tôi thực sự khuyên dùng nó. Tôi có thể dành thời gian tương đương hoặc nhiều hơn so với việc chỉ sử dụng một cái gì đó như Google Slides, nhưng ít nhất nó vui hơn. Và Anthropic chắc chắn sẽ rất vui vì điều đó. Được rồi. Hãy cho tôi biết khi mọi người đã truy cập được repo. Nếu bạn không thể nhìn thấy hoặc scanQR, tôi có lẽ nên phóng to liên kết nữa. Vậy là bạn đã yêu cầu một demo. Đây là demo trên slides của tôi. Vậy thì, chủ yếu mọi người ở đây trong phòng này đều đã sử dụng skills. Vì vậy, tôi có lẽ sẽ không phải "bán" cho bạn sức mạnh của skills. Nhưng nếu bạn vẫn còn hơi hoài nghi về skills, toàn bộ bài thuyết trình này mà không có skills sẽ không mấy dễ chịu, có thể nói vậy. Sẽ xấu hơn nhiều. Ok, bạn có lẽ nên thấy nó bây giờ. Vậy, về cơ bản, hãy điều hướng đến GitHub Hudripppn, đó là biệt danh của tôi, và improve-skills-workshop-AIE-Europe. Một cái tên rất dài. Được rồi. Mọi người đã ở GitHub repo chưa? Ok. Mọi người đều không gặp khó khăn gì. Được rồi. Vậy, không phải cái này, phải không? Vậy, đây là repo mà bạn nên xem. Về cơ bản, tôi biết nó là một repo lớn, nhưng chúng ta sẽ chia nhỏ nó ra. Thực ra, tôi sẽ di chuyển. Ok, sẽ chuyển sang VS Code.

Khám phá Ứng dụng Demo

Được rồi, ở đây chúng ta có hai ứng dụng Next.js. Thực ra, các slides cũng được nhúng ở đây. Ứng dụng Next.js quan trọng nằm trong thư mục demo, phải không? Và để bạn hình dung nó trông như thế nào, nó cơ bản là thế này. Đây là một ứng dụng rất đơn giản. Bạn có thể thấy rằng nó là một ứng dụng được code nhanh, thành thật mà nói. Layout của nó không có gì đặc biệt. Như tôi đã mô tả trước đó, bạn có một số nhân viên của công ty hư cấu này. Và bạn có thể nghĩ nó giống như một intranet hoặc một ứng dụng performance review application, nơi bạn, với tư cách là nhân viên HR, có tất cả thông tin về các nhân viên khác của công ty. Và vì mục đích trình bày, bạn có thể thay đổi giữa các người dùng. Vậy, điều chúng ta sẽ làm là, đầu tiên, không có skill, chúng ta sẽ cố gắng triển khai một view mới. Ở đây, chúng ta sẽ triển khai reports view. Về cơ bản, phần reports này của ứng dụng sẽ hiển thị cả salaryaverage rating cho performance review của từng phòng ban. Để HR có thể có cái nhìn tổng quan về toàn bộ công ty. Vì vậy, trước khi chúng ta bắt đầu code nhanh, bởi vì trong các workshop này, không ai thực sự viết code nữa. Vì vậy, tất nhiên, tôi sẽ code nhanh nó. Chúng ta sẽ chỉ chia nhỏ ứng dụng này ra. Vậy, nếu chúng ta điều hướng đến dashboard, không có gì đặc biệt để xem. Về cơ bản, đó là trang đầu tiên, trang chính mà bạn đã thấy. Và sau đó bạn có phần reports ở đây, nơi chúng ta nên có. Vâng. Chúng ta nên có view này tồn tại. Tôi đã chuẩn bị backend. Chúng ta sẽ tạo viewbackend dưới dạng SQL view trên cơ sở dữ liệu, và sau đó chúng ta sẽ có thể thấy nó trên ứng dụng.

Sử dụng Lời nhắc để Tạo Chế độ xem cơ sở dữ liệu

Vậy, tôi đã chuẩn bị... nó ở đâu nhỉ? Vâng. Vậy, tôi đã chuẩn bị lời nhắc và chúng ta sẽ live test nó. Cầu mong điều này thành công. Được rồi. Đầu tiên, hãy để tôi điều hướng đến ứng dụng. Okay. Ở đây chúng ta có nhiều quyền kiểm soát hơn. Được rồi. Về cơ bản, đối với những người ở phía sau, tôi sẽ yêu cầu Claude tạo một department stats view hiển thị số lượng nhân viên và mức lương trung bình được phân chia theo phòng ban. Đúng vậy. Để bộ phận HR có cái nhìn tổng quan đầy đủ về những gì đang diễn ra trong công ty. Vì vậy, chúng ta sẽ gửi lời nhắc và chờ xem nó sẽ đưa ra kết quả gì. Đúng vậy. Tôi quên mất phần này. Tôi đã cấu hình máy chủ MCP này. Nếu bạn có... thực ra tôi đã bỏ qua phần README. Nếu bạn đang theo dõi, xin lỗi về điều này. Nếu bạn đang theo dõi, bạn có thể làm theo các hướng dẫn thiết lập để khởi động ứng dụng của mình cục bộ. Điều này về cơ bản sẽ cài đặt các dependency, clone repo, cài đặt các dependency, khởi động cục bộ dự án Supabase của bạn. Bạn không cần phải cài đặt CLI mà chúng ta đang sử dụng npx để chạy nó như một binary. Chỉ cần reset trạng thái cơ sở dữ liệu để bạn bắt đầu từ đầu với seeded data, và sau đó chỉ cần chạy ứng dụng bằng npm run dev sẽ có sẵn trên localhost:3000/dashboard. Bạn cũng sẽ có tệp MCP.json này được chuẩn bị. Điều này về cơ bản đang trỏ đến máy chủ MCP mà chúng tôi, Supabase, đã kích hoạt cho các dự án cục bộ. Không yêu cầu authentication. Vì vậy, tác nhân của bạn có thể tải nó theo yêu cầu. Máy chủ MCP này hiển thị một tập hợp các công cụ. Tôi không biết có nhiều bạn đã sử dụng máy chủ MCP của Supabase không, nhưng tôi nghĩ chúng ta hiện có khoảng 20, 29 công cụ cho phiên bản production. Phiên bản này nhỏ hơn, có 20 công cụ, nhưng về cơ bản, bạn có thể thực hiện gần như bất cứ điều gì mà phiên bản để kết nối với dự án từ xa của bạn làm được, về cơ bản là liệt kê các bảng bạn có, thực thi SQL trực tiếp trên cơ sở dữ liệu của bạn, áp dụng migration và chạy database advisor, v.v. Vì vậy, về cơ bản, những gì nó bắt đầu làm là liệt kê các bảng của tôi. Vì vậy, tôi đã yêu cầu một view, nó sẽ xem xét schema mà tôi đã triển khai. Vì vậy, tôi sẽ để bạn và bây giờ nó sẽ chạy công cụ apply migration để tạo view. Vì vậy, về cơ bản, nó đang thực hiện thay đổi schema trên cơ sở dữ liệu của tôi và nó sẽ tạo view. Nếu chúng ta kiểm tra view, chúng ta về cơ bản đang tạo... create or replace a view department stat là tên mà chúng ta đã đặt, và chúng ta đang... bằng cách fetch tất cả thông tin từ... tôi nghĩ là department... không, từ profiles chính xác và group by department. Được rồi, đã mắc lỗi. Nó sẽ thử lại. Được rồi, nó sẽ kiểm tra. Đó thực sự là điều tôi rất thích. Được rồi, đây là view của chúng ta trên cơ sở dữ liệu.

Kiểm tra Chế độ xem và Vấn đề Quyền truy cập

Vậy, chúng ta hiện có nó trên cơ sở dữ liệu. Hãy xem liệu nó cũng được bật trên ứng dụng không. Okay, vậy thì không. Hãy nhanh chóng... tôi đã tạo SQL. Tôi đã đặt tên gì? Đây chính là vấn đề với live views — nó thường không hoạt động tốt ngay từ lần thử đầu tiên. Tôi muốn lặp lại và xem liệu nó có triển khai không. Nếu không, chúng ta có thể chỉ cần chạy SQL query để bạn thấy, với tư cách là những người dùng khác nhau, liệu mọi thứ có hoạt động đúng cách không. Vậy, hiện tại, nó sẽ cần triển khai trên ứng dụng Next.js để chúng ta có một giao diện đẹp để kiểm tra kết quả. Tôi cần bật mọi thứ. Đợi một chút, hãy để tôi bật chế độ tự động để tôi có thể tiếp tục nói. Về cơ bản, tác nhân đã tạo view, đã kiểm tra và nói rằng mọi thứ đều hoạt động đúng. Ứng dụng... tính năng đã được triển khai tốt. Nhưng chúng ta sẽ thực sự xem liệu mọi thứ có ổn không. Vì vậy, hãy cho nó một chút không gian, không gây áp lực để tạo tính năng. Hãy đợi thêm một chút thời gian. Trong lúc đó, nếu bạn đang theo dõi, bạn cũng có thể thử nghiệm với nó. Thay đổi layout thực sự bằng cách sử dụng Claude Code. Tôi không biết. Chỉ làm một cuộc khảo sát ngắn gọn ở đây trong workshop. Có bao nhiêu bạn cũng đang sử dụng Claude Code? Ồ, khá nhiều, gần như tất cả. Okay. Có bao nhiêu bạn đang sử dụng Cursor với Claude Code hoặc với plugin? Okay. Vâng, ít nhất một người. Chúng ta sẽ có một số người của Cursor ở đây. Tôi nghĩ là từ Anthropic nữa. OpenAI sẽ ở đây, cũng như Gemini. Tất nhiên, Google DeepMind đang tài trợ sự kiện. Vì vậy, chúng ta về cơ bản sẽ có toàn bộ nhóm ở đây. Okay. Vậy, chúng ta nên... tôi tin lời nó. Được rồi. Vậy, nó nói rằng chúng ta bây giờ đã hiển thị chính xác department stats view. Vậy, hãy xem điều đó có thực sự đúng không. Có vẻ đúng vậy. Vâng. Vì vậy, chúng ta bây giờ có những card này với cái nhìn tổng thể về công ty. Tôi đang đăng nhập với tư cách là Julia từ HR. Chúng ta có thể thấy rằng có năm người trong nhóm kỹ thuật với mức lương trung bình là 107 nghìn đô la. HR cũng vậy, chỉ có một người là Julia, và bộ phận sản phẩm có bốn người với mức lương trung bình đó. Vậy, cho đến nay mọi thứ đều ổn. Trông có vẻ ổn. Hãy xem. Đây là thông tin nhạy cảm. Các báo cáo, phải không? Vì vậy, chúng ta mong đợi rằng các nhân viên khác sẽ không có quyền truy cập vào nó và ngay cả các quản lý cũng chỉ có quyền truy cập cho bộ phận của họ. Hãy xem liệu đó có phải là trường hợp không. Vậy, hãy điều hướng đến Bob. Bob là trưởng phòng kỹ thuật. Ồ, okay. Vậy, Bob cũng có thể xem performance reviews của cả HR và sản phẩm. Chà, nó không quá tệ, phải không? Nó không lý tưởng, nhưng ít nhất anh ấy là quản lý, phải không? Vì vậy, anh ấy dù sao cũng nên có quyền truy cập vào thông tin đặc quyền. Và ai lại không thích một công ty minh bạch chứ? Hãy xem liệu tình trạng của chúng ta có ổn không. Okay, điều này có vấn đề. Vậy, về cơ bản chúng ta đã tạo một view. Claude nói mọi thứ đang hoạt động vì như bạn thấy thông tin ở đây.

Vấn đề về Bảo mật Cấp độ Hàng (Role-Level Security) trong Postgres View

Trong quá trình tạo view, đã xảy ra một vấn đề liên quan đến dữ liệu huấn luyện, đặc biệt đối với Postgres. Khi bạn tạo một view mới và bảng của bạn đã bật role-level security (bảo mật cấp độ hàng). Đối với những ai chưa biết, role-level security cho phép bạn xác định ai có thể xem thông tin trên một hàng cụ thể ở cấp độ cơ sở dữ liệu. Do đó, mà không cần tin cậy ứng dụng, bạn có thể lọc trực tiếp trên cơ sở dữ liệu. Trong trường hợp này, chúng ta nên giới hạn chế độ xem các hàng theo ID người dùngvai trò người dùng. Vì vậy, nếu một người dùng có vai trò nhân viên, họ không nên có quyền truy cập vào các hàng không thuộc về họ.

Chúng tôi đã bật role-level security. Nếu bạn điều hướng đến migrations của Superbase của chúng tôi, bạn có thể thấy rằng chúng tôi đã bật role-level security trên cả hồ sơđánh giá hiệu suất. Trong một đánh giá hiệu suất, reviewer ID phải bằng current setting, vì vậy nó phải hoạt động. Tại sao nó không hoạt động? Khi bạn tạo một view trên Postgres, theo mặc định, quyền được tạo bằng các quyền hoặc thông tin xác thực của người dùng đã tạo view, chứ không phải bằng thông tin xác thực của bảng, tức là với role-level security. Về cơ bản, theo mặc định, nó bỏ qua role-level security mà bạn đã thiết lập trên bảng của mình. Để kịch bản này xảy ra, chúng ta phải sử dụng cờ SECURITY INVOKER để chuyển các chính sách role-level security hoặc để bật các chính sách RLS trên chính view. Đây là lý do tại sao hiện tại mọi người đều có thể xem thông tin của người khác, vì các chính sách role-level security đã bị bỏ qua trên view.

Giới thiệu Skill về Bảo mật Postgres

Vì mục đích của buổi workshop này, tôi đã tạo một skill để trình bày. Về cơ bản, kỹ năng này là ba điểm bảo mật chính về Postgrestác nhân nên biết trong suốt bài trình bày. Đối với skill này, tôi thực sự đã cung cấp quá nhiều thông tin chi tiết cho chính xác view mà chúng tôi đang tạo. Nhưng các mô hình hiện tại đủ thông minh để tổng quát hóa điều này. Và nếu tôi muốn tạo một view mới, nó sẽ được tạo với cờ này. Kể từ phiên bản Postgres 15, cờ này đã được bật và mỗi khi nó được bật, các chính sách RLS cũng được bật trên view.

Như bạn có thể thấy, đây là một tài liệu khá dễ đọc. Hầu hết các bạn đã viết kỹ năng, vì vậy tôi sẽ không đi sâu vào chi tiết này. Nhưng như bạn có thể thấy, chúng tôi có cả tiêu đề. Tôi gọi nó là "Bảo mật Superbase" (Superbase security) và mô tả sử dụng động từ "use" (sử dụng). Đây là một hiểu biết mà tôi có được từ một số thử nghiệm mà tôi đã thực hiện; việc sử dụng các động từ, chủ yếu là động từ "use", làm tăng cơ hội kỹ năng được tải, ít nhất là trên Claude. Tôi không biết liệu đây có phải là hành vi mặc định cho Claude hay không, liệu nó có được huấn luyện để dễ dàng nhận biết các động từ, cụ thể là "use" hay không. Nhưng tôi thấy hiệu quả hơn nếu bạn viết "use" và sau đó là toàn bộ mục đích của kỹ năng trước nó, rồi một danh sách Markdown thông thường. Chúng ta có trường hợp view ở đó, nhưng cũng có một danh sách kiểm tra khác cho các điểm bảo mật trên RLS. Các schema công khai nên có RLS được bật theo mặc định. Các schema công khai hoặc schema lộ ra là các schema cơ sở dữ liệu sẽ cung cấp thông tin cho ứng dụng mà người dùng có thể thấy. Ví dụ, bảng người dùng, hồ sơ, đánh giá hiệu suất, tất cả thông tin này sẽ được giao diện người dùng lấy. Nó hoàn toàn được bảo mật vì Superbase làm cho nó an toàn bằng cách cho phép bạn lấy thông tin từ giao diện người dùng. Nhưng phần quan trọng ở đây là nếu bạn không bật role-level security, bạn sẽ không có bộ lọc này trên bảng và bạn sẽ phải dựa vào logic ứng dụng để tạo bộ lọc. Vì vậy, việc bật role-level security ít nhất giúp an toàn hơn cho bạn với tư cách là kỹ sư backend, rằng bạn chỉ tiết lộ thông tin mà bạn thực sự muốn ngay từ đầu. Và một vài điều nữa mà tôi sẽ không đi sâu vào.

Cài đặt và Kích hoạt Skill

Vì vậy, chúng ta có thể cài đặt kỹ năng này trên dự án này bằng cách chạy lệnh npx. Tôi sẽ sử dụng gói npm của Vercel có tên skills. Tôi tò mò muốn biết các bạn đã đóng gói kỹ năng của mình như thế nào. Các bạn đã bao giờ sử dụng gói này chưa? Các bạn đang sử dụng plugin phải không? (Một người khác trả lời: "Cái này", "Cái này?", "Chủ yếu là cái này.") Vâng, nó trở nên rất phổ biến vài tháng trước. (Một người khác trả lời: "Tôi nghĩ vấn đề duy nhất là nó không thực sự tuân thủ dự án của bạn. Vì vậy, bạn chỉ nhận được toàn cục cho dự án cục bộ của mình.") Vâng, bạn có thể cài đặt nó toàn cục và trên dự án của bạn, và nó cũng hỗ trợ nhiều tác nhân. Trong khi plugin hiện tại vẫn bị ràng buộc với tác nhân sẽ tải chúng. Ví dụ, Cursorplugin, Claude Codeplugin. Tôi nghĩ các nhà cung cấp khác cũng có, nhưng chúng được phân phối và tạo riêng cho các mô hình cụ thể đó.

Vì vậy, chúng tôi đang sử dụng gói này để cài đặt. Bạn có thể cài đặt bất kỳ kỹ năng nào từ một kho lưu trữ trực tuyến có tệp skill.md hoặc bạn có thể sử dụng nó để cài đặt cục bộ. Nó sẽ tự động phát hiện vị trí bạn đang cố gắng lấy từ, dựa trên định dạng. Trong trường hợp này, chúng tôi không có GitHub, chúng tôi không có giao thức HTTP nào ở đó. Vì vậy, chúng tôi có dấu chấm /., nó sẽ nhận ra rằng đó là một kỹ năng cục bộ. Và để làm điều này, tôi sẽ chuyển đến main. Được rồi. Và theo cách truyền thống, tôi sẽ chạy trên bash.

Nó sẽ hiển thị một cửa sổ bật lên, hỏi tôi muốn cài đặt trên tác nhân nào. Tôi đang sử dụng Claude Code, vì vậy tôi sẽ cài đặt nó trên Claude Code. Nếu bạn đang sử dụng bất kỳ tác nhân nào khác, bạn cũng có thể cài đặt nó miễn là nó hỗ trợ. Tôi sẽ cài đặt nó ở cấp độ dự án. Trong trường hợp này, nó sẽ tạo một thư mục tác nhân với kỹ năng và liên kết nó với thư mục mycloud/skills của tôi. Vì vậy, Claude biết nơi để tìm chúng. Tôi sẽ tạo một liên kết tượng trưng (symlink) và chúng tôi đã sẵn sàng để cài đặt. Vì vậy, nếu chúng ta... đừng để lộ khóa API của tôi. Tôi sẽ xóa cái này, đây chỉ là cho buổi workshop nên tôi sẽ xóa nó sau. Cứ thoải mái sử dụng tín dụng miễn phí của tôi trong thời gian này, nhưng về cơ bản đã tạo ra tác nhân, nó ở đâu? Vâng. Vì vậy, tôi cũng có một số thứ khác mà chúng ta sẽ xem sau. Nhưng phần thiết yếu có kỹ năng mà tôi đã trình bày trước đây. Vâng, đây rồi. Đó là kỹ năng và sau đó cũng đã tạo một liên kết tượng trưng đến Claude. Đây là cách gói hoạt động. Và cách này cho phép Claude tìm kiếm trong tác nhân, nơi đang trở thành tiêu chuẩn hoặc trong thư mục Claude mà nó có.

Vì vậy, hãy chạy lại cùng một lời nhắc trong một phiên mới. Hãy quay lại apps demo. Vâng. Và bắt đầu một phiên mới. Chúng ta nên bật kỹ năng này. Vâng, đây rồi. Vì vậy, Claude đã nhận thức được kỹ năng bảo mật Superbase. Bây giờ để chạy kỹ năng, bạn có thể chỉ cần chạy lời nhắc của mình và hy vọng rằng Claude sẽ nhập kỹ năng của bạn dựa trên mô tả bạn đã đưa ra. Bạn có thể bao gồm các từ khóa "use" và sau đó là tên của kỹ năng bạn có trên lời nhắc và điều này sẽ tải kỹ năng của bạn gần như 100% các lần. Hoặc nếu bạn đang sử dụng Claude Code, bạn chỉ cần gạch chéo và viết tên kỹ năng của mình. Và điều này đảm bảo 100% rằng Claude sẽ nhập kỹ năng. Vì vậy, đối với trường hợp sử dụng của chúng tôi hoặc đối với bài trình bày, tôi sẽ (vì tôi không thể chấp nhận việc nó không tải kỹ năng). Hãy đợi. Tôi cần đặt lại cơ sở dữ liệu để tạo lại view. Buổi workshop và đó là npxb reset. Vâng, tôi chỉ cần đặt lại cơ sở dữ liệu, áp dụng migrations từ đầu. Nó đã không tạo bất kỳ tệp migration nào. Anh ấy đã áp dụng migration trực tiếp vào cơ sở dữ liệu. Vì vậy, bây giờ chúng ta sẽ ổn để tiếp tục. Vì vậy, nó sẽ tắt cơ sở dữ liệu và tạo một cơ sở dữ liệu mới dựa trên schema mà chúng tôi đã định nghĩa trong các tệp migration và dữ liệu ban đầu.

Thảo luận về Skill và Tương lai của Tác nhân

(Người tham gia): "Vâng. Bạn đã tìm thấy cách nào để xây dựng kỹ năng chưa?"

Vâng, đó là một điểm hợp lý. Toàn bộ câu hỏi hoặc quan sát của bạn là lời hứa ban đầu về các kỹ năngAnthropic đã trình bày là...

(Người tham gia): "Vâng..."

...vì điều này giống như ở phía tác nhân, đúng không, tác nhân quyết định khi nào tải điều này. Điều tốt nhất bạn có thể làm mà không cần rõ ràng, bằng lệnh gạch chéo hoặc "use" và sau đó là tên kỹ năng trong lời nhắc của bạn, là bạn hãy thử nghiệm với mô tả và chạy một loạt kiểm thử thủ công hoặc tự động để kiểm tra xem điều gì thực sự hiệu quả và điều gì không đối với những gì bạn mong đợi tác nhân sẽ hoạt động, đúng không? Vì vậy, bạn xác định một loạt kịch bản mà bạn nghĩ rằng kỹ năng nên được tải và khi nào kỹ năng không nên được tải. Bạn hãy kiểm tra nó. Bạn có thể kiểm tra nó trên máy của mình, giống như trong kịch bản này, tôi không muốn kỹ năng được tải. Hãy nhắc lời nhắc trên Claude Code chẳng hạn và kiểm tra xem kỹ năng đã được tải hay chưa thông qua giao diện dòng lệnh. Và sau đó thử nghiệm với mô tả để xem điều gì thực sự hiệu quả hay không. Như vậy, mà không cần gọi kỹ năng một cách rõ ràng, đây là điều tốt nhất bạn có thể làm để kiểm tra xem kỹ năng có được tải chính xác hay không.

Vâng, chúng ta vẫn đang ở giai đoạn rất sơ khai của kỹ năng, ngay cả đối với MCP, tất cả những thứ liên quan đến tác nhân này đều khá mới. Vì vậy, chúng ta vẫn đang tiêu chuẩn hóa mọi thứ. Chúng ta vẫn đang tìm ra điều gì hiệu quả và điều gì không. Progressive disclosure là một điều mà không ai nói đến sáu tháng trước và bây giờ có thể nói đó là một trong những kim chỉ nam của phát triển tác nhân. Vì vậy, sáu tháng nữa, có thể sẽ là một điều khác. Vì vậy, hoặc kỹ năng có thể là tiêu chuẩn hoặc có thể Anthropic hoặc OpenAI hoặc ai đó khác đã tìm ra một cách hiệu quả hơn để quản lý ngữ cảnh hoặc cung cấp nhiều ngữ cảnh hơn cho tác nhân. Vì vậy, chúng ta sẽ xem xét. Được rồi. Cơ sở dữ liệu đã được đặt lại.

Chạy lại Lời nhắc và Kết quả

Được rồi. Ít nhất bây giờ chúng ta có view nhưng chúng ta không có thông tin trên cơ sở dữ liệu của bạn. Vì vậy, bây giờ chúng ta có thể chạy lại cùng một lời nhắc nhưng với kỹ năng. Nếu chúng ta nhấn lời nhắc, bạn nói nó khá nhanh, tôi không nghĩ vậy, vâng nhưng nó không tạo ra một cái. Được rồi, hãy thử một điều khác. Thay vì thế này, hãy dùng "use to create". Hãy xem liệu nó có hoạt động bây giờ không. Vâng. Được rồi. Vì vậy, nó đã tải kỹ năng. Vì vậy, bây giờ ít nhất nó nên có ngữ cảnh để tạo ra cờ RLS hoặc SECURITY INVOKER nên được đưa vào khi tạo view, và các bước, phần còn lại của quy trình làm việc nên giữ nguyên. Vì vậy, nó sẽ liệt kê các bảng của tôi. Đúng vậy. Chính xác. Xác định các bảng. Và bây giờ nếu chúng ta nhìn kỹ, chúng ta có thể thấy rằng chúng ta bây giờ có cờ này ở đây sẽ nằm trên migration. Vì vậy, hãy xem liệu với cờ này, đây có phải là kết quả mong đợi không. Đây là điều xảy ra khi bạn mã hóa một giao diện dòng lệnh. Bây giờ bạn có giao diện người dùng bị trùng lặp. Đúng không? Vì vậy, nó đã tạo view. Chúng ta sẽ có thể thấy nó, nhưng Alice thì không nên. Vậy điều gì đang xảy ra? Khoan. Được rồi. Vậy, tôi có phải đặt lại bây giờ không? Hừm, thú vị. Có lẽ nên có một cái khác. Hãy để tôi xem liệu tôi có nó ở đây không. Tôi đã đặt nó ở đâu? Vậy thì, tôi sẽ gian lận ở đây.

Khắc phục sự cố và Cải thiện Kỹ năng

Chúng ta sẽ nói rằng cả người dùng và nhân viên đều có thể thấy thông tin. Được rồi, về cơ bản là khắc phục sự cố trực tiếp. Điều gì đang không diễn ra? Có lẽ là từ một chính sách khác mà tôi đã định nghĩa ở đây. Nhưng bây giờ nó sẽ khắc phục sự cố. Hãy xem liệu kỹ năng có thực sự cải thiện nỗ lực ở đây hay không. Nếu không, tôi có một quân bài tẩy. Bởi vì, nếu bạn chưa biết, Superbase về cơ bản có các cố vấn cơ sở dữ liệu mà bạn có thể sử dụng để cố gắng xác định sớm một số lỗ hổng tiềm ẩn hoặc schema bị lộ, thông tin có thể bị lộ trước khi bạn triển khai vào môi trường sản xuất. Vì vậy, nếu nó có thể tự mình tìm ra, tôi sẽ đưa vào kỹ năng để cũng chạy cố vấn để kiểm tra.

Đây là phần chính của kỹ năng là bạn có thể – ồ, đó là bạn có thể thấy, thật sự đây là một ứng dụng được viết rất tệ, tôi phải nói vậy – đó về cơ bản là phần chính của kỹ năng. Vấn đề không phải là liệu bản demo cụ thể này có hoạt động hay không, mà là hành vi đã thay đổi một khi nó tải kỹ năng, phải không? Nó đã được tạo với phần security invoker. Và với điều đó, nó cho thấy sức mạnh của việc bạn có thể tạo, bạn có thể thay đổi hành vi hoặc hướng dẫn Tác nhân theo yêu cầu dựa trên thông tin bạn cung cấp. Bạn có thể coi các tệp skill.md như một lời nhắc mẫu mà bạn có thể cung cấp cho Tác nhân của mình. Vì vậy, hãy nhanh chóng khắc phục sự cố. Ồ, nó thậm chí còn đề xuất áp dụng một migration. Hãy xem liệu nó có làm hỏng ứng dụng của tôi không. Được rồi. Vậy có vẻ quá phức tạp.

Hiệu suất Kỹ năng và So sánh với MCP

Tôi có khá nhiều kỹ năng. Như bạn thấy, tôi đã thử nghiệm với chúng. Tôi cũng có một số máy chủ MCP được cài đặt sẵn mà Superbase hỗ trợ. Nhưng về cơ bản, sẽ thú vị hơn nếu tôi đã so sánh ngữ cảnh trước và sau khi tải kỹ năng. Hiện tại, các kỹ năng chiếm 1.300 mã thông báo trong ngữ cảnh của tôi, phải không? Như bạn đã thấy, tôi có nhiều hơn một kỹ năng này, nhưng kỹ năng đã được tải, vì vậy toàn bộ thông tin bên trong skills.mmd đã được tải vào ngữ cảnh. Nếu chúng ta xóa và chạy lại ngữ cảnh, lượng kỹ năngkỹ năng này không đủ để bạn thấy – nhưng như bạn thấy, kỹ năng chiếm ít không gian hơn đáng kể so với MCP.

Được rồi, tôi có một phiên bản Claude Code mới hơn. Vì vậy, đối với những ai chưa biết, Entropic gần đây đã phát hành tool search tool, đây là một cơ chế để Claude Code tải công cụ theo yêu cầu. Vì vậy, nó không tải tất cả; về cơ bản là progressive disclosure (tiết lộ dần dần), nhưng dành cho MCP tools, phải không? Sự khác biệt chính giữa progressive disclosure này hoặc tool search tool trên Claude Codekỹ năngprogressive disclosure được thiết kế riêng cho kỹ năng. Vì vậy, nó đã được tích hợp sẵn vào cấu trúc, vào thể hiện của kỹ năng, trong khi trên MCP, nó vẫn chưa phải là một tiêu chuẩn cho tất cả các công cụ. Vì vậy, nó hoạt động với Claude Code, nhưng đối với nhiều client khác thì không. Nó sẽ chỉ tải tất cả các công cụ trực tiếp vào ngữ cảnh của bạn. Vì vậy, đây hiện tại là một điều chỉ dành cho Claude Code. Nếu bạn quan tâm, chúng tôi sẽ có người sáng lập hoặc một trong những người đồng sáng lập MCP phát biểu vào ngày 10. Vậy, vào thứ Sáu, anh ấy sẽ đưa ra một cái nhìn tổng quan ngắn gọn về lộ trình MCP. Mà, nếu không có gì thay đổi kể từ tuần trước khi anh ấy trình bày điều này ở New York tại MCP dev summit, thì nên đưa phần progressive disclosure này vào công cụ để đưa nó vào chính giao thức.

Tải Schema cơ sở dữ liệu lớn: Kỹ năng hay MCP?

Vâng. Giả sử chúng ta có một cơ sở dữ liệu rất lớn và chúng ta phải tải schema của cơ sở dữ liệu này vào ngữ cảnh vì chúng ta phải truy vấn cơ sở dữ liệu bằng cách sử dụng Tác nhân. Theo ý kiến của bạn, liệu có tốt hơn không nếu sử dụng một kỹ năng hay một MCP để tải schema này, nhưng theo cách tiết lộ dần dần? Có thể sử dụng schema để tiết lộ/tải schema của cơ sở dữ liệu lớn này một cách dần dần trong kinh nghiệm của bạn không?

Vâng. Ồ vâng. Được. Vậy câu hỏi của bạn chủ yếu là về cách chúng ta nên truy cập nó hay toàn bộ kiến trúc của pipeline này để nhập dữ liệu? Tôi chỉ muốn yêu cầu một Tác nhân truy vấn cơ sở dữ liệu và rõ ràng là Tác nhân phải biết schema của cơ sở dữ liệu trước hay không. Làm thế nào bạn có thể dạy Tác nhân truy vấn cơ sở dữ liệu bằng cách sử dụng các kỹ năng, sử dụng một máy chủ MCP hay thứ gì đó tương tự? Và nếu bạn sử dụng các kỹ năng, nếu bạn quyết định sử dụng các kỹ năng để tải ngữ cảnh của Tác nhân với schema của cơ sở dữ liệu, liệu có thể tải schema một cách dần dần trong ngữ cảnh không?

Được rồi, tôi hiểu rồi. Hãy để tôi phân tích tình huống này cho bạn. Về cơ bản, bạn sẽ có hai phần. Một là những gì sẽ nằm trong ngữ cảnh. Vì vậy, những gì sẽ được tải và thông tin cụ thể mà bạn muốn có trong kịch bản của mình. Và phần thứ hai là cơ chế thực tế, cơ chế trích xuất mà bạn sẽ sử dụng để tải thông tin từ cơ sở dữ liệu. Vì vậy, đối với phần thứ hai, để tải thông tin từ cơ sở dữ liệu, bạn có thể sử dụng một script (tức là một kỹ năng gọi một script) hoặc một công cụ MCP.

Tôi khuyên bạn nên sử dụng một công cụ MCP vì bạn có thể sử dụng nó nếu bạn đang triển khai trong môi trường sản xuất hoặc trên một dự án từ xa. Bạn không phụ thuộc vào môi trường cục bộ của mình. Bạn không phải quản lý các khóa. Và công cụ đã được chuẩn hóa, đồng thời bạn đã có sẵn xác thực được tích hợp vào giao thức. Vì vậy, Tác nhân không bao giờ quản lý mã thông báo xác thực. Nó chỉ chạy công cụ, và nó hoạt động để tiết lộ thông tin trong cơ sở dữ liệu một cách dần dần. Bạn sẽ phải – bạn có thể đưa nó vào một kỹ năng. Vâng. Bạn sẽ sử dụng công cụ MCP. Trong kỹ năng, bạn có thể sẽ nêu rằng 'sử dụng công cụ này để tải', và trong triển khai công cụ, bạn phải cho phép nó không tải tất cả mà tải dần dần, phải không? Tức là tải theo từng chunk. Có thể chỉ cần đủ từ các tham số công cụ. Tác nhân nên tự mình tìm ra rằng nếu bạn đặt một tham số gọi là buffer chẳng hạn, nó sẽ có thể tải theo chunk, phải không? Thay vì toàn bộ bảng. Nhưng nếu bạn muốn chắc chắn 100% rằng nó sẽ tải theo chunk và sử dụng đúng cách, tôi cũng sẽ đóng gói nó với một kỹ năng và mô tả cách tôi dự định sử dụng công cụ này. Vì vậy, đây thực sự là cách cả kỹ năngMCP cùng hoạt động. Công cụ là để kích hoạt kết nối này, tích hợp này, và kỹ năng là để mô tả cách sử dụng nó. Vâng, đây là cách tôi sẽ triển khai loại hệ thống này. Cảm ơn bạn đã đặt câu hỏi. Và điều đó đã cho tôi cơ hội để về cơ bản nói về cách sử dụng cả kỹ năngMCP chứ không phải đặt chúng đối lập nhau.

Đánh giá và Tự động hóa Kỹ năng

Vì vậy, như đã hứa, chúng ta nên tiếp tục. Tôi sẽ phải dành thêm thời gian để tìm hiểu vì về cơ bản, trong quá trình chuẩn bị workshop, tôi đã tạo ra một loạt các lỗ hổng. Vì vậy, nếu tôi chỉ giữ cho nó đơn giản, bản demo đó có lẽ đã hoạt động. Vì tôi có nhiều lỗ hổng bị lộ hơn mà nếu có thời gian, tôi sẽ cố gắng giải quyết. Hiện tại nó chưa hoạt động, nhưng bạn đã thấy trong cả hai kịch bản rằng kịch bản đầu tiên không có cờ security invoker, còn kịch bản thứ hai thì có. Vì vậy, ít nhất chúng ta có thể ngụ ý rằng kỹ năng đang làm điều gì đó. Tác nhân đã thấy thông tin trên kỹ năng. Nó đã hợp nhất thông tin đó với lời nhắc hệ thống hoặc lưu trữ gần lời nhắc hệ thống và thay đổi hành vi tương ứng.

Để kiểm tra điều này, nếu bạn muốn đưa phần kỹ năng này vào sản xuất, phải không? Vì vậy, nó hoạt động trên máy của bạn. Đó là một câu chuyện xưa như Trái đất rằng 'nó đang hoạt động trên máy của tôi', nhưng tôi không biết liệu nó có hoạt động trên Tác nhân của bạn, trên máy của bạn, trên môi trường của bạn hay không. Vì vậy, để kiểm tra điều này hoặc để tự động hóa quá trình kiểm tra này, và với điều này, chúng ta có thể mở khóa việc có một pipeline. Ví dụ, nếu bạn thay đổi một điều gì đó trong kỹ năng của mình, làm thế nào bạn có thể đáng tin cậy cho biết rằng nó vẫn đang làm những gì bạn mong đợi và không làm hỏng luồng trước đó? Vì vậy, nếu tôi thay đổi một trong các checklist, làm thế nào tôi có thể đảm bảo rằng những cái khác vẫn hoạt động đúng cách? Đây là nơi eVals có thể can thiệp.

Evaluations (đánh giá) là một thuật ngữ rất rộng. Bạn về cơ bản có thể đánh giá bất cứ điều gì vì đây là một tệp markdown. Đó là một tệp văn bản tự do. Bạn có thể đánh giá về cơ bản bất cứ điều gì. Vì vậy, việc tạo eVals khá khó khăn – phần khó nhất, tôi muốn nói, là thực sự đưa ra các kịch bản vì trước tiên bạn sẽ phải biết hành vi mong đợi của các Tác nhân của mình là gì. Vì vậy, việc đưa ra các kịch bản đại diện thực sự tốt, bao gồm một lượng lớn các use case mà bạn muốn xây dựng là khó nhất. Và vẫn chưa có một cấu trúc chuẩn hóa để tạo các evaluations. Bạn có thể kiểm tra nó bằng cách nhập một loạt lời nhắcđầu ra mong muốn từ tệp CSV hoặc tệp JSON. Bạn có thể sử dụng các công cụ như Brain Trust hoặc Lenfuse để kiểm tra nó và để có một lớp analyticskhả năng quan sát trên đó.

Đối với bài thuyết trình này, tôi đã tuân theo những gì tiêu chuẩn mở agent skills open standard định nghĩa để thiết kế các trường hợp thử nghiệm. Vì vậy, nếu bạn chưa biết về trang web này, đây là trang đích của agent skills open standards để cố gắng chuẩn hóa kỹ năng là gì và nó nên hoạt động như thế nào, và họ về cơ bản đề xuất một cấu trúc rất đơn giản, một cách cục bộ để kiểm tra các kỹ năng được tổ chức bằng cách bạn sẽ có một tệp eval.json về cơ bản có một tập hợp các eval scenarios (kịch bản đánh giá). Bạn sẽ đặt lời nhắc mà bạn sẽ cung cấp cho Tác nhân, đầu ra mong đợi từ Tác nhân. Điều này chỉ áp dụng nếu bạn có một LLM đóng vai trò là judge (trọng tài). Đây là một kỹ thuật được sử dụng để đánh giá không xác định. Thay vì một con người, bạn có thể cung cấp đầu ra của một lần chạy đánh giá cho một LLM khác. Đặt ra một tiêu chí thành công và để LLM có vai trò là trọng tài (đó là lý do tại sao nó được gọi là LLM as a judge) chấm điểm nó về cơ bản. Vì vậy, đây là một phần mà bạn có thể tự động hóa trong các đánh giá của mình cho các workflow không xác định. Bạn có thể khẳng định liệu một công cụ có được gọi hay không hoặc bạn có thể cung cấp kết quả cho một LLM và không xác định cố gắng để Tác nhân chấm điểm hiệu suất của các Tác nhân khác. Chúng ta về cơ bản có các Tác nhân đánh giá các Tác nhân.

Vì vậy, tôi đã tuân theo cấu trúc này. Tôi đã cung cấp cùng một đầu vào ở đây, phải không? Vì vậy, Tác nhân sẽ chạy đánh giá này sẽ nhận được cùng một đầu vào mà chúng ta đã có. Đầu ra mong đợi là security invokertrue. Vì vậy, nó có mặt trên ứng dụng, xin lỗi, trên view. Và sau đó tôi có một loạt các khẳng định mà trong trường hợp này, tôi sẽ kiểm tra một cách xác định. Tôi đã chuẩn bị một script Python về cơ bản chỉ đặt lại trạng thái của cơ sở dữ liệu để chúng ta đảm bảo rằng, vì chúng ta đang chạy cục bộ và không trên một môi trường biệt lập như Docker container chẳng hạn, chúng ta phải đảm bảo rằng các hệ thống luôn bắt đầu từ cùng một nền tảng. Vì vậy, tôi sẽ đặt lại ứng dụng. Nếu bạn muốn chạy các đánh giá, bạn cũng phải chọn Entropic key của riêng mình, tạo, sao chép cái này. Bạn có thể làm theo README bên trong Superbase security ở đây; bạn sẽ có hướng dẫn cách thiết lập. Nhưng sau đó tôi sẽ chạy Claude Code trên đó. Tôi nghĩ nó ở chế độ print mode hoặc tôi không nhớ họ gọi nó là gì, nhưng về cơ bản, tôi sẽ chạy nó như một binary headless.

Cấu hình và Chạy Đánh giá Kỹ năng

Tác nhân sẽ nhận lời nhắc từ hệ thống đánh giá làm nhiệm vụ cần thực hiện. Chúng ta sẽ kiểm tra hai điều kiện: một có kỹ năng và một không có. Để bạn hình dung quy trình, đây là nơi Claude Code sẽ chạy. Nếu điều kiện là có kỹ năng, chúng ta sẽ tải skill.md vào lời nhắc hệ thống.

Nếu bạn muốn mô phỏng hành vi này, bạn có thể chạy nó trên một Vùng chứa Docker. Bạn sẽ đặt các kỹ năng tác nhân vào thư mục Claude/skills bên trong Vùng chứa Docker và để Claude Code tự động tìm và sử dụng chúng. Đối với buổi thuyết trình này, đây là một thiết lập rất đơn giản; tôi chỉ nối thêm nó vào lời nhắc hệ thống.

Chúng ta sẽ chạy các đánh giá. Tôi đã sửa lại tên bị lỗi trước đó. Chúng ta bắt đầu bằng cách chạy với kỹ năng. Kết quả đầu tiên mà chúng ta nhận được là từ trường hợp có kỹ năng. Nó đã dừng. Bây giờ nó đang chạy mà không có kỹ năng, và sau đó chúng ta sẽ so sánh các kết quả. Quá trình này sẽ tạo ra một thư mục workspace iteration one. Trong khi trường hợp không có kỹ năng đang tải, chúng ta hãy nhanh chóng kiểm tra đầu ra của trường hợp có kỹ năng.

Về cơ bản, bạn có thể thấy rằng nó đã tạo ra view với security invoker và sau đó chúng ta có tệp grading.json chứa nhiều thông tin, chẳng hạn như các assertion mà chúng ta đã đặt trong eval.json. Chúng ta có chúng ở đây và có thể thấy rằng đối với trường hợp này, nó được đánh dấu là "thất bại" mặc dù nó đã tạo... tại sao nó không tìm thấy view dưới dạng security? Được rồi, tôi thực sự đang đánh giá sai điều gì đó, vì vậy vấn đề bây giờ là với view. Vì tôi đã mong đợi nó tạo ra một PG class RL options thay vì chỉ kiểm tra view, nên nó báo rằng đã thất bại.

Phân tích Kết quả và Thách thức khi Viết eVals

Phần quan trọng là nó đã hoàn thành chưa? Nó chưa hoàn thành. Vẫn đang chạy. Mất một thời gian dài. Được rồi, và bây giờ chúng ta có thể kiểm tra. Đây thực sự là một cái nhìn sâu sắc tốt. Với những kết quả này, đây là phần khó khăn khi viết eVals. Giống như các bài kiểm tra thông thường, kết quả sẽ phụ thuộc vào cách bạn triển khai chúng, phải không? Nó chỉ là code. Vì vậy, nếu bạn đang đánh giá sai một điều gì đó hoặc không phải hành vi mong đợi, bạn sẽ nhận được kết quả sai. Có thể không phải do hệ thống AI không hoạt động.

Chúng tôi đã kiểm tra thủ công và thấy rằng với kỹ năng, nó đã tạo ra với security flag. Chúng ta thực sự có thể kiểm tra nó ở đây với kỹ năng đã tạo. Hãy xem liệu lần này, đáng ngạc nhiên là nó đã làm được. Đây là một hành vi không xác định của Claude Code.

Nhưng vì tôi đã đánh giá sai điều gì đó, phải không? Tôi đã mong đợi nó tạo hoặc kiểm tra một meta schema để xác định xem view security invoker có ở đó hay không, thay vì chỉ kiểm tra trực tiếp view. Các kết quả đã sai lệch một chút. Vì vậy, nó nói rằng với kỹ năng thì thất bại, và không có kỹ năng thì vượt qua. Và nếu chúng ta kiểm tra cả hai đầu ra, chúng về cơ bản là giống nhau. Điều này chỉ để cho bạn thấy việc viết eVals khó khăn như thế nào, bởi vì mặc dù điều này có thể xảy ra với các bài kiểm tra thông thường, nhưng nó dễ phát hiện hơn vì đầu raxác định, phải không? Nó chỉ là code. Ở đây, nếu bạn giao cho một Mô hình Ngôn ngữ Lớn đánh giá, đôi khi nó có thể tạo ra ảo giác.

Kiến trúc Đánh giá và Quản lý Kỹ năng trong Sản xuất

Để kết thúc, vì chúng ta cũng gần hết thời gian để tóm tắt cấu trúc. Đây là cấu trúc mà họ đề xuất. Tôi thấy nó rất dễ triển khai để bắt đầu. Sau này, bạn có thể chuyển sang các kịch bản đánh giá phức tạp hơn như chạy trên Docker hoặc trong môi trường biệt lập để đảm bảo rằng bạn có một môi trường mới chỉ với một kỹ năng mà bạn đang kiểm tra trong bộ của mình. Nhưng về cơ bản, bạn chỉ cần đặt hai điều kiện: có và không có kỹ năng, so sánh các kết quả và chạy chúng trên agent harness mà bạn muốn, sau đó so sánh các kết quả ở đó. Đây về cơ bản là pipeline đánh giá đầu tiên của bạn để tự động kiểm tra kỹ năng.

Về phía tôi, đó là tất cả. Tôi hy vọng bạn thấy hội thảo này hữu ích để nâng cao kỹ năng của mình và sẵn sàng cho môi trường sản xuất. Như tôi đã nói lúc đầu, tôi sẽ có một buổi nói chuyện vào ngày mai về cách chúng tôi đã triển khai và tạo ra kỹ năng Superbase cho chính sản phẩm đó. Cách chúng tôi giữ cho nó có thể bảo trì được đồng thời đảm bảo nó mang lại giá trị và hiện đang kiểm thử nó trong môi trường sản xuất. Cảm ơn bạn.

Hỏi đáp: Quản lý Số lượng Kỹ năng

Hỏi: Tôi có một câu hỏi về số lượng kỹ năng mà bạn thường cài đặt trong môi trường của mình, bởi vì với cơ chế progressive disclosure này, có vẻ như chúng ta có thể tiếp tục thêm các kỹ năng khác nhau và tác nhân sẽ tự động tìm thấy chúng. Bạn có khuyến nghị nào về số lượng kỹ năng nên có không, hay có giới hạn nào không, hay chúng ta chỉ nên tiếp tục thêm vào và nó sẽ hoạt động một cách kỳ diệu?

Đáp: Vâng. Có lẽ tôi không phải là người tốt nhất để nói về điều này vì rất dễ để bạn rơi vào vòng luẩn quẩn của việc, đặc biệt là khi bạn đang thử nghiệm, có rất nhiều kỹ năng như bạn đã thấy. Tôi đã cài đặt rất nhiều trong số chúng một cách toàn cầu và tôi nghĩ công bằng mà nói là tôi sử dụng tất cả chúng hàng ngày. Nhưng điều đó còn tùy thuộc vào việc bạn có sử dụng chúng trên máy cục bộ của mình hay không. Tôi nghĩ khá dễ để bạn có một môi trường lộn xộn với tất cả hoặc hầu hết chúng được cài đặt. Đối với môi trường cục bộ của bạn, hiện tại tôi sẽ không, vì đây là giai đoạn thử nghiệm hoặc theo ý kiến cá nhân của tôi, tôi sẽ không tự giới hạn mình về quản lý không gian hoặc quản lý ngữ cảnh liên quan đến progressive disclosure. Đây là một điều rất mạnh mẽ mà bạn có thể khám phá. Trong trường hợp này, chắc chắn nếu bạn có các kỹ năng mà bạn không sử dụng, chúng sẽ lấp đầy cửa sổ ngữ cảnh của bạn, nhưng mô tả của chúng rất nhỏ nên bạn có thể không cần xóa chúng nếu không muốn.

Trong môi trường sản xuất, hãy coi chúng như bất kỳ artifact nào bạn có trong CI của mình. Vì vậy, hãy giữ cho nó sạch sẽ. Trong môi trường sản xuất, trong CI của bạn, tôi sẽ chỉ giữ lại những kỹ năng chính xác mà bạn đang sử dụng trong trường hợp cụ thể đó.

Một thông tin khác mà tôi có thể cung cấp cho bạn về phần sản xuất là ngày càng phổ biến hơn khi bạn xuất kỹ năng hoặc làm cho kỹ năng có sẵn trên các repo của mình như một phần tài liệu khác. Vì vậy, hãy coi các kỹ năng mà bạn đưa vào sản xuất như tài liệu thực tế mà bạn sẽ đọc tài liệu. Điều quan trọng là bạn phải cập nhật chúng, bao gồm quy trình làm việc cập nhật vào CLAUDE.md hoặc agents.mmd của bạn. Để bạn đảm bảo rằng nếu có bất kỳ thay đổi nào, bạn cũng sẽ thay đổi kỹ năng này, giống như bạn làm với tài liệu nếu một tính năng hoặc quy trình làm việc thay đổi. Thỉnh thoảng, bạn cũng có thể tạo một job để kiểm tra xem kỹ năng có còn chạy một quy trình làm việc hợp lý hay không. Bằng cách nào đó, bạn có thể kiểm tra xem kỹ năng đã được người dùng của bạn tải hay chưa. Nếu nó chưa được người dùng của bạn tải trong một thời gian dài, liệu nó có còn ý nghĩa khi có mặt ở đó không?

Vâng, đây về cơ bản là lời khuyên mà tôi có thể đưa ra cho bạn về kỹ năng trong môi trường sản xuất dựa trên kinh nghiệm của tôi. Đối với phần còn lại, bạn sẽ phải đến buổi nói chuyện vào ngày mai để tìm hiểu. Chúng tôi đang đưa nó vào sản xuất trên Superbase.

Kết luận và Liên hệ

Còn câu hỏi nào nữa không? Tôi sẽ có mặt trong suốt sự kiện. Vì vậy, nếu bạn gặp tôi, nếu bạn đi ngang qua, hãy thoải mái hỏi tôi bất cứ điều gì. Hãy kể cho tôi nghe về những gì bạn đang xây dựng. Rất muốn biết nếu nó dùng Superbase. Thậm chí còn vui hơn khi nghe về nó.

Và từ phía tôi một lần nữa, xin cảm ơn rất nhiều. Các bạn thật tuyệt vời hôm nay vào lúc 9 giờ sáng. Khá hay. Năng lượng tốt. Vậy thì từ phía tôi, chúc các bạn tận hưởng phần còn lại của hội nghị và hẹn gặp lại. Cảm ơn. Tuyệt vời!

Góp ý / Báo lỗiPhát hiện sai sót hoặc có ý tưởng cải thiện?