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

OpenAI + @Temporalio : Building Durable, Production Ready Agents - Cornelia Davis, Temporal

TL;DR

  • Bài thuyết trình giới thiệu sự tích hợp giữa OpenAI Agents SDK và Temporal, hai công nghệ quan trọng để xây dựng các ứng dụng AI bền vững và có khả năng phục hồi.
  • OpenAI Agents SDK cho phép các Mô hình Ngôn ngữ Lớn (LLM) chủ động điều khiển luồng ứng dụng thông qua các tác nhân, trong khi Temporal cung cấp độ bền vững và khả năng chịu lỗi cho hệ thống phân tán.
  • Sự kết hợp này giúp nhà phát triển dễ dàng tạo ra các tác nhân AI mạnh mẽ, tự động xử lý các vấn đề như thử lại, quản lý trạng thái và lỗi, giảm đáng kể chi phí vận hành.

Điểm chính

  • Định nghĩa OpenAI Agents SDK: SDK này trao quyền chủ động cho các Mô hình Ngôn ngữ Lớn (LLM) để chúng quyết định luồng của ứng dụng, hoạt động như "tác nhân" và tương tác với các công cụ bên ngoài.
  • Vòng lặp tác nhân (Agentic Loop): Mỗi lần gọi runner.run tương ứng với một Agent Loop riêng biệt, là một chu trình liên tục nơi LLM đưa ra quyết định, gọi các công cụ, xử lý đầu ra và lặp lại cho đến khi hoàn thành.
  • Temporal như một dịch vụ nền (Backing Service): Temporal là một dự án mã nguồn mở, hoạt động như một dịch vụ nền cung cấp độ bền vững của hệ thống phân tán, giúp xử lý các phức tạp của lỗi, thử lại và quản lý trạng thái.
  • Lợi ích về độ bền vững: Với Temporal, nhà phát triển có thể tập trung vào logic nghiệp vụ của mình (ví dụ: các cuộc gọi API tới LLM) mà không phải lo lắng về việc giới hạn tốc độ (rate limiting), lỗi tạm thời của API hạ nguồn, hoặc sự cố ứng dụng, vì Temporal tự động xử lý thử lại và lưu trữ trạng thái.
  • Khái niệm trừu tượng cốt lõi (Activities & Workflows): Các nhà phát triển sử dụng Temporal SDK để định nghĩa activity (các phần công việc có thể tương tác bên ngoài và có thể thất bại) và quy trình làm việc (logic nghiệp vụ điều phối các activity này).
  • Các tính năng hệ thống phân tán tích hợp: Temporal SDK có rất nhiều logic tích hợp sẵn để xử lý các thuật toán phức tạp của hệ thống phân tán như tính đồng thời (concurrency), quorum, hàng đợiquản lý trạng thái (thông qua event sourcing).
  • Giảm thiểu chi phí vận hành: Việc áp dụng Temporal (đặc biệt là Temporal Cloud) có thể giúp các tổ chức chuyển tỷ lệ thời gian từ việc quản lý cơ sở hạ tầng (như Kafka hoặc Redis) sang phát triển logic nghiệp vụ cốt lõi (ví dụ: từ 25/75 sang 75/25).
  • Hỗ trợ ngôn ngữ rộng rãi và giấy phép mã nguồn mở: Temporal hỗ trợ chính thức bảy ngôn ngữ lập trình khác nhau (và nhiều ngôn ngữ thử nghiệm khác), được cấp phép chủ yếu dưới MITApache 2.0.

Từ vựng

  • OpenAI Agents SDK — OpenAI Agents SDK
  • Temporal — Temporal
  • hệ thống phân tán — distributed system
  • AI tạo sinh (Gen AI) — Generative AI
  • Mô hình Ngôn ngữ Lớn (LLM) — Large Language Model (LLM)
  • Vòng lặp tác nhân — Agent Loop
  • công cụ — tools
  • độ bền vững của hệ thống phân tán — distributed systems durability
  • logic nghiệp vụ — business logic
  • quy trình làm việc / activity — workflow / activity

Nội dung chi tiết

Chào mừng và Khảo sát đối tượng

Tôi sẽ giới thiệu bản thân trong giây lát, nhưng trước tiên tôi muốn tìm hiểu một chút về các bạn. Các bạn có thể thấy hai thương hiệu trên màn hình ở đây: đó là OpenAI Agents SDK nói riêng, và Temporal. Tôi làm việc cho Temporal. Tôi sẽ nói thêm về bản thân mình sau. Tôi tò mò muốn biết có bao nhiêu bạn đang sử dụng OpenAI Agents SDK hôm nay? Được, khoảng một phần tư các bạn. Có framework tác nhân nào khác không? Được, cũng chừng đó. Vậy có vẻ như khá nhiều bạn chưa sử dụng một framework tác nhân nào cả. Vì vậy, tôi sẽ giới thiệu cho các bạn một chút về nó. Được. Câu hỏi tiếp theo. Có bao nhiêu bạn đang làm việc với Temporal? Không nhiều lắm. Tuyệt vời! Tôi sẽ giới thiệu cho các bạn một số điều. Được, vậy là tốt.

Hôm nay chúng ta sẽ nói về cả hai công nghệ này. Tôi sẽ trình bày riêng lẻ từng cái, nhưng tôi sẽ dành nhiều thời gian để nói về chúng cùng nhau. Tiết lộ trước, chúng tôi thực sự có một sự tích hợp giữa hai sản phẩm mà TemporalOpenAI đã cùng nhau phát triển. Và bạn sẽ thấy, nó thực sự rất thú vị.

Giới thiệu diễn giả và kinh nghiệm

Hãy để tôi tự giới thiệu một cách ngắn gọn. Tên tôi là Cornelia Davis. Tôi là chuyên gia phát triển (developer advocate) tại Temporal. Tôi đã dành rất nhiều thời gian, tôi nghĩ phần lớn sự nghiệp của mình, trong không gian hệ thống phân tán (distributed system). Tôi đã rất may mắn khi làm việc tại Pivotal, phát triển Cloud Foundry từ đầu những năm 2010. Vì vậy, tôi thực sự đã có mặt trong phong trào chuyển đổi sang kiến trúc microservice, hệ thống phân tán và những thứ tương tự. Có ai trong phòng này biết về Cloud Foundry không? Ồ, chỉ một vài người. Với những ai không biết Cloud Foundry, Cloud Foundry là một công nghệ vùng chứa (container) đời đầu trên thị trường. Nó được ươm tạo như một dự án mã nguồn mở tại VMware. Và nó đã sử dụng hình ảnh vùng chứa (container images), vùng chứa Linux (Linux containers), điều phối vùng chứa (container orchestration), tính nhất quán cuối cùng (eventual consistency) – tất cả những thứ đó, trước cả khi Docker và Kubernetes tồn tại. Vì vậy, tôi rất, rất may mắn khi có mặt ở buổi đầu của phong trào chuyển đổi sang các nền tảng hỗ trợ phương thức làm việc linh hoạt hơn, dựa trên hệ thống phân tán này. Và vì tôi đã dành rất nhiều thời gian trong thế giới microservice, tôi cũng đã viết cuốn sách này.

Nội dung trình bày

Vậy, hôm nay chúng ta sẽ nói về OpenAI Agents SDK. Sau đó, tôi sẽ cung cấp cho bạn tổng quan về Temporal. Tôi sẽ thực hiện nhiều bản trình diễn và tôi sẽ giới thiệu các repo (kho lưu trữ mã nguồn) nếu bạn muốn theo dõi. Bạn có thể truy cập và tải các repo về. Cả hai bản trình diễn của tôi, tôi thực sự đã thay đổi sáng nay, vì vậy chúng nằm trong các nhánh (branches) thay vì các nhánh chính (main branches), nhưng tôi cũng sẽ làm rõ điều đó. Tôi sẽ thực hiện nhiều bản trình diễn ở đó, và sau đó tôi sẽ chuyển sang phần kết hợp giữa OpenAI Agents SDKTemporal, và chúng ta sẽ thực hiện thêm các bản trình diễn ở đó nữa. Và sau đó, tôi sẽ nói một chút về việc điều phối các tác nhân (orchestrating agents) theo nghĩa chung.

Đây là một notebook mà tôi sẽ không sử dụng hôm nay. Tôi đã tổ chức workshop này vào đầu tuần và tôi quyết định rằng đối với cộng đồng AI, nó quá cơ bản. Tuy nhiên, nếu bạn quan tâm, bạn có thể truy cập vào đó. Nó sẽ hướng dẫn bạn thiết lập với Jupyter notebooks. Bạn có thể chạy nó trong code spaces trên GitHub, và bạn có thể chạy tác nhân OpenAI Agents SDK đầu tiên của mình. Sau đó, bạn có thể chạy ứng dụng Temporal 101 đầu tiên của mình. Sau đó, bạn có thể theo dõi toàn bộ nội dung chương trình theo cách đó. Nhưng nó khá cơ bản, và tôi quyết định rằng đối với đối tượng này, tôi muốn làm điều gì đó nâng cao hơn. Vì vậy, chúng ta sẽ không sử dụng notebook đó hôm nay, và tôi vừa tạo một số bản trình diễn này sáng nay.

Tổng quan về OpenAI Agents SDK

Không để các bạn chờ đợi lâu, đây sẽ là phần ngắn nhất của bài thuyết trình, tôi sẽ giới thiệu về OpenAI Agents SDK. Nó được ra mắt vào khoảng tháng Năm. Tôi sẽ không đọc cho các bạn nghe những slide này. Và ồ, để các bạn biết chúng ta sẽ đi đâu, tôi sẽ sử dụng một số slide vì tôi là một trong những người nghĩ rằng hình ảnh thực sự hữu ích. Tôi có rất nhiều biểu đồ ở đây, nhưng chúng ta cũng sẽ dành nhiều thời gian để đi sâu vào mã nguồn.

Định nghĩa Tác nhân AI

Tôi không nghĩ mình cần định nghĩa tác nhân. Tôi sẽ nói với bạn rằng, đối với cá nhân tôi, sự khác biệt mà tôi tạo ra giữa các ứng dụng AI tạo sinh (Gen AI) và khi chúng trở thành tác nhân là khi chúng ta trao quyền chủ động cho các Mô hình Ngôn ngữ Lớn (LLM). Khi các LLM là những thứ quyết định luồng của ứng dụng, đó đối với tôi chính là một tác nhân. Và các framework này, như OpenAI Agents SDK, được thiết kế để giúp bạn bắt đầu dễ dàng hơn với chúng. Và trên thực tế, chúng ta sẽ thấy sự tương phản về điều đó với hai bản trình diễn chính mà tôi sẽ giới thiệu cho bạn hôm nay.

Cấu trúc cơ bản của một Tác nhân

Nó có sẵn cả trong Python và TypeScript. Và đây là ứng dụng cơ bản nhất. Bạn có thể thấy ở đây là chúng ta đã định nghĩa một tác nhân. Chúng ta đã đặt tên cho nó, và chúng ta đã cung cấp lời nhắc (instructions) cho nó, và nó đã lấy các giá trị mặc định cho phần còn lại. Có những thứ được mặc định, như bản thân mô hình (model). Tôi không biết giá trị mặc định hiện tại là gì. Và sau đó, tất cả những gì bạn cần làm là chạy nó.

Vòng lặp tác nhân (Agentic Loop)

Mỗi khi bạn thấy runner.run, điều đó tương ứng với một Agent Loop. Và chúng ta sẽ nói về Agent Loop nhiều lần trong suốt bài thuyết trình. Mỗi khi bạn thấy một trong những runner.run đó, đó là một Agent Loop riêng. Và khi chúng ta đến phần orchestration (điều phối) sau này, bạn sẽ hiểu tại sao tôi lại phân biệt như vậy.

Nó cũng, như tôi đã nói, rất đơn giản ở đây, nhưng nó có rất nhiều tùy chọn khác mà bạn có thể cấu hình cho tác nhân, các cấu hình điều khiển cách Agent Loop hoạt động. Bạn có thể có handoffs. Chúng ta sẽ nói về điều đó. Vì vậy, tôi sẽ làm rõ điều đó sau, nhưng bạn có thể thiết lập hàng rào bảo vệ (guardrails). Bạn có thể thêm công cụ (tools). Và cả hai ví dụ của tôi đều tập trung mạnh vào quyền chủ động của LLM, và nó sẽ quyết định sử dụng công cụ nào. Vì vậy, tôi sẽ trình bày các công cụ. Có rất nhiều điều bạn có thể làm ở đây, và tôi sẽ chỉ cho bạn các ví dụ khi chúng ta tiếp tục.

Thực sự, đây là bức tranh về những gì tôi đang nói. Mỗi runner.run về cơ bản có một vòng lặp liên tục quay trở lại LLM. Và sau cuộc API call đến LLM, nó quyết định thực hiện các hành động. Nếu LLM, ví dụ, đã nói rằng tôi muốn bạn gọi một số công cụ, nó sẽ tiến hành gọi những công cụ đó. Và sau đó, nó sẽ lấy đầu ra từ các công cụ và chuyển trở lại LLM và tiếp tục. Và LLM sẽ quyết định khi nào nó hoàn thành, tuân theo các lời nhắc hệ thống (system instructions). Và chúng ta sẽ thấy điều đó. Vậy đó là tổng quan cơ bản về framework tác nhân. Và có rất nhiều framework tác nhân ngoài kia.

Tổng quan về Temporal

Vì rất ít bạn biết Temporal, tôi sẽ nói chậm lại một chút ở đây và giới thiệu thêm về Temporal.

Temporal và Hệ thống phân tán

Temporal là một dự án mã nguồn mở. Nó đã tồn tại được khoảng năm hoặc sáu năm. Vâng, nó đã có từ trước sự bùng nổ AI tạo sinh (Gen AI) mà chúng ta đang trải qua. Nó được thiết kế cho các hệ thống phân tán. Và các ứng dụng AI là gì nếu không phải là hệ thống phân tán? Vì vậy, hóa ra Temporal rất phù hợp cho loại trường hợp sử dụng này.

Temporal như một dịch vụ nền (Backing Service)

Hiện tại, nó được sử dụng trong rất nhiều trường hợp không phải AI. Ví dụ, mọi snap của Snapchat đều chạy qua Temporal. Mọi đặt phòng Airbnb đều chạy qua Temporal. Các đơn hàng Pizza Hut, Taco Bell đều chạy qua Temporal. Có rất nhiều trường hợp khác mà tôi không nhớ. OpenAI Codex chạy trên Temporal. Vì vậy, bây giờ chúng ta bắt đầu chuyển sang các trường hợp sử dụng AI. Codex chạy trên Temporal. Image gen của OpenAI chạy trên Temporal. Đó là hai điều tôi có thể nói với bạn. Đó là hai điều được công chúng biết đến. Vì vậy, chúng ta có rất nhiều ứng dụng khác đang chạy trên Temporal. Vậy là chúng ta chắc chắn đang tạo ra nhiều tiến bộ trong không gian AI.

Tôi đã nói cho bạn biết ai đang sử dụng nó. Nhưng hãy để tôi nói cho bạn biết nó là gì. Nó là các hệ thống phân tán như một dịch vụ nền (backing service). Tôi nghĩ mọi người đều quen thuộc với khái niệm Redis như một dịch vụ nền, hoặc Kafka như một dịch vụ nền, hoặc một cơ sở dữ liệu như một dịch vụ nền. Vì vậy, tôi có các ứng dụng của mình đang chạy và tôi sử dụng các dịch vụ backend này để đóng một phần trong ứng dụng của mình. Temporal là một dịch vụ nền.

Độ bền vững của hệ thống phân tán (Distributed Systems Durability)

Điều mà Temporal mang lại là độ bền vững của hệ thống phân tán (distributed systems durability). Và tôi sẽ làm rõ điều đó hơn khi chúng ta đi sâu vào bài thuyết trình. Điều đó có nghĩa là bạn, với tư cách là nhà phát triển, có thể lập trình "lộ trình hạnh phúc" (happy path). Bạn có thể lập trình logic nghiệp vụ (business logic) của mình. Và logic nghiệp vụ mà chúng ta sẽ lập trình hôm nay là các tác nhân AI. Vì vậy, bạn có thể nói, bạn biết không? Điều tôi muốn làm là gọi một LLM. Sau đó, tôi muốn lấy đầu ra từ LLM. Và tôi có thể muốn gọi một số API khác. Và sau đó tôi muốn quay trở lại LLM. Và bạn không cần phải xây dựng logic trong đó để nói rằng, điều gì xảy ra nếu LLM bị giới hạn tốc độ (rate limited)? Điều gì xảy ra nếu API downstream của tôi bị lỗi tạm thời? Điều gì xảy ra nếu ứng dụng của tôi gặp sự cố? Bạn không cần phải lập trình bất kỳ điều nào trong số đó. Chúng tôi làm điều đó cho bạn. Và tôi sẽ chỉ cho bạn một vài hình ảnh về cách điều này hoạt động trong giây lát.

Cách Temporal SDK hoạt động

Vậy có một dịch vụ Temporal là dịch vụ nền. Và cách bạn kết nối với dịch vụ nền là thông qua một SDK. Và SDK đó nằm bên cạnh logic nghiệp vụ của bạn. Vì vậy, bạn có thể lập trình logic nghiệp vụ của mình. Và cách bạn tạo logic nghiệp vụ của mình là bạn đặt các "wrapper" xung quanh một số hàm nhất định. Và điều đó cho phép SDK nói, "Ồ, khoan đã. Nếu bạn đang thực hiện một API call downstream, tôi sẽ can thiệp và cung cấp cho bạn một số dịch vụ." Vì vậy, tôi sẽ cung cấp cho bạn các lần thử lại (retries). Nếu dịch vụ downstream đó thành công, tôi sẽ ghi lại điều đó cho bạn. Tôi sẽ ghi lại câu trả lời cho bạn để trong trường hợp có điều gì đó xảy ra và chúng ta cần thực hiện lại luồng, tôi có thể chỉ cần lấy kết quả mà bạn đã gọi trước đó.

Điều đó có nghĩa là, ví dụ, nếu bạn đã sử dụng Temporal để cung cấp độ bền vững cho các tác nhân của mình, khi bạn đang ở lần API call thứ 1350 đến LLM và ứng dụng của bạn gặp sự cố, đừng lo lắng. Chúng tôi đã theo dõi mọi cuộc API call đến LLM và kết quả trả về, và bạn sẽ không phải "đốt" lại những mã thông báo (tokens) đó. Đó là ý nghĩa của độ bền vững trong không gian này.

Hỗ trợ ngôn ngữ và Giấy phép

Chúng tôi chính thức hỗ trợ bảy ngôn ngữ lập trình khác nhau, nhưng Apple vừa phát hành Swift SDK vài tuần trước. Vì vậy, có sự hỗ trợ trong hầu hết mọi ngôn ngữ. Cũng có những thứ thử nghiệm khác ngoài kia, trong Clojure, những thứ tương tự. Tôi đã nói nó là một dự án mã nguồn mở. Phần lớn trong số đó được cấp phép MIT. Có một chút Apache 2.0 license còn lại trong Java SDK. Vì vậy, các giấy phép rất, rất rộng rãi. Và những ai không biết lịch sử, Temporal là một nhánh của một dự án được tạo ra từ Uber có tên là Cadence. Có ai biết Cadence không? Vâng, được, vậy một vài người biết Cadence. Vì vậy, Cadence, hầu hết mọi ứng dụng chạy tại Uber đều chạy trên Cadence. Và đó là vì họ có thể lập trình "lộ trình hạnh phúc" và tất cả độ bền vững đều được xử lý cho bạn. Đó là tổng quan về Temporal.

Các khái niệm trừu tượng nền tảng của Temporal: Activity

Vậy tôi sẽ nói về hai khái niệm trừu tượng nền tảng. Cũng có một vài khái niệm khác. Nhưng hai khái niệm trừu tượng nền tảng mà bạn cần biết với tư cách là nhà phát triển là bạn cần biết về một activity. Và một activity chỉ là một phần công việc. Đây là công việc có thể thực hiện các API call bên ngoài. Vì vậy, đó là công việc có thể thất bại. Đó giống như rất nhiều công việc có thể thất bại. Hoặc nếu bạn đang thực hiện rất nhiều công việc mà bạn không muốn phải làm lại trong trường hợp có điều gì đó không ổn, bạn cũng có thể muốn đặt điều đó vào một activity. Vì vậy, đó là những thứ như rút tiền khỏi tài khoản, gửi tiền vào tài khoản. Chúng ta sẽ chuyển sang các trường hợp sử dụng AI trong giây lát. Vì vậy, đó là các activity. Bạn bao bọc điều đó.

Trí thông minh trong Temporal SDK

Ồ, và tôi chưa đề cập đến điều này. Nhưng các SDK không chỉ là những wrapper mỏng nằm trên đỉnh của REST API. Đây là các SDK mà, như bạn có thể tưởng tượng, việc cung cấp độ bền vững trên các hệ thống phân tán có nghĩa là tất cả những thuật toán mà bạn nghĩ rằng mình phải triển khai, như lo lắng về tính đồng thời (concurrency) và quorum và tất cả những thứ đó, tất cả đều được triển khai trong Temporal. Và vì vậy, các SDK của chúng tôi có rất nhiều logic đó nằm trong SDK. Dịch vụ chủ yếu là để lưu trữ (persistence) cho việc đó. Vì vậy, có rất nhiều trí thông minh trong SDK.

Hoạt động và Quy trình làm việc (ActivitiesWorkflows)

Vì vậy, những hoạt động này, nếu bạn đã nói: "Hãy xem, đây là công việc của tôi. Đây là một công việc nặng nhọc hoặc một thứ gì đó sẽ tương tác bên ngoài. Chúng ta hãy đặt một activity decorator lên đó." Sau đó, SDK sẽ nói: "Ồ, được thôi, tôi sẽ cung cấp cho bạn một số hành vi đặc biệt." Tiếp theo, bạn sẽ orchestrate các hoạt động đó lại với nhau vào logic nghiệp vụ của mình. Và những gì chúng tôi gọi là các orchestration đó chính là các quy trình làm việc. Vì vậy, bạn sẽ thấy rằng điều kỳ diệu thực sự xảy ra khi bạn kết hợp các hoạt động và quy trình làm việc với nhau. Có một mức độ kỳ diệu nào đó trong các hoạt động. Trên thực tế, chúng tôi vừa bắt đầu phát hành cái mà chúng tôi gọi là các hoạt động độc lập. Do đó, bạn sẽ có thể sử dụng các hoạt động mà không cần quy trình làm việc và cũng nhận được một số lợi ích về độ bền. Vì vậy, có đủ loại sự phát triển đang diễn ra.

Thử lại và Hệ thống phân tán tích hợp

Nhưng loại điều kỳ diệu mà tôi đang nói đến khi bạn kết hợp các quy trình làm việc và hoạt động lại với nhau là tôi đã phủ lên đây một loạt các biểu tượng. Vì vậy, tôi đã phủ lên các biểu tượng thử lại nhỏ này. Điều bạn làm là bạn chỉ định trong logic quy trình làm việc của mình, bạn chỉ định cấu hình thử lại. Vì vậy, bạn có thể quyết định: Bạn sẽ thực hiện thử lại theo cấp số nhân? Bạn sẽ thực hiện thử lại không giới hạn? Bạn sẽ dừng ở năm lần thử lại? Bạn sẽ có một khoảng thời gian tối đa giữa các lần thử lại? Bạn có thể cấu hình tất cả những điều đó. Và ngay sau khi bạn làm điều đó và bạn orchestrate những thứ này lại với nhau, bạn sẽ có các lần thử lại. Và bạn sẽ thấy mã trong ít phút nữa. Đơn giản bằng cách gọi các hoạt động này, tôi không cần phải triển khai logic thử lại. Tôi không cần phải triển khai bất kỳ logic nào khác. Nó tự động xảy ra.

Vì vậy, tôi có các lần thử lại. Tôi cũng nhận được những hàng đợi nhỏ này. Vậy điều gì đối với bạn trông giống như một ứng dụng một tiến trình? Tôi đang gọi cái này, rồi tôi gọi cái kia, và tôi lại gọi cái này. Mỗi lần bạn gọi vào một hoạt động, mỗi lần bạn quay trở lại từ một hoạt động về quy trình làm việc chính, tất cả đều được thực hiện thông qua các hàng đợi. Vì vậy, cái trông giống như một ứng dụng nguyên khối đơn lẻ đã biến thành một hệ thống phân tán. Vì vậy, bạn có thể triển khai một loạt các phiên bản của chúng, và về cơ bản, bạn có thể mở rộng bằng cách chỉ cần triển khai thêm các phiên bản. Bạn không cần phải quản lý các hàng đợi Kafka cues hay bất kỳ thứ gì tương tự. Tất cả đều được tích hợp sẵn. Tôi đã nói chuyện với một người tại hội nghị AI Engineers ở đây tuần này, người đó là một người dùng mã nguồn mở, thực chất là một khách hàng của chúng tôi. Và tôi đã hỏi anh ấy – đó là một công ty khởi nghiệp tương đối nhỏ – và tôi nói: "Tại sao bạn lại chọn Temporal?" Và anh ấy trả lời: "Vì chúng tôi đã cố gắng xây dựng tất cả những thứ này với các hàng đợi Kafka cues, và cuối cùng chúng tôi đã dành toàn bộ thời gian để vận hành Kafka, và chỉ dành 25% thời gian cho logic nghiệp vụ. Khi chúng tôi chuyển sang Temporal, chúng tôi dành 75% thời gian cho logic nghiệp vụ, và họ đang sử dụng Temporal Cloud." (Tôi chưa đề cập đến mô hình kinh doanh của chúng tôi là dịch vụ đó.) Chúng tôi cung cấp nó dưới dạng SaaS. Vì vậy, họ đang sử dụng Temporal Cloud. Về cơ bản, họ đã chuyển tỷ lệ từ 25/75 sang 75/25 bằng cách chuyển sang đây. Không còn phải quản lý các hàng đợi Kafka cues hay Redis hay bất cứ thứ gì tương tự.

Quản lý trạng thái và Phục hồi lỗi

Và nói về Redis, bạn thấy ở góc trên bên phải, bạn thấy phần quản lý trạng thái. Và một trong những điều chúng tôi cũng làm là chúng tôi theo dõi vị trí của bạn trong quá trình thực thi ứng dụng. Chúng tôi thực hiện điều đó bằng cách ghi lại trạng thái. Một lần nữa, mỗi khi bạn thực hiện các cuộc gọi đến một hoạt động và quay lại, chúng tôi ghi lại điều đó. Về cơ bản, đó là event sourcing. Đó là những gì chúng tôi đang làm. Nó không chỉ là các kiến trúc hướng sự kiện, mà chúng tôi đang cung cấp event sourcing dưới dạng một dịch vụ. Vì vậy, bạn có thể làm điều đó. Chúng tôi lưu trữ tất cả trạng thái đó để nếu có gì đó sai sót – và tôi sẽ làm một bản demo về điều đó, chúng ta sẽ thấy mọi thứ hoạt động không đúng – nó sẽ tiếp tục từ nơi đã dừng lại vì chúng tôi sẽ chỉ chạy qua lịch sử sự kiện và tiếp tục từ nơi đã dừng. Vì vậy, những biểu tượng nhỏ mà tôi đã cho thấy được phủ lên sơ đồ logic – tôi sẽ trả lời câu hỏi của bạn ngay lập tức. Thực ra, tất cả các dịch vụ đó đều nằm trên dịch vụ này, vì vậy chúng đều bền vững. Vì vậy, không phải chúng nằm trong tiến trình, mà chúng nằm trong dịch vụ này.

Hỗ trợ StreamingLưu trữ tải trọng lớn

Bạn có câu hỏi không? Ồ, một câu hỏi hay. Vâng, vì vậy câu hỏi là: "Rất nhiều tác nhân mà tôi đang xây dựng đang thực hiện truyền phát, liệu bạn có thực hiện truyền phát không?" Và câu trả lời hiện tại rất đơn giản là "Không, chúng tôi không." Nhưng đó là một trong những điều – và đồng nghiệp của tôi ở phía sau, Johann, là Trưởng phòng Kỹ thuật AI. Vì vậy, hãy trò chuyện với anh ấy, hoặc với bất kỳ ai trong chúng tôi. Đó là một trong hai ưu tiên hàng đầu mà chúng tôi đang thực hiện ngay bây giờ. Điều còn lại là lưu trữ tải trọng lớn. Nếu tôi không có cơ hội nói về nó ở đây trong buổi hội thảo, hãy tìm một trong số chúng tôi; chúng tôi có thể kể cho bạn nghe về điều đó. Bạn có thể hình dung lưu trữ tải trọng lớn là gì. Đó là khi bạn làm việc với các Mô hình Ngôn ngữ Lớn, bạn sẽ truyền dữ liệu lớn đi, thay vì truyền theo giá trị, bạn sẽ truyền theo tham chiếu. Đó là lưu trữ tải trọng lớn. Đó là Johann. Đúng vậy. Vâng, tôi sẽ nhắc lại những gì Johann đã nói phòng trường hợp bạn không nghe rõ. Vì vậy, chúng tôi có những khách hàng đã xây dựng hỗ trợ truyền phát trên Temporal, nhưng điều chúng tôi đang làm là xây dựng nó một cách tự nhiên (tích hợp sẵn). Vâng, bạn có thể làm điều đó ngay hôm nay; chỉ là cần thêm một chút công sức. Đó không phải là lộ trình thuận lợi. Được rồi.

Demo: Thiết lập Temporal cục bộ

Với những điều đó, tôi muốn giới thiệu cho bạn một bản demo. Đây sẽ là bản demo đầu tiên của tôi mà tôi sẽ chuyển sang đây. Để xem tôi có thể lấy lại màn hình của mình không. Được rồi, nếu bạn muốn theo dõi, điều đầu tiên tôi sẽ làm là tôi sẽ đến đây và tôi sẽ, hãy để tôi tăng kích thước phông chữ. Vì vậy, tôi sẽ chỉ cho bạn hai kho lưu trữ. Đây thực sự là kho lưu trữ thứ hai, nhưng điều tôi đang hiển thị trên màn hình hiện tại là nếu bạn muốn bắt đầu với Temporal, nó cực kỳ đơn giản: bạn không cần phải sử dụng Temporal Cloud, bạn chỉ cần chạy một Dịch vụ Temporal (dịch vụ hỗ trợ) cục bộ trên máy của mình. Vì vậy, bạn có thể thực hiện bằng cách dùng curl để tải xuống. Bạn cũng có thể cài đặt nó bằng Homebrew. Và sau đó để chạy máy chủ cục bộ đó, bạn chỉ cần gõ Temporal Server Start Dev. Và bây giờ bạn có một Dịch vụ Temporal đang chạy cục bộ. Và tất cả các ứng dụng của tôi ở đây chỉ kết nối với máy chủ cục bộ của tôi, và chúng ta sẽ thấy giao diện người dùng ngay lập tức. Tôi sẽ quay lại kho lưu trữ này ngay lập tức. Repo mà tôi sẽ trình diễn cho bạn là cái này. Và xin lỗi, tôi không biết cách tăng kích thước phông chữ, nhưng bạn có thể thấy rằng tổ chức và kho lưu trữ ở đây là tổ chức TemporalIO. Đó cũng là nơi bạn sẽ tìm thấy tất cả mã nguồn mở cho Temporal. Và sau đó chúng tôi có một thứ gọi là AI cookbook. Và đó là một trong các ví dụ. Thực ra tôi đã mở rộng ví dụ này sáng nay, và bạn sẽ tìm thấy nó trong nhánh mà chúng ta sẽ trình diễn hôm nay, có tên là Agentic Loop Branch. Vì vậy, nếu bạn muốn quay lại và tự xem xét điều này sau, đó là những gì chúng ta sẽ xem.

Giới thiệu Codebase của Agentic Loop

Được rồi, với điều đó, hãy để tôi đến thiết bị đầu cuối của mình. Và đây là nơi tôi sẽ chạy nó, nhưng trước tiên tôi muốn cho bạn xem mã nguồn. Được rồi, vậy tôi có đang ở đúng cái – OpenAI không? Không, cái này sai rồi. Con trỏ khác của tôi, đây rồi. Vì vậy, đây là Agentic Loop. Vì vậy, tôi sẽ thực hiện hai bản demo trong suốt ngày hôm nay. Và điều bạn thấy ở phía bên trái – hãy để tôi phóng to thêm một chút – là hãy nhớ rằng tôi đã nói về các hoạt động và tôi đã nói về các quy trình làm việc. Vì vậy, điều đầu tiên tôi sẽ làm là tôi sẽ cho bạn xem các hoạt động. Hãy nhớ chúng ta có "rút tiền và gửi tiền", những thứ tương tự như vậy. Ở đây, tất nhiên, điều chúng ta đang làm là một Vòng lặp Agentic. Vì vậy, các hoạt động của tôi sẽ là: gọi API của OpenAI, chưa phải Agents SDK (chỉ là OpenAI API), và sau đó gọi một số công cụ. Vì vậy, đây là hai hoạt động của tôi.

Chi tiết Activities (gọi OpenAI API)

Vậy hãy cùng xem hoạt động đầu tiên, và bạn sẽ thấy nó đơn giản đến mức nào. Tôi đã hứa với bạn về lộ trình thuận lợi; thực sự là như vậy. Vậy đây là lời gọi của tôi đến API phản hồi của OpenAI. Được rồi, nó chính xác như những gì bạn mong đợi. Tôi đang truyền vào mô hình, tôi đang truyền vào một số hướng dẫn. Đầu vào người dùng sẽ đến từ các công cụ của tôi (mà tôi sẽ cho bạn xem ngay sau đây), và sau đó tôi có một số thời gian chờ mà tôi có thể cấu hình ở đó; điều đó dành cho OpenAI. Điều tôi đã làm là tôi đã gói gọn nó trong một hàm. Nó nhận vào yêu cầu đó, vì vậy tất cả các tham số đó đến từ một yêu cầu mà tôi đang truyền vào, và bạn sẽ thấy cách tôi gọi nó ngay sau đây. Và đây là annotation đó. Hiện tại, các SDK khác nhau có các phương pháp tiếp cận khác nhau. Ví dụ, TypeScript không yêu cầu nhiều annotation. Nó tự động tìm ra và biết các hoạt động nằm ở đâu. Java có các annotation và những thứ tương tự, nhưng đây là Python. Vì vậy, bạn có thể thấy ở đây rằng chúng ta chỉ có một activity decorator. Vì vậy, chỉ cần có decorator đó, bạn có thể thấy nó không hề phức tạp chút nào. Tất cả những gì bạn cần làm với tư cách là một nhà phát triển là nói: "Đây là một loạt công việc mà tôi muốn làm, mà tôi muốn đóng gói thành một bước, và bạn chỉ cần đặt nó vào một hàm, bạn đặt một activity decorator lên đó." Vì vậy, tôi sẽ quay lại trình gọi công cụ ngay sau đây vì có điều gì đó thú vị đang diễn ra ở đây.

Chi tiết Workflow (vòng lặp LLM và gọi công cụ)

Vậy bây giờ nếu chúng ta đi đến quy trình làm việc, quy trình làm việc cũng khá là đơn giản. Vì vậy, những gì tôi có ở đây là định nghĩa quy trình làm việc của tôi. Bạn có thể thấy đó là một lớp. Lý do nó là một lớp là vì khi bạn tạo một quy trình làm việc, bạn tạo luồng chính của ứng dụng (cái mà tôi gọi là luồng chính của ứng dụng), và đó là cái có workflow.run trên đó. Nhưng quy trình làm việc này cũng vậy – tôi sẽ không đề cập đến các trừu tượng hóa này hôm nay – nhưng chúng tôi có một vài trừu tượng hóa khác như tín hiệu. Vì vậy, đối với một quy trình làm việc đang chạy, bạn có thể gửi tín hiệu vào đó, và chúng tôi cũng có một trừu tượng hóa gọi là update. Đó là một loại tín hiệu đặc biệt, và chúng tôi cũng có cái tương tự, đó là các truy vấn. Vì vậy, những thứ đó được thêm vào lớp quy trình làm việc này dưới dạng các hàm được chú thích bằng signal, update hoặc query. Vì vậy, đó là lý do tại sao chúng tôi có một lớp cho quy trình làm việc. Và nếu chúng ta xem xét logic bên trong, bạn có thể thấy rằng tôi có một vòng lặp while true. Vì vậy, ứng dụng đơn giản này chỉ là bức tranh tương tự mà tôi đã cho bạn xem trước đó, nơi tôi nói LLM, chúng ta chỉ đang lặp trên LLM. Và nếu Mô hình Ngôn ngữ Lớn đưa ra quyết định làm như vậy, chúng ta sẽ gọi các công cụ. Đó là toàn bộ ứng dụng. Nhưng bạn sẽ thấy rằng tôi đang thực hiện một vài điều thú vị với Temporal ở đây. Vì vậy, để gọi Mô hình Ngôn ngữ Lớn, tôi thực thi hoạt động đó. Vì vậy, bạn có thể thấy rằng tôi đang truyền vào mô hình của mình. Các hướng dẫn ở đây, tôi sẽ không cho bạn xem, nhưng bạn có thể thấy tất cả trong kho lưu trữ. Lời nhắc hệ thống tác nhân hữu ích về cơ bản chỉ nói: "Bạn là một tác nhân hữu ích." "Nếu người dùng nói điều gì đó, và bạn nghĩ rằng bạn nên sử dụng một công cụ, hãy cho tôi biết, bạn biết đấy, hãy chọn một công cụ." "Nếu không, hãy phản hồi bằng haikus. Bạn sẽ thấy điều đó ngay lập tức." Giống như, haikus giống như món khai vị của thế giới Trí tuệ nhân tạo, phải không? Tất cả chúng ta đều sẽ viết các tác nhân. Nó là chương trình "hello world" của không gian tác nhân. Vì vậy, chúng ta sẽ phản hồi bằng haikus. Và đó là tất cả. Vì vậy, chúng ta đang thực hiện điều này trong một vòng lặp while true. Và tôi có một vài câu lệnh in ở đó. Bạn sẽ thấy điều này chạy như thế nào ngay lập tức. Giả định đơn giản hóa ở đây: Tôi đang giả định rằng nó chỉ gọi một công cụ tại một thời điểm, vì vậy tôi đang lấy đầu ra của công cụ đó. Và sau đó tôi chỉ cần nhìn vào nó và nói: "Đây có phải là một lời gọi hàm không?" Và nếu đó là một lời gọi hàm, thì tôi sẽ xử lý lời gọi hàm đó. Tôi sẽ cho bạn xem mã đó ngay lập tức. Và sau đó tôi sẽ lấy đầu ra từ lời gọi hàm đó và tôi sẽ thêm nó vào lịch sử hội thoại. Vì vậy, tôi không thực hiện bất kỳ kỹ thuật ngữ cảnh phức tạp nào ở đây. Không có điều đó. Tôi chỉ đơn giản là gắn thêm vào cuối lịch sử hội thoại. Được chứ? Bây giờ, việc xử lý lời gọi hàm cũng rất đơn giản. Vì vậy, điều đầu tiên tôi đang làm là tôi đang thêm phản hồi từ Mô hình Ngôn ngữ Lớn. Vì vậy, khi chúng ta hoàn thành lời gọi hàm này, chúng ta sẽ đã thêm hai thứ vào lịch sử hội thoại. Chúng ta sẽ thêm phản hồi từ Mô hình Ngôn ngữ Lớn nói rằng: "Vui lòng thực hiện một lời gọi hàm." Và sau đó chúng ta sẽ thực hiện lời gọi hàm và sau đó chúng ta sẽ thêm kết quả. Và tôi vừa cho bạn xem nơi chúng ta đang thêm kết quả của lời gọi hàm. Vì vậy, ở đây, đây chỉ là tôi thêm điều đó vào... và đây là một số chi tiết phức tạp nhất.

Xử lý Định dạng và Lệnh Gọi Công cụ

Tôi có ứng dụng này chạy với API Gemini. Và điều khó khăn lớn nhất trong tất cả những việc này là các định dạng khác nhau. Vì vậy, tôi phải viết lại bởi vì các định dạng JSON của lịch sử trò chuyện là khác nhau giữa các mô hình khác nhau. Vâng, tôi biết có các khung làm việc LLM ngoài kia, nhưng tôi không thích những mẫu số chung nhỏ nhất và tôi cũng muốn hiểu các định dạng đó trông như thế nào. Nhưng bạn có thể thấy ở đây rằng tôi chỉ đang thực hiện một số phân tích cú pháp không được đẹp cho lắm. Và sau đó tôi đang thực thi – hãy nhớ, tôi đang xử lý lệnh gọi công cụ ở đây. Tôi đang thực thi hoạt động với lệnh gọi công cụ đó. Vì vậy, tôi đã lấy lệnh gọi công cụ ra khỏi phản hồi từ LLM. Và sau đó tôi sẽ kích hoạt hoạt động đó, đó là thực thi hoạt động và tên mục là công cụ.

Mô hình Agentic và Hoạt động Động

Một trong những điều tôi thực sự muốn ở đây là tôi không muốn xây dựng một ứng dụng Agent Loop duy nhất chỉ thực hiện một tập hợp các công cụ. Và sau đó phải xây dựng lại một ứng dụng hoàn toàn khác khi tôi có một tập hợp các công cụ khác. Bản thân tác nhân – và chúng ta đã nghe, tôi không nhớ ai đã nói về điều này nhưng ai đó đã nói về điều này trên sân khấu tuần này – rằng mô hình agentic khá chuẩn. Và điều chúng ta đang làm bây giờ là chúng ta đang chèn mọi thứ vào Agent Loop đã được tiêu chuẩn hóa. Và đó chính xác là điều mà các khung làm việc AI này, các khung làm việc tác nhân này đang làm. Và tôi cũng muốn làm điều đó ở đây trong mã Temporal.

Điều thú vị là Temporal có một thứ gọi là hoạt động động. Hoạt động động cho phép bạn gọi một hoạt động theo tên, nhưng hoạt động đó được tìm thấy động tại thời điểm chạy. Vì vậy, bộ xử lý hoạt động ở đây – và tôi sẽ cho bạn xem mã trong giây lát – về cơ bản sẽ nhận tên đó và nói, "ồ, được rồi, tôi..." Và hãy nhớ, đây là hướng sự kiện. Vì vậy, chúng ta có một hoạt động đang chờ đợi mọi thứ trên một hàng đợi, và bạn có thể cấu hình một hoạt động, bạn có thể cấu hình một trong các worker của chúng tôi để nói, "này, đây là một worker về cơ bản sẽ lấy bất kỳ thứ gì từ hàng đợi hoạt động." Không quan trọng tên là gì. Vì vậy, bạn không cần phải liên kết chặt chẽ với một tên chủ đề cụ thể, ví dụ. (Có) vâng, câu hỏi?

Quản lý Mô-đun Công cụ

Điều đó là riêng biệt. Tôi sẽ cho bạn xem mô-đun đó. Có một mô-đun ở đây mà bạn thấy có tên là tools. Nếu bạn thấy thư mục tools. Cách tôi chạy nó ở đây là, nó tải những thứ đó tại thời điểm tôi tải ứng dụng. Vì vậy, tôi không thực hiện bất kỳ tải động nào, nhưng tôi có thể hoán đổi mô-đun tools đó vào và ra mà mã tác nhân không thay đổi gì cả. Vì vậy, tôi không đi đến mức đã triển khai một bộ đăng ký và đang gọi động những thứ đó. Bạn có thể làm điều đó, nhưng ví dụ đơn giản này về cơ bản chỉ đặt tất cả vào một mô-đun riêng biệt và bạn sẽ thấy mô-đun đó có thể được hoán đổi vào và ra như thế nào vì tôi đang tải nó khi bắt đầu thời điểm chạy. Vì vậy, việc này đang được đơn giản hóa, nhưng vâng, bạn có thể làm điều đó.

Chi tiết Tool Invoker và Quản lý Mô tả Công cụ

Được rồi, vậy tôi sẽ gọi một hoạt động và hãy cùng xem hoạt động đó trông như thế nào. Đó là tool invoker này. Và bạn có thể thấy ở đây nó có decorator hoạt động giống như tôi đã chỉ cho bạn trước đây, nhưng bây giờ nó nói dynamic = true. Điều đó có nghĩa là bộ xử lý hoạt động này sẽ lấy bất kỳ thứ gì xuất hiện trên một hàng đợi mà chưa được hoạt động nào khác xử lý. Vì vậy, nó sẽ lấy get weather, nó sẽ lấy get random number, nó sẽ lấy bất cứ thứ gì xuất hiện ở đó. Bạn phải đăng ký, không, bạn không cần phải đăng ký tất cả những thứ đó. Những thứ đó có thể được thực hiện động. Bạn không cần phải đăng ký chúng vào worker.

Và điều bạn có thể thấy ở đây là chúng tôi về cơ bản lấy điều đó. Chúng tôi nhận tên công cụ và sau đó bạn có thể thấy ở đây tôi đang tìm kiếm hàm một cách hiệu quả. Bạn có thể thấy ở đây không có tên công cụ nào cả. Nó về cơ bản đang tìm kiếm tên công cụ từ một từ điển. Nó mang tính ẩn dụ là một từ điển. Tôi sẽ chỉ cho bạn các hàm đó trong giây lát.

Vì vậy, tôi có một hàm là hàm get tools, mà nhân tiện, hãy để tôi quay lại đó. Trong các phản hồi của OpenAI, không, xin lỗi, nó nằm trong quy trình làm việc. Khi tôi gọi LLM ở đây, hãy chú ý rằng tôi đã thực hiện lệnh gọi get tools này. Tôi sẽ chỉ cho bạn lệnh gọi get tools đó trong giây lát. Nó hoàn toàn nằm ngoài phạm vi của quy trình làm việc và các hoạt động. Nó nằm trong mô-đun riêng của nó. Tôi sẽ chỉ cho bạn hàm đó trong giây lát.

Được rồi, quay lại tool invoker. Nó về cơ bản bây giờ đang lấy tên và sau đó nó đang thực hiện get handler. Vì vậy, ở đâu đó ở đây là một lệnh gọi get handler. Đây là bộ xử lý. Tôi vừa chuyển nó. Xin lỗi. 17, cảm ơn bạn. Tôi đánh giá cao điều đó. Vì vậy, đây là get handler. Và tôi sẽ chỉ cho bạn hàm đó trong giây lát. Vì vậy, câu hỏi rất hay về việc những thứ này liên kết chặt chẽ đến mức nào. Hãy để tôi chỉ cho bạn nơi liên kết đó hiện tại.

Vì vậy, tôi có một mô-đun tools ở đây. Và cuối cùng đó là nơi tôi đã định nghĩa hai hàm đó. Vì vậy, tôi có get tools. Và get tools về cơ bản chỉ lấy danh sách các hàm. Và tôi sẽ chỉ cho bạn các hàm đó. Và các hàm mà chúng tôi đang truyền vào đây là chúng tôi đang truyền vào các đối tượng JSON được truyền cho LLM dưới dạng mô tả công cụ. Vì vậy, đây là các mô tả công cụ. Ví dụ, hãy để tôi chỉ cho bạn get weather.

Vì vậy, nếu chúng ta đi đến get weather ở đây, bạn có thể thấy rằng đối tượng JSON nằm ngay đây. Và thật thú vị vì OpenAI trong API Completions, họ có một API công khai cho phép bạn lấy bất kỳ hàm nào có doc strings và tạo JSON cho API Completions cho các công cụ. API Responses không có API công khai như vậy. Vì vậy, có một cảnh báo ở đây nói rằng API mà tôi đang sử dụng, nằm trong tool helper này. Tôi sẽ chỉ cho bạn tool helper. Đây là tool helper của tôi. Các helper. Đây rồi. Tôi đoán tôi có thể đặt nó vào tools. Là có một điều ở đó nói rằng cảnh báo. Hiện tại không có API công khai để tạo đối tượng JSON của công cụ cho API Responses. Vì vậy, tôi đang sử dụng một API nội bộ. Có một vấn đề đang mở về điều này. Vì vậy, chỉ có một cảnh báo ở đó rằng tôi đang sử dụng một API nội bộ.

Vì vậy, nếu chúng ta quay lại đó, tôi đã sử dụng một API nội bộ để chỉ lấy yêu cầu cảnh báo thời tiết của tôi, đó là một mô hình pedantic có các hàm ở đó và có một số siêu dữ liệu bổ sung xung quanh nó và tạo đối tượng JSON. Vì vậy, một lần nữa, đó là những gì bạn thấy khi chúng ta vào tác nhân, đó là những gì bạn nhận được với get tools. Bạn đang nhận được mảng các đối tượng JSON cho mỗi công cụ. Và sau đó, như tôi đã nói, get handler về cơ bản có, về cơ bản là một từ điển mà tôi đã triển khai dưới dạng một tập hợp các câu lệnh if-then. Vì vậy, nó lấy tên công cụ và sau đó nó chọn hàm thực tế là gì. Hoàn toàn độc lập. Và ví dụ cụ thể này có một tập hợp các công cụ ở đây – và tôi sẽ minh họa điều này cho bạn trong giây lát. Và bạn chỉ có thể hoán đổi những thứ đó. Hiện tại bạn phải khởi động lại tiến trình Python của mình chỉ vì cách tôi đã triển khai nó. Được chứ? Có hợp lý không? Được rồi, hãy để tôi chỉ cho bạn điều này hoạt động như thế nào.

Hoạt động của Worker và Thực thi Quy trình làm việc

Và những gì tôi có ở đây là tôi đang chạy worker. Tôi sẽ không dành nhiều thời gian ở đây để nói về worker, nhưng bạn nhớ rằng tôi đã nói rằng tất cả điều này đều hướng sự kiện. Và vì vậy có một thứ đang lấy công việc từ các hàng đợi sự kiện và sau đó thực thi các quy trình làm việc và hoạt động phù hợp dựa trên những gì nó đã lấy từ các hàng đợi sự kiện. Thứ trong Temporal làm điều đó là thứ chúng ta gọi là worker. Vì vậy, worker là một tiến trình mà bạn chạy. Với worker đó, bạn đăng ký các hoạt động và quy trình làm việcworker đó sẽ chịu trách nhiệm. Vì vậy, nó sẽ tìm kiếm những thứ trên hàng đợi để kéo ra từ đó. Worker đó tự nó là đa luồng. Vì vậy, nó không phải là một worker, một tiến trình. Nói chung, mọi người chạy. Tùy thuộc. Bạn có thể tinh chỉnh worker. Nhưng nói chung, mọi người chạy vài trăm luồng. Vì vậy, bạn chạy một worker và nó đã là một kiến trúc đa luồng đồng thời. Vì vậy, đây là một số thứ vững chắc. Temporal chỉ là những thứ tuyệt vời nhất. Nó thực sự, thực sự được thiết kế như các hệ thống phân tán.

Được rồi, vì vậy tôi đang chạy worker ở đây, đây là nơi bạn sẽ thấy các đầu ra từ các hoạt động và quy trình làm việc. Và tôi sẽ tiếp tục chạy một quy trình làm việc. Và vì vậy hãy nói, có bất kỳ cảnh báo thời tiết nào ở California không? Đó là nơi tôi đến. Và tôi nghĩ rất nhiều bạn cũng đến từ đó. Và hy vọng đó là nơi tôi sẽ quay trở lại tối nay. Và vì vậy chúng ta sẽ bắt đầu với những gì bạn có thể thấy ở đây là cách ứng dụng này được viết là về cơ bản, tôi nói, liệu tôi có đang gọi một công cụ hay không. Và vì vậy bạn có thể thấy ở đây nó nói, "ồ, tôi đã gọi get weather alerts". Và đó là những gì đang xảy ra. Vì vậy, có một lệnh gọi công cụ đang diễn ra. Và chỉ trong một lát, tôi tình cờ biết rằng ngay khi chúng ta có một vài giọt mưa ở California, có những cảnh báo khắp nơi. Vì vậy, đây rồi. Đây là rất nhiều cảnh báo thời tiết ở California. Bạn sẽ thấy tại sao tôi lại chỉ ra điều đó. Nó khá vui.

Trực quan hóa Workflow với Giao diện người dùng Temporal

Được rồi, bây giờ hãy để tôi chỉ cho bạn điều này trông như thế nào. Trong Giao diện người dùng Temporal. Vì vậy, ở đây, tôi có Giao diện người dùng Temporal. Và bạn có thể thấy rằng tôi đã chạy một loạt các quy trình làm việc sáng nay. Và vì vậy hãy để tôi làm mới điều này. Và đây là cái tôi vừa chạy. Và những gì chúng ta thấy ở đây là, vâng, có tất cả các cảnh báo sương mù dày đặc. Đó là mức độ cực đoan nhất mà chúng ta có ở California. Một chút sương mù, một chút gió, sóng lớn, nguy hiểm bãi biển. Nhưng đây là những gì đã xảy ra.

Vì vậy, bạn có thể thấy trong Giao diện người dùng Temporal, bạn có thể thấy từng hoạt động mà tôi đã gọi. Bạn có thể thấy rằng tôi đã gọi LLM. Đó là dòng tạo mà bạn thấy ở phía dưới. Vì vậy, chúng ta đang làm việc từ dưới lên trên. Sau đó, bạn có thể thấy rằng tôi đã thực hiện một hoạt động động. Nhưng hoạt động động mà tôi đã thực hiện nói riêng, nó không nói hoạt động động chung chung. Nó nói tôi đã thực hiện get weather alerts. Và sau đó như chúng ta làm với Agent Loop, chúng ta lấy đầu ra của công cụ và chúng ta gửi nó trở lại LLM và chúng ta nhận được điều này.

Bây giờ, tôi muốn chỉ cho bạn một cái gì đó ở đây. Tôi sẽ chỉ cho bạn một ví dụ khác. Vì vậy, tôi sẽ hỏi câu hỏi, có bất kỳ cảnh báo thời tiết nào ở nơi tôi đang ở không? Vậy nó có biết tôi đang ở đâu không? Và tôi sẽ bắt đầu điều này. Và tôi sẽ rất nhanh chóng đến đây. Và chúng ta sẽ thấy cái này đang chạy. Và bạn có thể thấy, ồ, tôi sẽ quá chậm có vẻ như vậy. Nhưng tôi sẽ quay lại và làm lại bản minh họa này. Nhưng bạn có thể thấy cách nó vừa đưa những thứ đó vào. Vì vậy, tôi hiện có ba công cụ đã được đăng ký. Tôi có một công cụ lấy vào một tiểu bang. Tôi có một công cụ lấy vào một địa chỉ IP và trả về một tiểu bang. Và tôi có một công cụ cung cấp cho tôi một địa chỉ IP cho máy tính đang chạy hiện tại. Và vì vậy tôi đã không cài đặt điều đó. Mà LLM đã đưa ra những quyết định đó chỉ dựa trên các công cụ. Vì vậy, tất cả những gì tôi đã làm là tôi đã cung cấp các công cụ đó. Nhưng bạn có thể có được khả năng quan sát đó trên toàn bộ điều này trong Temporal. Vì vậy, bạn có thể thấy rằng chúng ta bắt đầu với get IP address. Sau đó, chúng ta nhận được thông tin vị trí từ địa chỉ IP đó. Sau đó, chúng ta nhận được các cảnh báo thời tiết. Và đây là điều trớ trêu. Là không có cảnh báo thời tiết nào ở New York. Vì vậy, tôi nghĩ New York là một nơi có thời tiết khắc nghiệt hơn nhiều. Nhưng có lẽ hôm nay đã đến. Bạn có sương mù, nhưng không có cảnh báo sương mù. Vì vậy, tất cả các bạn kiên cường hơn rất nhiều so với những người California còn lại của chúng tôi.

Tính Bền vững của Agent trong Temporal

Được rồi, vì vậy tôi muốn chỉ cho bạn một điều khác, đó là, tôi sẽ quay lại đây. Tôi sẽ chạy lại cái này. Và tôi sẽ cố gắng nhanh hơn nhiều. Vì vậy, tôi sẽ nhấn OK. Và bây giờ tôi sẽ lên đây. Và tôi sẽ Ctrl+C. Không có worker nào đang chạy. Tác nhân của tôi không chạy. Nó không chạy chút nào. Và vì vậy nếu chúng ta đến đây và chúng ta xem điều này trông như thế nào trong Temporal, và điều này sẽ cho bạn bức tranh rõ ràng nhất về ý nghĩa của tôi về tính bền vững và các tác nhân bền vững, là tôi có tác nhân này đang chạy. Và bạn có thể thấy rằng nó đã thực hiện lệnh gọi LLM đầu tiên. Sau đó, nó đã nhận được, nó đã thực hiện lệnh gọi công cụ đến địa chỉ IP. Và bây giờ nó bị kẹt. Nó bắt đầu gọi LLM, nhưng khoan đã. Có gì đó không ổn. Bản thân tác nhân không chạy. Và nhân tiện, tôi cũng có thể đã thực hiện một bản minh họa. Và tôi không có thời gian để làm tất cả những điều đó hôm nay.

Xử lý Lỗi và Khôi phục Trạng thái

Nhưng tôi đã có thể thực hiện một bản demo trong đó tôi cắt mạng. Tôi đã có thể ngắt kết nối mạng. Và điều bạn sẽ thấy ở đây, trong thanh màu đỏ nhỏ này, là nó sẽ hiển thị: "Create attempt one", "Create attempt two", "Create attempt three". Tôi có thể khôi phục mạng và sau đó nó sẽ hoàn tất. Nhưng để tiết kiệm thời gian ở đây, vì tôi vẫn còn nhiều nội dung để trình bày, tôi chỉ cho bạn thấy một trong các chế độ lỗi (failure modes). Có rất nhiều chế độ lỗi được xử lý.

Vì vậy, tôi sẽ quay lại đây và khởi động lại worker. Và điều chúng ta sẽ thấy xảy ra là, chắc chắn rồi, nó tiếp tục hoạt động. Nó đã tiếp tục từ nơi nó dừng lại. Khi tôi nói nó tiếp tục từ nơi nó dừng lại, dĩ nhiên, tôi đã tắt process. Không còn gì chạy trong bộ nhớ nữa. Vì vậy, khi tôi đưa worker trở lại, nó phải tái tạo trạng thái của ứng dụng. Nó đã làm điều đó thông qua event sourcing. Về cơ bản, đó là cách Temporal hoạt động. Có câu hỏi nào về điều đó không? Vâng?

Uỷ quyền Tác nhân và Tính Idempotence

"Chúng ta có thể ủy quyền một tác nhân cho một tác nhân khác không?" "Bạn có thể ủy quyền một tác nhân cho một tác nhân khác không?" Chắc chắn rồi. Hiện tại, chúng tôi chưa có hỗ trợ gốc cho giao thức A-to-A, nếu bạn nghĩ về giao thức đó cụ thể. Nhưng một trong những điều bạn chắc chắn có thể làm là để một tác nhân hoạt động như một công cụ. Có một số cách khác nhau để làm điều đó. Bạn có thể thực hiện một activity và gọi một tác nhân khác, hoặc bạn có thể sử dụng một số cơ chế khác. Chúng tôi có child workflows và những loại điều đó. Tôi sẽ không đề cập đến điều đó trong các trường hợp sử dụng nâng cao hơn. Nhưng vâng, chắc chắn rồi. Vâng. OK. Tôi sẽ không hỏi điều đó. OK.

Câu hỏi đầu tiên là về tính idempotence. Bạn đã nhận ra rằng bản thân các activities nên có tính idempotence. Chúng tôi không yêu cầu điều đó. Chúng tôi không kiểm tra nó vì chúng tôi không đi sâu vào hoạt động bên trong của các activities. Chúng tôi để điều đó cho các nhà phát triển. Nhưng hướng dẫn là nếu chúng không có tính idempotence, vì hãy nhớ rằng khi chúng tôi thực hiện các lần thử lại thay mặt bạn, chúng tôi không biết tại sao chúng tôi không nhận được phản hồi từ lần gọi đầu tiên. Vì vậy, chúng tôi sẽ tiếp tục thử lại cho đến khi chúng tôi nhận được phản hồi. Tất nhiên, có thể là request chưa bao giờ đến được activity. Có thể là nó đã đến và nó đã gọi downstream function. Có thể đã có lỗi ở một số nơi. Vậy làm thế nào để bạn đảm bảo rằng các nhà phát triển của bạn đang tạo các activities có tính idempotence? Giáo dục. Chúng tôi không có giải pháp nào mang tính "viên đạn bạc" ở đây.

Độ trễ (Latency) trong Tác nhân

Câu hỏi thứ hai là về độ trễ (latency). Bởi vì vâng, tôi đang truy cập server ở đây với mỗi activity call đó. Và vì vậy, khi chúng ta nghĩ về các tác nhân, loại độ trễ (latency), và Johann, tôi không nhớ chính xác các con số. Bạn có nhớ các con số là bao nhiêu không? Ý tôi là, nó rất nhỏ. Độ trễ (latency) để truy cập server liên quan đến activities. Vì vậy, nó sẽ ảnh hưởng một chút. Hàng chục mili giây. Vì vậy, nó khá nhỏ. Tôi nghĩ tôi đã nghe nói về một số khách hàng đang sử dụng điều này trong các ứng dụng thời gian thực. Nhưng trong trường hợp của các tác nhân, đặc biệt là các tác nhân chạy dài hạn trong vài phút, vài giờ, vài ngày, hoặc có tương tác người dùng, độ trễ vài chục mili giây là có thể chấp nhận được. Vì vậy, có thể có các trường hợp sử dụng không phù hợp do độ trễ đó, nhưng nó khá nhỏ. Nó áp dụng được trong hầu hết các trường hợp. OK. Được rồi.

Tổng quan về TemporalAgents SDK

Vậy đó là tổng quan về Temporal. Bây giờ, tôi muốn chuyển trở lại agents SDK và chỉ cho bạn thấy sự khác biệt và điểm tương đồng. Vì vậy, hãy quay lại đây. Tôi sẽ đi qua một vài hình ảnh nữa. OK. Vậy thì, OpenAI agents SDK, sự kết hợp của hai thứ này ở cấp độ cao trông như thế này:

Ở nền tảng, chúng ta có các mô hình OpenAIOpenAI API, không phải SDK, mà là OpenAI API. Vì vậy, bạn có thể đã nhận thấy rằng tôi đã sử dụng OpenAI API. Và bây giờ chúng ta sẽ bắt đầu sử dụng agents SDK. Và sau đó chúng ta cũng có Temporal như một yếu tố nền tảng. Và bây giờ agents SDK được xếp lớp lên trên nó. Vì vậy, đó là hai thành phần nền tảng.

Không phải là chúng ta đang để Temporal nằm một bên hay OpenAI, các mô hình của chúng ta nằm một bên. Chúng ta thực sự đã tích hợp những thứ này lại với nhau. Và tôi sẽ đưa ra một số bình luận khi chúng ta xem code về cách chúng ta thực hiện tích hợp đó. Và tôi hoàn toàn mời Yohan bổ sung vào đó nữa, vì anh ấy đã dẫn dắt kỹ thuật cho việc tích hợp ở đây.

Vì vậy, bây giờ bạn có agents SDK. Và bây giờ bạn sẽ sử dụng agents SDK để xây dựng các tác nhân của mình, để thêm hàng rào bảo vệ. Tôi sẽ cho bạn thấy một số tính năng tracing. Tôi đã cho bạn thấy giao diện người dùng Temporal UI. Nhưng agents SDK cũng có một số tính năng tracing thực sự thú vị. Và bạn sẽ thấy rằng chúng tôi đã tích hợp những thứ đó lại với nhau. Bạn sẽ thấy chúng kết hợp lại với nhau. Và tất nhiên, công cụ.

Tích hợp OpenAI Agents SDK với Temporal

Tôi đã nói về các Temporal activities này. Và chúng ta đã thấy điều này rồi, tôi sẽ bỏ qua nó. Và bây giờ tôi sẽ lấy cùng một ví dụ chính xác mà chúng ta vừa xem qua. Tôi sẽ có ba công cụ. Một là weather API. Và hai cái còn lại là các location APIs. Và chúng ta sẽ làm gì? Chà, chúng ta sẽ đặt các activity decorators xung quanh chúng. Và tôi sẽ chỉ cho bạn thấy điều đó trông như thế nào trong cơ sở mã khác chỉ trong giây lát.

Chúng ta sẽ đảm bảo có các docstrings ở đó, bởi vì tôi đã chỉ cho bạn cách OpenAI APIhelper function nội bộ cho phép chúng ta tạo ra các JSON blobs để mô tả các công cụ. Chà, agents SDK thực sự còn làm nhiều hơn thế nữa cho chúng ta. Vì vậy, bạn sẽ thấy rằng một phần code của tôi đã biến mất. Và sau đó chúng ta sẽ tiếp tục từ đó.

Và đây sẽ là loop của chúng ta ở đây. Tôi sẽ chỉ cho bạn khi chúng ta xem code rằng cách chúng ta tạo JSON blob đó là một phần của tích hợp. Vì vậy, bạn có thể lấy một activity. Và chúng tôi đã cung cấp cho bạn một function có tên là activity as tool sẽ nhận vào activity, bản thân function. Vì vậy, bạn không phải lo lắng về việc serialize nó. Không có API nội bộ. Đây là một API công khai. Đó là một phần của tích hợp. Và bạn sẽ gọi activity as tool, nó sẽ tạo ra JSON blob. Và sau đó bạn cũng có thể có timeouts của mình.

Có một phần khác, thực sự quan trọng, đó là bạn phải cấu hình tích hợp. Vì vậy, agents SDK một mình không sử dụng Temporal. Và nếu bạn muốn sử dụng Temporal, bạn cần đảm bảo rằng bạn bao gồm một plugin. Và tôi sẽ chỉ cho bạn code cho điều đó trong giây lát. Và sau đó, tất nhiên, chúng ta sẽ chạy nó. Và chúng ta sẽ chạy nó theo cùng một cách cơ bản. OK, vậy hãy demo điều đó.

Cấu trúc Codebase của ActivitiesAgent Workflow

Vì vậy, chúng ta sẽ dành nhiều thời gian hơn trong codedemo một lần nữa. Để tôi quay lại cursor. OK, vậy tôi có bốn file mà tôi muốn chỉ cho bạn ở đây. Tôi sẽ bắt đầu lại với các activities.

Đây là get-weather activity. Và bạn sẽ thấy rằng nó thực sự đã đơn giản hơn một chút. Nó chỉ có activity decorator trên get-weather alerts. Và sau đó đây là function nơi nó thực sự gọi National Weather Service API. Vì vậy, có một chút code ở đó đang thực hiện một số formatting nơi nó thực hiện API call đó để tạo JSON blob. Điều đó biến mất vì chúng tôi có một function được hỗ trợ cho việc đó. Các location activities cũng đơn giản tương tự. Vì vậy, theo nghĩa đen, đây là toàn bộ file. Vì vậy, tôi có hai function này với các activity decoratorsdocstrings của tôi. Vì vậy, các docstrings đang mô tả các arguments và như vậy. OK?

Vậy bây giờ, còn bản thân tác nhân thì sao? Vậy hãy nhớ, activities chỉ là những thứ mà các công cụtác nhân đang sử dụng. Những gì tôi đã chỉ cho bạn trước đây là một Agent Loop được viết bằng Python đang orchestrating LLM call và các tool invocations. Vậy bây giờ, nếu tôi chuyển sang workflow, workflow của tôi trông như thế nào? Đây chính là nó.

Tôi có, xin lỗi, đây chính là nó. Đây là workflow. Và về cơ bản, để tôi tăng cỡ chữ lên, vì tôi có rất nhiều không gian, hãy chú ý rằng tôi đang sử dụng agents SDK. Vì vậy, tôi đang định nghĩa một tác nhân ngay tại dòng 18. Tôi đặt tên cho nó: "Bạn là một tác nhân hữu ích." Và tôi cung cấp cho nó một tập hợp các công cụ. Những công cụ đó được triển khai dưới dạng activities. Và ở đó bạn có thể thấy rằng tôi đã thực hiện function call có tên là activity as tool. Điều đó tạo ra JSON blob. Thế thôi. Đó là tất cả những gì có. Đó là cách tôi đã triển khai nó.

Mở rộng Tác nhânHandoff

Bây giờ, hãy chú ý rằng tôi vẫn đang làm điều đó trong workflow. Bởi vì hãy nhớ, trước đó, tôi đã nói, chúng ta có activities. Chúng ta có workflows. Khi bạn kết hợp chúng lại với nhau, đó là nơi phép màu xảy ra. Vì vậy, việc đặt tác nhân này vào bên trong một workflow, đó là điều bổ sung tất cả các khả năng bền bỉ (durability capabilities) này.

Bây giờ, tôi sẽ không demo phiên bản không bền bỉ (non-durable version) của điều này, bởi vì một lần nữa, chúng ta chỉ có thời gian hạn chế ở đây hôm nay. Nhưng nếu tôi đã triển khai điều này chỉ với agents SDK, đó chỉ là một Python library, tôi sẽ có một single process. Và nếu tôi tắt process đó, mọi thứ sẽ biến mất cùng với nó. Không có cách nào để tôi mở rộng (scale) process đó. Và hãy nhớ, tôi có một runner ở dưới, ngay dưới đây. Vì vậy, mỗi runner đó, nó chỉ là một monolithic agent. Nó chỉ là một Python process. Bằng cách thực hiện theo cách này, bạn có thể thấy rằng nếu tôi đang chạy nhiều worker, tôi có thể tiếp tục mở rộng (scaling out) điều này bằng cách chỉ chạy nhiều worker đang lấy các thứ khác ra khỏi queue.

Vâng. "Việc handoffs cho các tác nhân khác có hoạt động không?" "Việc handoffs cho các tác nhân khác có hoạt động không?" Có. Và tôi sẽ quay lại điều đó trong phần cuối cùng nơi chúng ta sẽ nói về orchestration. Vâng, chúng có hoạt động. Chắc chắn rồi. OK.

Cấu hình WorkerPlugin cho Tác nhân AI

Vậy bây giờ hãy để tôi đi đến, tôi cần phải... Tôi cần lấy một thứ khác ra khỏi đây. Tôi cần lấy worker của mình. Worker của tôi đâu? Đây là worker của tôi. Bởi vì nó nằm trong worker nơi plugin ở đâu? Johan, giúp tôi với. Tôi vừa bỏ qua nó. Oh, đây rồi: OpenAI agents plugin.

Vậy nó nằm trong worker. Hãy nhớ, worker là nơi tất cả execution đang diễn ra. Hãy nghĩ về nó như một kiểu container logic, ẩn dụ. Và thường xuyên, bạn đang chạy các worker trong các container. Và đây là cấu hình bạn cần đặt vào đó. Đó là những điều bạn có thể chú ý rằng nó đang thực hiện, như cấu hình một số hành vi thử lại (retry behavior) xung quanh LLM. Bạn sẽ nhận thấy, bạn có nhận thấy rằng tôi không cung cấp cho bạn một activity để gọi LLM không? Điều đó được thực hiện như một phần của tác nhân. Nhưng chúng tôi vẫn muốn điều đó bền bỉ (durable). Và đó là một trong những điều mà implementation của chúng tôi làm ở đây. Vì vậy, bạn đang thực hiện một số retry policies cho LLM. Và về cơ bản bạn đang nói, "này, OpenAI agents SDK, hãy sử dụng các phần này của Temporal."

Tích hợp Chuyên sâuAbstract Runner Class

Hãy để tôi kể cho bạn một chút về những gì chúng tôi đã làm như một phần của tích hợp. Những gì chúng tôi đã làm, nếu bạn quay lại và nhìn vào commit history của OpenAI agents SDK, bạn sẽ tìm thấy một commit nơi nó nói, "làm cho runner class trừu tượng." Họ đã làm điều đó cho chúng tôi. Bởi vì đó là cách chúng tôi có được tính bền bỉ (durability) này. Đó là cách chúng tôi có thể làm cho các LLM calls bền bỉ (durable), cùng với tất cả các công cụ mà bạn vừa thấy. Vì vậy, chúng tôi có implementation của riêng mình về abstract runner class. Vì vậy, đó là cách điều này hoạt động. OK.

Chúng ta đã xem xét các activities. Chúng ta đã xem xét workflow. Và sau đó chúng ta chạy tools workflow. Tôi không nghĩ có gì khác để xem ở đó.

Minh họa Tác nhân đang chạy

Vậy hãy chuyển sang cái này. Để tôi tìm đúng cửa sổ của mình. Đó là cửa sổ này. OK. Vậy điều tôi đang làm trong cửa sổ này, để tôi tăng cỡ chữ lên một chút, là ở cửa sổ trên cùng, và tôi sẽ thoát khỏi những cái này vì tôi chỉ cần hai cái. OK. Vậy ở cửa sổ trên cùng, tôi đang chạy worker của mình một lần nữa. Bạn đã thấy điều đó trước đây. Vì vậy, tôi đang chạy worker ở trên đó. Và vì vậy nó có một vài log messages sẽ xuất hiện.

Và sau đó ở dưới đây là nơi tôi đang khởi động workflow. Đây là nơi tôi đang tương tác với tác nhân. Vì vậy tôi sẽ, tôi vừa đẩy một số thứ này lên. Oh, tôi sẽ chỉ cho bạn repository trong giây lát. Vậy "Có bất kỳ cảnh báo thời tiết nào ở California không?" Và hãy nhớ code. Code chỉ là tác nhân đó. Chúng tôi vẫn đã triển khai các activities của mình. Nhưng codetác nhân đó. Và bạn có thể thấy những thứ đang cuộn lên ở đó. Vì vậy, bạn có thể thực sự thấy các API calls đến LLM.

Trình diễn Tác nhân AI và Khả năng Quan sát

Bạn có thể thấy API call tới National Weather Service. Và nếu chúng ta quay lại Temporal UI, đó là một workflow khác có tên là Tools Workflow, ở đây bạn có thể thấy nó trông hoàn toàn giống nhau. Đó là lý do tại sao tôi muốn dành thời gian để cho bạn thấy nó với Temporal, bởi vì Temporal, nếu bạn đang xây dựng các ứng dụng Claude-native này, bạn sẽ có được tất cả khả năng bền vững này, bạn có được visibility này, nó trông hoàn toàn giống nhau. Nhưng bạn đang sử dụng Agents SDK để triển khai các tác nhân của mình, điều mà tôi nghĩ là rất tuyệt vời.

Vậy hãy chạy ví dụ thứ hai. Tôi sẽ chỉ cho bạn repository sau một giây nữa. Chúng ta sẽ chạy ví dụ thứ hai này, đó là có bất kỳ cảnh báo thời tiết nào ở nơi tôi đang ở không? Và chúng ta sẽ quay lại đây. Chúng ta sẽ theo dõi nó đang chạy. Vậy là nó đang chạy. Và nó đang chạy theo cùng một cách. Và tôi sẽ chạy lại nó một lần nữa khi nó quay lại. Và nó nói, không, bạn ổn ở New York. Hãy để tôi chạy nó một lần nữa. Tôi sẽ để nó bắt đầu, chạy được một nửa, sau đó control C thoát ra. Và chúng ta quay lại đây. Và chúng ta thấy điều tương tự như chúng ta đã thấy trước đây. Agents SDK bền vững, điều này thật tuyệt vời. Tôi, xin lỗi, tôi làm điều này mọi lúc, nhưng tôi vẫn rất hào hứng về điều này. Và nó đây rồi.

Xử lý Quy trình Dài hạn với Temporal

Tôi sẽ chia sẻ với bạn một cách để suy nghĩ về điều này một cách trực quan, về những gì chúng ta đang làm ở đây. Tôi đã viết phần mềm hơn 30 năm rồi. Vâng, tôi có mái tóc bạc để chứng minh điều đó, phải không? Tôi đã viết phần mềm mà khi tôi viết, tôi đang nghĩ về các quy trình mà nó chạy trong đó. Tôi đang nghĩ về thực tế rằng, ồ, tôi có một quy trình ở đây và điều gì sẽ xảy ra nếu có điều gì đó xảy ra với quy trình đó. Hoặc khi tôi mở rộng quy mô mọi thứ và mọi thứ có thể không chạy trong cùng một quy trình, tôi luôn nghĩ về các quy trình.

Với Temporal, điều bạn có thể làm là bạn có thể viết chương trình của mình mà không cần nghĩ về một quy trình như một thực thể logic. Và chỉ cần để Temporal ánh xạ nó xuống các quy trình vật lý thực tế đang tồn tại. Điều này đặc biệt, rất thú vị khi nhìn vào. Khi bạn làm những việc như human in the loop. Vì vậy, đầu tuần này, tôi đã thực hiện một trong những buổi nói chuyện khác mà tôi làm là về human in the loop với các tác nhân. Và một trong những vấn đề lớn của human in the loop là khi bạn đang nghĩ về việc xây dựng những thứ này và bạn đang nghĩ về các quy trình, bạn sẽ nghĩ, OK, tôi cần chạy một lúc. Và bây giờ tôi sẽ chờ đợi human in the loop. Và có thể mất một giây. Có thể mất một phút. Rất có thể, sẽ mất hàng giờ hoặc hàng ngày trước khi con người này quay lại. Tôi phải làm gì với quy trình đang chờ phản hồi đó trong khi chờ đợi? Giống như, bạn với tư cách là một nhà phát triển phải tìm ra điều đó. Với Temporal, bạn không cần. Bạn chỉ cần viết mã.

Và nhân tiện, cách hoạt động của kiến trúc worker là nếu nó đang chờ đợi điều gì đó như đầu vào từ con người, nó sẽ giữ nó trong bộ nhớ một lúc, vài giây, sau đó nó sẽ đưa nó ra khỏi bộ nhớ hoạt động, nhưng nó vẫn nằm trong một cache. Và sau một thời gian nữa, nó sẽ ra khỏi cache. Và nó sẽ giống như bạn vừa kết thúc quy trình đó. Vì vậy, khi nó quay trở lại sau nhiều ngày hoặc nhiều tuần, khi người dùng quay lại và cung cấp cho bạn đầu vào đó, nó chỉ đơn giản là khôi phục bộ nhớ theo cách nó đã có khi đang chờ người dùng và tiếp tục.

Vì vậy, hãy nhớ tôi đã nói đó là một lỗi hệ thống (crash), hoặc có thể là những thứ khác, những thứ liên quan đến vận hành, tất cả những loại điều đó. Vì vậy, nó rất giải phóng. Một khi bạn bắt đầu thực sự đi sâu vào thứ Temporal này, thật giải phóng khi nhận ra rằng tôi không phải nghĩ về các quy trình vật lý nữa. Đối với tôi, các quy trình chỉ là logic. Temporal sẽ lo phần còn lại cho tôi. Rất tuyệt vời.

Điều phối Tác nhân AI với OpenAI Agents SDK

Được rồi, chúng ta còn khoảng 20 phút nữa. Tôi sẽ đi qua một vài slide nữa để trả lời một trong những câu hỏi về handoffs. Và chỉ cho bạn thêm một chút nội dung. Và sau đó chúng ta sẽ có một chút thời gian trong 10 hoặc 15 phút cuối cùng, tôi rất sẵn lòng nhận thêm câu hỏi. Và Yeohan, tôi chắc chắn, cũng rất vui lòng tham gia.

OK, vậy hãy để tôi. Với OpenAI Agents SDK, điều tôi đang nói ở đây hơi cụ thể đối với Agents SDK, nhưng điều này cũng khái quát hóa cho các tác nhân nói chung, đó là, với OpenAI Agents SDK, mô hình mà họ sử dụng ở đó là để xây dựng nhiều tác nhân nhỏ có các nhóm tác nhân độc lập của riêng chúng và sau đó orchestrate chúng lại với nhau. Và có hai cách mà bạn có thể orchestrate chúng lại với nhau trong Agents SDK. Và tôi sẽ chỉ cho bạn cả hai cách đó trong giây lát.

Vậy điều chúng ta thấy trên màn hình ở đây chỉ là một vài sơ đồ về, OK, tôi có một tác nhân phân loại (triage agent), tôi có một tác nhân làm rõ (clarification agent), sau đó tôi có một human in the loop, đó không phải là một tác nhân. Mặc dù bạn có thể coi con người là tác nhân trong ứng dụng này, phải không? Sau đó, tôi có một tác nhân hướng dẫn (instructions agent) sẽ tạo ra một số thứ, sau đó tôi có một tác nhân lập kế hoạch (planning agent), sau đó bạn có thể thấy rằng chúng ta đang làm mọi thứ song song. Tôi chưa nói về điều này, nhưng Temporal có tất cả các trừu tượng đó. Bất cứ điều gì bạn có thể viết trong một ngôn ngữ lập trình thông thường, bạn muốn thực hiện đa luồng và có nhiều luồng khác nhau và làm mọi thứ song song và sau đó chờ chúng quay lại với nhau. Bạn có thể làm điều đó. Bạn muốn có một loại await nào đó nói rằng, bạn biết đấy, khi chúng bắt đầu đến, tôi sẽ bắt đầu xử lý chúng. Không vấn đề gì. Bạn có thể làm điều đó. Bất cứ điều gì bạn có thể làm trong mã, bạn có thể làm với Temporal, bởi vì bạn chỉ đang viết mã.

Vì vậy, đó là cách nó hoạt động hiệu quả ở đây với agent SDK cũng như vậy. Tôi sẽ chỉ cho bạn những điều đó một lần nữa. Vì vậy, bạn có thể làm song song, bạn có thể có thời gian chờ dài, và bạn có thể có các vòng lặp. Vì vậy, tôi đã chỉ cho bạn thực tế rằng tôi không phải tạo ra logic của mình trong Python. Logic, LLM đã đưa ra các quyết định về cách luồng sẽ diễn ra trong ứng dụng đó, phải không? Vì vậy, tôi chỉ có một vòng lặp mà bản thân vòng lặp đó là cố định, nhưng điều xảy ra trong vòng lặp hoàn toàn được xác định bởi LLM. Vì vậy, đó là tất cả những điều bạn có thể làm.

Vì vậy, có hai cách với agent SDK mà bạn có thể orchestrate các microagents này. Và nhân tiện, tôi chỉ phải nói rằng tôi yêu thuật ngữ microagent. Như tôi đã đề cập từ đầu, tôi đã dành rất nhiều thời gian trong thế giới microservices. Và ôi trời ơi, chúng ta đã đạt được rất nhiều lợi ích từ đó, phải không? Đó là lý do chúng ta có thể triển khai phần mềm nhiều lần trong ngày. Đó là lý do chúng ta có thể mở rộng quy mô theo cách chúng ta có thể mở rộng quy mô. Microservices đã chứng minh được giá trị của chúng. Tôi nghĩ chúng ta sẽ thấy một mô hình rất tương tự, thành công rất tương tự khi nói đến việc xây dựng các tác nhân AI, công cụ MCP, và tất cả những thứ tương tự. Vì vậy, tôi yêu khái niệm microagents làm một việc và làm tốt một việc. Tôi cũng đã dành đủ thời gian trong thế giới Unix để điều đó làm trái tim tôi rung động.

Vì vậy, chỉ cần viết mã (just code) và handoffs, just code thực sự đơn giản. Đó là điều tôi đã mô tả trước đây. Vì vậy, bạn có thể thấy ở đây rằng tôi có runner.run. Tôi đang thực thi một tác nhân. Tôi nhận được kết quả từ tác nhân đó. Và tôi chuyển kết quả đó vào tác nhân tiếp theo. Tôi có thể song song hóa, tôi có thể lặp, tôi có thể làm bất cứ điều gì tôi muốn. Cách thứ hai, ồ vâng, và tôi đã trình bày tất cả những điều đó. Vì vậy, vâng, vâng, tôi đã đề cập tất cả những điều đó rồi.

Cách thứ hai mà OpenAI, và bạn có đang nói về OpenAI cụ thể khi bạn hỏi về handoffs không? Vâng. Vì vậy, đối với những người không biết, OpenAI có một cách thứ hai để thực hiện orchestrations, được gọi là handoffs. Và vì vậy điều bạn thấy ở đây là trong định nghĩa về một tác nhân của tôi, tôi có thể định nghĩa handoffs. Những handoffs đó là các tác nhân khác. Chúng đã được định nghĩa, tôi có lẽ nên có nó trên slide. Nhưng tôi có một tác nhân thời tiết (weather agent) được định nghĩa rất giống nhau. Nó đang sử dụng agent, có tên, có hướng dẫn, có thể có công cụ.

Vì vậy, hai thứ này là các tác nhân. Và tất cả điều này hoạt động với sự tích hợp với Temporal. Và điều thú vị ở đây là những microagents đó, khi nó handoff cho một tác nhân, nó không thực hiện một agent loop riêng biệt. Nó thực sự, và đây là nỗ lực điên rồ của tôi để cố gắng mô tả những gì đang xảy ra ở đây, đó là khi bạn thực hiện handoff, điều bạn đang thực sự làm là chỉ thay đổi context của agentic loop. Vì vậy, chỉ có một agentic loop duy nhất. Ví dụ, bạn có một tác nhân phân loại. Nó quyết định rằng nó sẽ đi vào việc cung cấp, tôi đã làm việc tại Alexa một thời gian. Vì vậy, bạn đã hỏi Costco mở cửa muộn đến mức nào hay bạn đã hỏi nhiệt độ hiện tại là bao nhiêu? Vì vậy, đó là hai tác nhân khác nhau, tác nhân thời tiết và tác nhân thông tin địa phương. Và điều bạn đang thực sự làm là agentic loop đó đang đảm nhận một persona khác. Bạn chỉ đang chuyển đổi ngữ cảnh. Và chúng ta đã nghe rất nhiều buổi nói chuyện tuần này về context engineering. Bởi vì đó là điều tuyệt vời về việc LLM hay quên, đó là bạn có thể kiểm soát hoàn toàn ngữ cảnh đang đi vào chúng. Vì vậy, điều này hoạt động chính xác, Temporal hoàn toàn handoff-aware. Tôi không có một bản demo trực tiếp về điều đó. Và vậy là xong. OK.

Tài nguyên và Phản hồi

Với điều đó, chúng ta sẽ có vài phút còn lại cho các câu hỏi. Tôi muốn để lại cho bạn một vài tài nguyên. Vì vậy, điều bạn thấy ở phía bên trái là bạn thấy một mã QR cho Temporal Python SDK. Bạn sẽ tìm thấy rất nhiều thông tin tuyệt vời về Python SDK của chúng tôi. Nhưng bạn cũng sẽ tìm thấy một thư mục Contribute Directory. Và đó là nơi chứa tất cả mã tích hợp vào OpenAI Agents SDK. Và bạn sẽ tìm thấy rất nhiều ví dụ trong đó.

Ở phía bên phải, tôi không có mã QR cho nó vì nhân viên marketing của tôi không làm việc vào sáng thứ Bảy. Tốt cho họ. Bạn sẽ thấy một URL ở đây. Vì vậy, nếu bạn truy cập tài liệu của chúng tôi, docs.temporal.io. Ở banner trên cùng, bạn sẽ tìm thấy AI cookbook. Chúng tôi có một AI cookbook triển khai một loạt các mô hình. Cái mà tôi đã chỉ cho bạn hôm nay, agentic loop, hiện đang ở trong một nhánh. Nó đã sẵn sàng để được hợp nhất. Nó đã được xem xét. Nhưng người xem của tôi thực sự đã không đưa ra một đánh giá chấp thuận. Họ chỉ xem xét nó và nói, trông tốt. Nhưng tôi cần một sự chấp thuận. Vì vậy tôi không thể hợp nhất nó sáng nay. Nhưng công thức đó sẽ có ở đó. Và có một số công thức khác. Có một công thức trong đó cho OpenAI Agents SDK. Vì vậy, bạn cũng sẽ tìm thấy nó trong đó.

Tóm lại, tôi sẽ không nói quá nhiều về điều đó. Tôi nghĩ chúng ta cũng đã đi qua điều đó. Hai tài nguyên khác mà tôi muốn để lại cho bạn là ở phía bên trái, bạn sẽ tìm thấy blog của chúng tôi nơi chúng tôi mô tả sự tích hợp của OpenAI Agents SDK và Temporal. Đó là blog ở phía bên trái.

Điều khác bạn sẽ nhận thấy là tôi có một blog mang tính hàn lâm ở đó. Và vì vậy ý tưởng mang khả năng bền vững đến các khung làm việc tác nhân không bền vững này là một ý tưởng rất phổ biến. Vì vậy, sau khi chúng tôi thực hiện OpenAI Agents SDK, Pydantic đã tích hợp Temporal vào khung làm việc tác nhân của họ. Và Johann, tôi không biết chúng ta có thể nói về những cái nào. Chúng ta có cả một loạt các cái khác đang được tiến hành. Đó có phải là tất cả những gì chúng ta muốn nói không? Hay bạn muốn nói về bất kỳ cái nào trong số đó cụ thể không? OK. Sẽ có nhiều hơn nữa. Vâng. Tôi nghĩ chúng ta có hai hoặc ba hoặc bốn cái đang được tiến hành ngay bây giờ sẽ xuất hiện từ chúng tôi hoặc từ một số khung làm việc tác nhân khác. Vì vậy, ý tưởng mang khả năng bền vững đến những gì nếu không thì chỉ là một công cụ proof of concept đang trở nên khá mạnh mẽ.

Và cuối cùng, nếu bạn muốn, đây là mã QR và URL. Nếu bạn muốn cung cấp cho chúng tôi một số phản hồi về hội thảo này, chúng tôi thực sự đánh giá cao điều đó. Và bao gồm trong phản hồi đó, có một phần tự do trong đó. Bao gồm trong phản hồi đó những gì bạn muốn thấy nhiều hơn. Chẳng hạn như, này, cái này rất hay, nhưng nó chưa đủ sâu. Hoặc bạn đã đề cập đến điều này. Tôi thực sự muốn xem thêm về human in the loop. Nhân tiện, nếu bạn truy cập kênh YouTube của chúng tôi, bạn sẽ tìm thấy một loạt các bài thuyết trình khác nhau. Vì vậy, human in the loop tôi đã làm một webinar về nó khoảng ba tuần trước. Chúng tôi đã làm một số module MCP, những thứ MCP, thậm chí nâng cao.

Dưới đây là bản dịch và chỉnh sửa theo yêu cầu:

Tổng quan và Hội nghị Sắp tới

Chúng tôi đã thực hiện một ví dụ nâng cao, cho bạn thấy cách sử dụng Temporal để triển khai một máy chủ MCP bền bỉ, hỗ trợ lấy mẫu và làm rõ một cách hiệu quả và bền vững hơn. Với phần trình bày đó, chúng ta vẫn còn khoảng tám phút. Tôi cũng muốn đề cập, đặc biệt nếu bạn ở Vùng Vịnh, nhưng ngay cả khi không, hội nghị của chúng tôi, hội nghị Replay của Temporal, sẽ diễn ra vào tháng 5 tại Moscone. Chúng tôi rất mong được gặp bạn ở đó. Mã QR này ban đầu dành cho buổi hội thảo tôi đã làm vào thứ Ba, nhưng thôi, hãy sử dụng nó ở đây luôn. Giảm giá 75%, đúng vậy, giảm 75% phí đăng ký tham dự Replay. Vì vậy, tôi mời bạn đến đó. Bạn sẽ tìm thấy tôi, bạn sẽ tìm thấy Johan, và rất nhiều người khác trong đội ngũ của chúng tôi. Bạn có thể thấy rằng chúng tôi có rất nhiều nhân vật nổi tiếng như Samuel Colvin đang đến, và chúng tôi có những người từ ReppletVidya, cùng nhiều người khác nữa. Tôi sẽ để phần phản hồi ở đây.

Hỏi đáp: Quản lý Trạng thái Temporal Server

Chúng ta có vài phút còn lại cho các câu hỏi. Vâng. Mức độ an toàn về trạng thái? Làm thế nào để an toàn về trạng thái...? Bạn đã tắt điện thoại. Vâng. OK, bạn đang nói về máy chủ Temporal mà tôi đã chỉ cho bạn cách chạy nó cục bộ. Khi bạn chạy nó cục bộ, bạn có thể bật một công tắc nói rằng, hãy khởi động trong SQLite hoặc thứ gì đó tương tự. Vì vậy, có trạng thái hỗ trợ nó. Tôi thường không chạy theo cách đó vì tôi muốn loại bỏ mọi thứ. Temporalopen source và chúng tôi có rất nhiều người dùng tự lưu trữ nó. Vì là open source, chúng tôi thực sự tại các sự kiện như thế này luôn gặp gỡ mọi người. Tôi đã gặp một người hôm qua hoặc lúc nào đó, họ nói: "Ồ, vâng, chúng tôi đang sử dụng Temporal." Và tôi nói: "Họ chỉ đang sử dụng bản open source." Vì vậy, nó thực sự là open source. Và chúng tôi có những người đang tự lưu trữ nó. Chúng tôi hỗ trợ cơ sở dữ liệu quan hệCassandra làm backing stores.

Trên Temporal Cloud, một phần lý do mọi người đến với Claude là, trước hết, chúng tôi chạy Claude ở 15 khu vực Amazon khác nhau. Tôi không biết, 4 hoặc 5 hoặc 6 khu vực Google. Chúng tôi có các tên, giao diện đa khu vực, và tất cả durability đó. Và sau đó, chúng tôi cũng có một số "bí quyết" đặc biệt về lưu trữ bền vững cho phép chúng tôi thực hiện mọi thứ hiệu quả hơn. Nhưng chúng tôi có những người đang lưu trữ nó khá thành công bằng cách sử dụng Cassandra hoặc các tùy chọn cơ sở dữ liệu. Vâng. Có câu hỏi nào khác không? Vâng?

Hỏi đáp: Vòng đời WorkflowDigital Twins

Bắt đầu và dừng. Khi tôi bắt đầu và dừng instance, ý bạn là tác nhân? Làm cách nào để dừng nó nếu người dùng muốn dừng nó? Công việc? Vâng. Có một vài cách khác nhau để bạn có thể bắt đầu một workflow. Bạn có thể bắt đầu một workflow mong đợi nó là đồng bộ. Và nó chỉ kết thúc và bạn sẽ phải có một loại lệnh dừng nào đó. Nhưng phổ biến hơn, bạn sẽ bắt đầu nó ở chế độ bất đồng bộ, và bạn sẽ nhận lại một handle. Sau đó, bạn có thể thực hiện các hành động với handle đó để dừng các workflow. Nhưng nói chung, điều phổ biến nhất là bạn sẽ xác định trong logic của mình ý nghĩa của việc hoàn thành trải nghiệm tác nhân hoặc hoàn thành workflow đó theo một cách nào đó. Và bạn sẽ quyết định, "Ồ, tôi đã xong bây giờ," và bạn sẽ chỉ cần return. Vì vậy, nó thực sự đơn giản như việc return từ nó. Đó là một câu hỏi hay, mặc dù chúng ta đang nói về những thứ bất đồng bộ này, tôi đã không đề cập đến nó trong phiên này. Nhưng một trong những điều thực sự mạnh mẽ là các workflow này có thể chạy trong hàng giờ, phút, ngày, tuần, tháng, năm. Và nó cực kỳ hiệu quả.

Một mô hình mà nhiều người dùng của chúng tôi sử dụng là họ sử dụng workflow như một digital twin của một thứ khác. Chúng tôi cũng gọi đó là entity workflow. Ví dụ, bạn có thể có một workflow tương ứng với một khách hàng thân thiết. Và mỗi khi khách hàng thân thiết đó quét mã QR của họ tại quầy thanh toán, nó sẽ gửi một tín hiệu vào workflow. Và workflow đó sẽ không tiêu tốn bất kỳ tài nguyên nào khác. Và nó sẽ chỉ bật lên, nhận tín hiệu, xử lý những gì cần thiết, và lại biến mất. Vì vậy, đó là một mô hình rất, rất phổ biến. Khái niệm workflowdigital twin của một quy trình hoặc một thực thể khác là vô cùng, vô cùng mạnh mẽ. Rất nhiều người sử dụng nó. Vâng?

Hỏi đáp: Tích hợp và Lưu trữ Workload

Vâng. Vậy nó sẽ hoạt động cho chúng tôi. Theo như tôi biết, chúng tôi không có những tích hợp đó, nhưng khách hàng của chúng tôi xây dựng những tích hợp đó. Vâng, vâng. Họ hoàn toàn xây dựng chúng dựa trên nền tảng của chúng tôi. Liệu chúng tôi có một số trong số đó trong Claude hay không, tôi không chắc. Nhưng không phải là chúng tôi không có các kết nối Slack gốc hoặc những thứ tương tự. Và một số điều đó tất nhiên sẽ không nhất thiết là một thứ liên quan đến Temporal. Giống như nếu bạn đang chạy các worker của mình trên Kubernetes, bạn có thể đã thiết lập cấu hình Kubernetes của mình để khi Vùng chứa ngừng hoạt động, bạn sẽ nhận được cảnh báo. Hoặc khi bạn thấy điều gì đó trong bảng điều khiển Kubernetes mà, ôi chao, giống như autoscaler của tôi. Và tất nhiên, bạn có thể có những worker này và bạn có thể chạy chúng trên Kubernetes với các autoscaler. Vì vậy, rất nhiều thứ đó, bạn biết đấy, những thứ orchestration CNTT đó có thể sẽ đến thông qua môi trường vận hành của bạn. Bạn, đó thực sự là một điểm rất hay, đó là chúng tôi lưu trữ máy chủ, nhưng chúng tôi không lưu trữ khối lượng công việc cho bạn. Vì vậy, bạn tự lưu trữ khối lượng công việc. Hầu hết mọi người đều thích điều đó vì họ muốn kiểm soát hoàn toàn điều đó. Chúng tôi đang cân nhắc ý tưởng trong một số trường hợp có thể lưu trữ worker trong tương lai, nhưng đó không phải là lộ trình hiện tại.

Hỏi đáp: Tác nhân thoạiCookbook

Vâng. Ví dụ về những người xây dựng tác nhân thoại với Temporal. Tôi không biết bất kỳ ví dụ nào có sẵn. Tôi không biết liệu có cái nào quan trọng không. Vâng. Vâng, câu hỏi ở phía sau. Tôi chưa có Claude, hãy để mắt đến cookbook. Tôi chưa có ví dụ cho Claude ngay bây giờ. Tôi gần như đã hoàn thành Gemini. Và vâng, chúng tôi muốn thêm Claude vào cookbook nữa. Chúng tôi cũng rất sẵn lòng chấp nhận PR. Vì vậy, nếu bạn muốn lấy ví dụ này và chuyển nó sang Claude, chúng tôi cũng rất muốn có PR về điều đó. Vâng, cookbook này là open source hoàn toàn. Tất cả đều được cấp phép MIT trong kho lưu trữ chính, tổ chức chính của chúng tôi.

Hỏi đáp: Agent trích xuất thông tin và Code Exchange

Vâng. Có agent mẫu nào để trích xuất thông tin từ Excel, phương tiện không? Agent mẫu để trích xuất từ Excel hoặc PDF. Cá nhân tôi không có cái nào. Một trong những điều khác mà tôi sẽ đề cập là chúng tôi có một code exchange. Vì vậy, cookbook là của chúng tôi. Và đó là nơi chúng tôi rất cẩn thận để đảm bảo rằng nó thể hiện thực hành tốt nhất. Và chúng tôi thực hiện đánh giá nghiêm ngặt về những điều đó vì chúng tôi không muốn gây nhầm lẫn cho bạn chút nào. Chúng tôi cũng có một code exchange, trong đó chúng tôi có, tôi nghĩ là 20, 30 hoặc 40 ví dụ. Có thể có một cái gì đó trong đó. Thành thật mà nói, tôi không chắc. Vâng. Nó có giống như một GitHub không? Vâng. Bạn sẽ tìm thấy code exchange trên trang web của chúng tôi. Và tôi tin rằng tất cả các mục trong code exchange đều có URL GitHub. Chúng tôi không sở hữu hầu hết chúng vì chúng đến từ cộng đồng, nhưng chúng là các kho lưu trữ của những người khác. Vì vậy, vâng, bạn sẽ tìm thấy điều đó.

Tuyển dụng

Được rồi. Vâng, đây là... còn câu hỏi nào khác không? Tôi chỉ muốn nhận xét rằng chúng ta đã đề cập vài lần rằng điều đó sắp đến, hoặc điều đó sẽ thực sự, thực sự thú vị để làm. Và nhóm của tôi đang tuyển dụng nhân sự. [Thông báo tuyển dụng.] Về các ứng dụng AI của Temporal. OK. Và vì anh ấy đã nói vậy, tôi thuộc nhóm phát triển cộng đồng nhà phát triển. Chúng tôi cũng đang tìm kiếm các chuyên viên quan hệ nhà phát triển. Vì vậy, nếu bạn phù hợp với hồ sơ kỹ sư, hãy nói chuyện với Yo-han, nếu bạn phù hợp với hồ sơ chuyên viên quan hệ nhà phát triển, hãy đến nói chuyện với tôi. OK. Cảm ơn rất nhiều.

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