Menu

Tree of thought prompting: cách hoạt động, ví dụ

Tree of thought prompting cho mô hình khám phá nhiều lời giải dang dở, đánh giá từng lời giải, và chỉ giữ lại những nhánh hứa hẹn. Bài này giải thích phương pháp gốc hoạt động thế nào, một phiên bản dùng một prompt để bạn thử, và những điểm phiên bản đó còn thiếu.

Mọi prompt bên dưới đều có thể chỉnh sửa: thay đổi nó, rồi mở trong ChatGPT, Claude hoặc ứng dụng AI khác.

Tree of thought prompting khiến mô hình ngôn ngữ giải một vấn đề theo cách bạn có thể làm trên giấy: viết ra vài bước tiếp theo khả dĩ, đánh giá bước nào có vẻ hứa hẹn, đi tiếp các bước đó, và bỏ một nhánh khi nó không dẫn tới đâu. Ý tưởng này đến từ bài báo của Yao và cộng sự năm 2023, "Tree of Thoughts: Deliberate Problem Solving with Large Language Models". Nó mở rộng chain of thought prompting, vốn đi theo một luồng lập luận duy nhất, thành một quá trình tìm kiếm trên nhiều luồng.

Trang này giải thích phương pháp gốc hoạt động thế nào, đưa cho bạn một phiên bản dùng một prompt để thử trong ChatGPT, Claude hoặc Gemini, và trình bày vòng lặp bằng code cho những lúc một prompt là không đủ.

Tree of thoughts hoạt động thế nào

Bài báo chia phương pháp thành bốn quyết định.

  1. Thế nào là một thought (ý nghĩ). Một thought là một bước trung gian, đủ nhỏ để mô hình tạo ra tốt và đủ lớn để đánh giá. Trong một câu đố toán, nó là một phương trình; trong một bài viết, nó là một dàn ý ngắn.
  2. Cách tạo ra các thought. Từ lời giải dang dở hiện tại, mô hình đề xuất vài bước tiếp theo ứng viên, bằng cách lấy mẫu độc lập hoặc liệt kê chúng trong một câu trả lời.
  3. Cách đánh giá chúng. Mô hình được yêu cầu chấm điểm từng lời giải dang dở. Bài báo dùng hai kiểu: chấm từng trạng thái riêng lẻ (ví dụ "chắc chắn", "có khả năng" hoặc "không thể"), hoặc cho mô hình xem nhiều trạng thái và để nó bỏ phiếu chọn trạng thái tốt nhất.
  4. Cách tìm kiếm. Một chương trình giữ lại vài trạng thái tốt nhất ở mỗi tầng (tìm kiếm theo chiều rộng, BFS) hoặc đi sâu theo một nhánh và quay lui khi đánh giá cho thấy nhánh đó vô vọng (tìm kiếm theo chiều sâu, DFS).

Lấy ví dụ bài toán Game of 24 trong bài báo: dùng các số 4, 9, 10 và 13, mỗi số một lần, với bốn phép tính cơ bản để ra 24. Chain of thought chốt luôn phương trình đầu tiên và phải sống chung với nó. Tree of thoughts có thể thử 13 - 9 = 4, 10 - 4 = 6 và 4 + 9 = 13 làm bước đầu, hỏi mô hình những số còn lại nào vẫn có thể ra 24, bỏ ngõ cụt (10, 13 và 13 không thể ra 24), và kết thúc ở (10 - 4) * (13 - 9) = 24.

Bài báo cho thấy điều gì

Nhóm tác giả chọn ba nhiệm vụ mà GPT-4 thấy khó ngay cả khi dùng chain of thought, vì mỗi nhiệm vụ đều cần lập kế hoạch hoặc tìm kiếm: Game of 24, một bài viết sáng tạo với các câu kết cố định, và ô chữ mini 5x5. Với GPT-4, tìm kiếm dạng cây giải được nhiều câu Game of 24 hơn hẳn so với chain of thought prompting hoặc so với việc lấy mẫu nhiều chuỗi rồi chọn đáp án đa số, và nó cũng làm tốt hơn ở hai nhiệm vụ còn lại.

Cái giá là số lần gọi. Mỗi bước ứng viên và mỗi lần đánh giá là một request riêng, nên giải một bài có thể tốn hàng chục lần gọi mô hình, trong khi chain of thought chỉ tốn một. Sự đánh đổi đó hợp lý với bài toán khó và chẳng đáng với bài toán đơn giản.

Tree of thought trong một prompt

Bạn có thể mô phỏng gần đúng ý tưởng này trong một tin nhắn: yêu cầu vài hướng tiếp cận khác biệt, một kết luận cho từng hướng dựa trên các dữ kiện bạn đưa ra, và chỉ phát triển hướng còn trụ lại. Các tab bên dưới gửi cùng một vấn đề theo cả hai cách.

Ứng dụng web của chúng mình chạy nhanh với người dùng ở châu Âu nhưng mất khoảng 12 giây để tải với người dùng ở Úc. Máy chủ đặt ở Frankfurt. Khi trang tải, trình duyệt gửi 40 request API nhỏ, lần lượt từng cái một. Nguyên nhân là gì và nên làm gì?
Try it
Example replyReplies vary between models and runs.

Nguyên nhân chính là khoảng cách địa lý giữa Úc và máy chủ của bạn ở Frankfurt. Mỗi request phải đi sang châu Âu rồi quay về, và với 40 request mỗi lần tải trang, độ trễ đó cộng dồn lại.

Cách khắc phục tiêu chuẩn là dùng CDN (mạng phân phối nội dung). CDN giữ bản sao trang web của bạn trên các máy chủ khắp thế giới, nên người dùng ở Úc tải từ một vị trí gần đó thay vì từ Frankfurt. Phần lớn nhà cung cấp cho phép bạn đặt CDN trước một trang web có sẵn mà không cần sửa code.

Bạn cũng có thể nén ảnh và bật bộ nhớ đệm của trình duyệt để giảm thêm thời gian tải.

Câu trả lời trực tiếp không vô lý; nó còn đếm được 40 request, nhưng nó lấy luôn cách giải thích đầu tiên nghe hợp lý ("khoảng cách") và đi theo đó. Câu trả lời rẽ nhánh đối chiếu từng cách giải thích với các chi tiết trong prompt, nhờ vậy nó nhận ra "lần lượt từng cái một" quan trọng hơn "ở Úc", và CDN sẽ không động gì đến các lời gọi API.

Một mẫu dùng lại được

Cấu trúc này cũng dùng được cho các lựa chọn thiết kế và kế hoạch. Điền vấn đề và các tiêu chí bạn quan tâm; câu trả lời bên dưới dùng giá trị mặc định.

Rẽ nhánh, đánh giá, lựa chọn
Fill in
Vấn đề: Nhóm ba người của chúng mình cần chọn cách triển khai một API Node.js nhỏ. Tiêu chí: chi phí hằng tháng, thời gian thiết lập, công bảo trì lâu dài Đề xuất 3 hướng tiếp cận thật sự khác nhau. Với mỗi hướng, đánh giá theo từng tiêu chí trong một dòng ngắn và đưa ra kết luận: giữ hoặc bỏ. Sau đó chỉ phát triển hướng tốt nhất thành năm bước đầu tiên cụ thể. Nếu hai hướng ngang nhau, hãy nói thông tin nào sẽ giúp quyết định giữa chúng.
Try it
Example replyReplies vary between models and runs.

Platform as a service (dịch vụ host ứng dụng được quản lý) Chi phí: vừa phải, tăng theo lưu lượng truy cập. Thiết lập: dưới một giờ từ một repo Git. Bảo trì: thấp, bên host vá hệ điều hành. Giữ.

Máy chủ ảo riêng Chi phí: thấp nhất. Thiết lập: mất một ngày cho máy chủ, TLS và trình quản lý tiến trình. Bảo trì: cao, việc cập nhật và khởi động lại là của bạn. Bỏ với nhóm ba người.

Serverless functions Chi phí: rất thấp ở quy mô nhỏ. Thiết lập: vừa phải, một ứng dụng máy chủ có sẵn có thể cần cấu trúc lại. Bảo trì: thấp, nhưng cold start làm tăng độ trễ. Giữ làm phương án dự phòng.

Tốt nhất: platform as a service. Các bước đầu tiên:

  1. Thêm script khởi động và đọc cổng từ một biến môi trường.
  2. Chuyển các thông tin bí mật vào phần cài đặt biến môi trường của bên host.
  3. Kết nối repository và triển khai nhánh chính.
  4. Thêm một endpoint health check.
  5. Đặt cảnh báo chi tiêu.

Những điểm phiên bản một prompt còn thiếu

Phiên bản một prompt giữ lại cách gọi tên của phương pháp nhưng mất gần hết bộ máy bên dưới.

  • Không thật sự quay lui. Mô hình viết mọi nhánh và kết luận trong một lượt. Nếu bước 3 của nhánh được chọn thất bại, không có gì đưa nó quay về bước 1.
  • Người chấm cũng là người viết. Chính câu trả lời đề xuất ý tưởng cũng chấm điểm nó, nên nó thường thiên vị nhánh vốn đã có sẵn trong đầu. Trong bài báo, việc đánh giá là một lần gọi riêng, diễn ra sau khi các ứng viên đã có.
  • Các nhánh không độc lập. Những ý tưởng được liệt kê trong cùng một câu trả lời ảnh hưởng lẫn nhau và thường thành các biến thể của cùng một chủ đề. Yêu cầu các hướng "thật sự khác nhau", như mẫu ở trên, giúp hạn chế điều này nhưng không loại bỏ được.
  • Mô hình suy luận vốn đã rẽ nhánh. Những mô hình suy nghĩ trước khi trả lời tự thử và loại bỏ các hướng tiếp cận bên trong. Với chúng, prompt này ít cải thiện độ chính xác hơn; giá trị còn lại là bạn thấy được các lựa chọn bị loại và có thể không đồng ý với lập luận.

Chạy tìm kiếm dạng cây thật bằng code

Phương pháp đầy đủ là một vòng lặp trong chương trình của bạn: tạo các bước ứng viên, chấm điểm từng lời giải dang dở trong một lần gọi riêng, giữ lại vài lời giải tốt nhất, rồi lặp lại. Đây là một phiên bản tìm kiếm theo chiều rộng tối giản dùng OpenAI Python SDK; cấu trúc tương tự dùng được với mọi nhà cung cấp.

from openai import OpenAI

client = OpenAI()
MODEL = "your-model-id"  # e.g. from your provider's model list

def ask(prompt, temperature=0.7):
    response = client.chat.completions.create(
        model=MODEL,
        messages=[{"role": "user", "content": prompt}],
        temperature=temperature,
    )
    return response.choices[0].message.content.strip()

def propose(problem, path, k=3):
    steps = "\n".join(path) or "(none yet)"
    prompt = f"Problem: {problem}\nSteps so far:\n{steps}\nPropose the next step only."
    return [ask(prompt) for _ in range(k)]

def score(problem, path):
    steps = "\n".join(path)
    prompt = (f"Problem: {problem}\nPartial solution:\n{steps}\n"
              "How likely is this to lead to a correct solution? Reply with a number from 1 to 10 only.")
    try:
        return float(ask(prompt, temperature=0))
    except ValueError:
        return 0.0

def tree_of_thought(problem, depth=3, keep=2):
    frontier = [[]]
    for _ in range(depth):
        candidates = [path + [step] for path in frontier for step in propose(problem, path)]
        candidates.sort(key=lambda p: score(problem, p), reverse=True)
        frontier = candidates[:keep]
    return frontier[0]

Với depth=3, keep=2 và ba đề xuất cho mỗi trạng thái, một lần chạy tốn khoảng ba mươi lần gọi. Với nhiều nhiệm vụ, self-consistency prompting (nhiều câu trả lời đầy đủ, chọn theo đa số) hoặc một chuỗi bước cố định với prompt chaining mang lại phần lớn lợi ích với ít lần gọi hơn. Hãy dùng tìm kiếm dạng cây khi nhiệm vụ thật sự cần tìm kiếm: có nhiều nước đi đầu tiên khả dĩ, và có cách nhận ra ngõ cụt từ sớm.

Câu hỏi thường gặp

Tree of thought prompting là gì?

Tree of thought prompting là một cách giải quyết vấn đề trong đó mô hình đề xuất vài bước tiếp theo khả dĩ, đánh giá mức độ hứa hẹn của từng bước, và chỉ đi tiếp những nhánh tốt nhất, quay lui khi một nhánh thất bại. Nó đến từ bài báo năm 2023 "Tree of Thoughts: Deliberate Problem Solving with Large Language Models" của Yao và cộng sự. Trong bài báo, việc rẽ nhánh và chấm điểm được một chương trình điều khiển, gọi mô hình rất nhiều lần.

Tree of thoughts khác chain of thought như thế nào?

Chain of thought đi theo một luồng lập luận từ đầu đến cuối, nên một lỗi ở bước đầu sẽ kéo theo đến tận câu trả lời. Tree of thoughts giữ nhiều lời giải dang dở cùng lúc, đánh giá chúng và bỏ những lời giải yếu, nên nó có thể gỡ lại sau một bước đầu tồi. Cái giá là phải gọi mô hình nhiều hơn hẳn.

Có dùng tree of thoughts trong ChatGPT hoặc Claude được không?

Bạn có thể dùng một phiên bản gần đúng: một prompt yêu cầu mô hình liệt kê vài hướng tiếp cận, đánh giá từng hướng theo tiêu chí của bạn, loại bỏ hướng yếu và phát triển hướng tốt nhất. Cách này dùng được trong mọi ứng dụng chat. Nó không phải phương pháp đầy đủ, vì mọi thứ diễn ra trong một câu trả lời duy nhất và mô hình tự chấm điểm ý tưởng của mình ngay trong lần viết ra chúng.

Tree of thought prompting còn hữu ích với các mô hình suy luận không?

Ít hơn trước. Những mô hình suy nghĩ trước khi trả lời vốn đã tự thử và loại bỏ các hướng tiếp cận bên trong, nên yêu cầu chúng rẽ nhánh giúp ích ít hơn. Phiên bản một prompt vẫn hữu ích khi bạn muốn thấy các lựa chọn và lý do chúng bị loại, để tự kiểm tra cách đánh giá.

Khi nào nên dùng tree of thought prompting?

Hãy dùng nó cho những vấn đề có nhiều hướng tiếp cận hợp lý mà ý tưởng đầu tiên thường sai: lập kế hoạch, lựa chọn thiết kế, chẩn đoán vấn đề từ triệu chứng, và các câu đố cần tìm kiếm. Với câu hỏi chỉ có một hướng hiển nhiên, chain of thought thông thường rẻ hơn và tốt không kém.

Hình minh họa các ngôn ngữ lập trình của Coddy

Học lập trình cùng Coddy

Bắt đầu