Sức mạnh của việc căn chỉnh với mô hình tư duy của người dùng
Khi thiết kế API của ConnectOnion, chúng tôi đã đối mặt với một quyết định quan trọng:
Chúng tôi nên gọi phương thức chính để tương tác với một agent là gì?
Sự lựa chọn đơn giản này sẽ ảnh hưởng đến trải nghiệm đầu tiên của mọi người dùng với framework của chúng tôi.
Vấn đề với run()
Ban đầu, chúng tôi đã tuân theo quy ước ngành với:
agent.run(prompt)
Có vẻ hợp lý — các agent “chạy” nhiệm vụ, đúng không?
Nhưng phản hồi của người dùng đã chỉ ra một vấn đề nghiêm trọng:
Từ "run" tạo ra sự ma sát về nhận thức.
Người dùng phải dịch ý định của họ (“Tôi muốn hỏi agent một điều gì đó”) thành thuật ngữ kỹ thuật (“Tôi cần chạy agent”).
Điều này diễn ra hàng ngàn lần mỗi ngày trong cộng đồng người dùng của chúng tôi.
Quy trình nghiên cứu
Chúng tôi đã nghiên cứu cách những người dùng mới tiếp cận API của chúng tôi mà không đọc tài liệu.
Những nỗ lực đầu tiên của người dùng mới:
- 40% thử
agent.input() - 18% thử
agent.ask() - 15% thử
agent.chat() - 12% thử
agent.run() - 8% thử
agent.process() - 7% các biến thể khác
Dữ liệu rõ ràng: người dùng nghĩ theo những gì HỌ làm (cung cấp thông tin), không phải những gì AGENT làm (chạy/xử lý).
Đánh giá các lựa chọn thay thế
Chúng tôi đã đánh giá 7 tùy chọn khác nhau:
1. agent.chat(prompt)
- Thân thiện và có tính đối thoại
- Nhưng ngụ ý cuộc hội thoại có trạng thái (gây hiểu lầm cho các lệnh không có trạng thái)
- Không phải tất cả các agent đều "nói chuyện" (một số tính toán, phân tích, v.v.)
2. agent.ask(prompt)
- Tự nhiên cho các kịch bản hỏi-đáp
- Nhưng hạn chế — không phải tất cả các tương tác đều là câu hỏi
- Không hoạt động cho các lệnh ("hỏi" agent để "xóa tệp"?)
3. agent.prompt(prompt)
- Chính xác về mặt kỹ thuật
- Nhưng gây nhầm lẫn giữa danh từ và động từ ("nhắc nhở nhắc nhở?")
- Quá kỹ thuật cho người bắt đầu
4. agent.process(prompt)
- Mô tả những gì xảy ra bên trong
- Nhưng thuật ngữ kỹ thuật
- Người dùng không nghĩ "Tôi cần xử lý một cái gì đó"
5. agent.invoke(prompt)
- Cảm giác chuyên nghiệp, thuộc về doanh nghiệp
- Nhưng có thể làm người mới cảm thấy sợ hãi
- Nghe giống như sự phức tạp của Java/doanh nghiệp
6. agent.input(prompt)
- Phù hợp với mô hình tư duy của người dùng
- Hoạt động cho tất cả các loại tương tác
- Tự tài liệu
- Nghe ít “kỹ thuật” hơn (thực sự là một lợi thế?)
7. agent.run(prompt) (ban đầu)
- Tiêu chuẩn ngành
- Nhưng yêu cầu dịch nghĩa
- "Chạy cái gì?"
- Ngụ ý chạy mã, không phải cuộc trò chuyện
Kiểm tra “Mom Test”
Chúng tôi đã áp dụng một tiêu chí đơn giản: một người không có kiến thức kỹ thuật có thể đoán được điều này làm gì không?
# Rõ ràng với mọi người
agent.input("Dịch câu này sang tiếng Tây Ban Nha: Xin chào")
# Gây nhầm lẫn với những người không phát triển
agent.run("Dịch câu này sang tiếng Tây Ban Nha: Xin chào")
agent.invoke("Dịch câu này sang tiếng Tây Ban Nha: Xin chào")
"Input" đã vượt qua bài kiểm tra mom. "Run" và "invoke" không làm được.
Nguyên tắc sâu hơn: Quan điểm của người dùng vs Hệ thống
Quyết định này đã tiết lộ một nguyên tắc cơ bản:
Thiết kế API từ quan điểm của người dùng, không phải từ quan điểm của hệ thống.
Quan điểm hệ thống (Cách nó hoạt động)
- Agent nhận prompt
- Agent xử lý prompt
- Agent chạy suy diễn
- Agent thực hiện công cụ
- Agent trả về phản hồi
Quan điểm người dùng (Cảm giác)
- Tôi cung cấp đầu vào
- Tôi nhận đầu ra
Quan điểm người dùng đơn giản hơn, rõ ràng hơn và dễ hiểu hơn.
Việc thực hiện rất đơn giản
Thay đổi này chỉ cần một dòng:
class Agent:
# Trước
def run(self, prompt: str) -> str:
return self._process(prompt)
# Sau
def input(self, prompt: str) -> str:
return self._process(prompt)
Nhưng tác động là rất sâu sắc.
Đo lường thành công
Sau khi thay đổi:
- 60% ít câu hỏi “Làm thế nào để tôi sử dụng agent?” trong Discord của chúng tôi
- Tỷ lệ thành công lần đầu tăng từ 67% lên 89%
- Thời gian để thực hiện lần gọi agent thành công đầu tiên giảm 40%
- Lượng tìm kiếm tài liệu về việc sử dụng cơ bản giảm 55%
Bài học rút ra
1. Thách thức các quy ước ngành
Chỉ vì tất cả mọi người sử dụng run() không có nghĩa là nó đúng. Đặt câu hỏi mọi thứ.
2. Dữ liệu thắng ý kiến
Chúng tôi đã có những ý kiến mạnh mẽ về run(). Hành vi của người dùng đã chứng minh chúng tôi sai.
3. Từ ngữ nhỏ, tác động lớn
Một sự thay đổi ba chữ cái (run → input) đã biến đổi trải nghiệm người dùng của chúng tôi.
4. Thiết kế cho mô hình tư duy
Căn chỉnh với cách người dùng nghĩ, không phải cách hệ thống hoạt động.
5. API tốt nhất không cần tài liệu
Khi người dùng đoán đúng, bạn đã tìm thấy cái tên đúng.
Hiệu ứng lan tỏa
Quyết định này đã ảnh hưởng đến toàn bộ triết lý thiết kế API của chúng tôi:
agent.input("...") # Không phải agent.run()
agent.history.summary() # Không phải agent.get_execution_log()
agent.tools = [...] # Không phải agent.register_capabilities()
Nhìn lại
Việc chọn input() thay vì run() có thể có vẻ tầm thường, nhưng nó đại diện cho một điều lớn lao hơn:
Cam kết của chúng tôi với trải nghiệm người dùng thay vì độ chính xác kỹ thuật.
Khi bạn gõ:
agent.input("2+2 là gì?")
Bạn không nghĩ về các mô hình thực thi hay quy trình xử lý.
Bạn đang nghĩ về việc cung cấp thông tin cho một agent.
Và đó chính xác là điều quan trọng.
Cách ConnectOnion
Quyết định này thể hiện triết lý của chúng tôi:
- Những điều đơn giản nên cảm thấy đơn giản
- APIs nên phù hợp với mô hình tư duy
- Trải nghiệm người dùng quan trọng hơn độ chính xác kỹ thuật
- Dữ liệu thắng ý kiến
- Đặt câu hỏi mọi thứ — ngay cả quy ước
Đôi khi, quyết định thiết kế API tốt nhất là quyết định khiến các nhà phát triển quên rằng họ đang sử dụng một API.
Suy nghĩ cuối cùng
Lần tới khi bạn thiết kế một API, hãy tự hỏi:
Tôi đang đặt tên cho điều này từ quan điểm của hệ thống hay quan điểm của người dùng?
Câu trả lời có thể biến đổi trải nghiệm người dùng của bạn.