Xây dựng Chatbot từ API LLM: Hướng dẫn Python
Các mô hình Abliterated là mô hình ngôn ngữ lớn nơi các cơ chế thực hiện từ chối an toàn đã được loại bỏ, cho phép mô hình trả lời các câu hỏi gây tranh cãi, người lớn hoặc chuyên biệt mà không bị chặn bởi bộ lọc nội dung. Cách tiếp cận này mang lại cho nhà phát triển quyền kiểm soát hoàn toàn giọng điệu và ngưỡng cắt kiến thức của mô hình, điều này đặc biệt có giá trị cho lập trình, nhập vai và viết sáng tạo nơi các hàng rào bảo vệ tiêu chuẩn có thể chặn đầu ra hữu ích.
Cập nhật

Điểm chính
- API không có trạng thái, vì vậy mã của bạn sở hữu lịch sử hội thoại và gửi nó trên mỗi yêu cầu.
- Truyền phát, gọi hàm và chế độ JSON đều sử dụng các tham số OpenAI tiêu chuẩn.
- Bạn nên cắt hoặc tóm tắt lịch sử trước khi nó tiến gần đến cửa sổ ngữ cảnh 100.000 token.
- 1.000 cuộc trò chuyện với 2.000 token đầu vào và 400 token đầu ra tốn khoảng $0,50.
Ý tưởng cốt lõi: chatbot là một vòng lặp và một danh sách
Mô hình ngôn ngữ không ghi nhớ gì giữa các yêu cầu. Mọi lệnh gọi POST /v1/chat/completions đều độc lập. Những gì giống như bộ nhớ thực chất là chương trình của bạn gửi lại các tin nhắn trước đó, mỗi tin được gắn vai trò: system cho hướng dẫn hệ thống, user cho nội dung người dùng nhập, assistant cho các phản hồi trước của mô hình.
Vì vậy, toàn bộ kiến trúc rất nhỏ. Bạn chỉ cần giữ một danh sách. Thêm tin nhắn người dùng. Gửi danh sách. Thêm phản hồi. Lặp lại. Mọi thứ khác trong hướng dẫn này, từ truyền phát đến công cụ, đều là biến thể của vòng lặp đó.
API ở đây tương thích với OpenAI, nên bạn sử dụng gói openai thông thường. Đặt base URL là https://api.abliterated.cc/v1, sử dụng khóa của bạn và đặt mô hình thành uncensored. Lấy khóa từ trang khóa API; tín dụng dùng thử $0,50 đủ cho hàng trăm tin nhắn kiểm tra ngắn.
Bước 1: một chatbot console hoạt động
Cài đặt SDK bằng pip install openai và chạy đoạn mã này.
from openai import OpenAI
client = OpenAI(
base_url="https://api.abliterated.cc/v1",
api_key="YOUR_KEY",
)
messages = [
{"role": "system", "content": "You are a concise, friendly support assistant for a bike shop."}
]
while True:
text = input("you: ")
if text.strip() in {"quit", "exit"}:
break
messages.append({"role": "user", "content": text})
resp = client.chat.completions.create(
model="uncensored",
messages=messages,
temperature=0.7,
)
answer = resp.choices[0].message.content
messages.append({"role": "assistant", "content": answer})
print("bot:", answer)
Đó là một chatbot hoàn chỉnh. Tin nhắn hệ thống xác định nhiệm vụ của nó, danh sách lưu trữ bộ nhớ và temperature kiểm soát mức độ đa dạng của các câu trả lời. Hãy hạ nó xuống gần 0,2 cho các bot hỗ trợ cần độ chính xác, tăng nó lên gần 1,0 cho các bot sáng tạo.
Viết một prompt hệ thống để xác định nhiệm vụ
Tin nhắn hệ thống là nơi rẻ nhất để cải thiện chatbot. Bạn nên giữ nó ngắn gọn và cụ thể. Hãy nêu rõ vai trò, đối tượng khán giả, độ dài và giọng điệu của phản hồi, cũng như cách xử lý khi bot không biết câu trả lời. Một prompt như "Bạn trả lời câu hỏi cho một cửa hàng xe đạp. Trả lời trong tối đa ba câu. Nếu câu hỏi về giá sửa chữa, hãy nói rằng một thợ máy phải kiểm tra xe" sẽ hiệu quả hơn nhiều so với một trang các phẩm chất chung chung.
Hai thói quen này mang lại hiệu quả. Thứ nhất, hãy đặt các quy tắc dưới dạng hành động, không phải thái độ: "hỏi một câu làm rõ khi yêu cầu không rõ ràng" thay vì "hãy hữu ích". Thứ hai, hãy thử nghiệm với các đầu vào thù địch, chẳng hạn như một tin nhắn trống, một đoạn văn bản rất dài và một yêu cầu không liên quan đến sản phẩm của bạn. Hãy điều chỉnh prompt dựa trên những gì bạn thấy, sau đó giữ các đầu vào đó làm danh sách kiểm thử hồi quy.
Vì tin nhắn hệ thống được gửi lại ở mỗi lượt, mọi từ trong đó đều được tính phí trên mỗi yêu cầu. Một prompt 400 token trên 1.000 cuộc trò chuyện với 5 lượt mỗi cuộc sẽ thêm 2.000.000 token đầu vào, tương đương 2 x $0,15 = $0,30. Con số này nhỏ, nhưng nó cho thấy lý do tại sao các prompt phình to lại tích lũy chi phí khi ở quy mô lớn.
Bước 2: truyền phát phản hồi
Chờ một câu trả lời đầy đủ cảm thấy chậm trong cửa sổ trò chuyện. Đặt stream: true và in các phần dữ liệu khi chúng đến. Luồng dữ liệu sử dụng sự kiện do máy chủ gửi (SSE) và kết thúc bằng một khối sử dụng, vì vậy bạn có thể ghi lại số lượng token.
from openai import OpenAI
client = OpenAI(base_url="https://api.abliterated.cc/v1", api_key="YOUR_KEY")
messages = [{"role": "user", "content": "Explain tire pressure in two sentences."}]
stream = client.chat.completions.create(
model="uncensored",
messages=messages,
stream=True,
)
reply = ""
for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content:
part = chunk.choices[0].delta.content
reply += part
print(part, end="", flush=True)
if getattr(chunk, "usage", None):
print("\ntokens:", chunk.usage.prompt_tokens, chunk.usage.completion_tokens)
Hãy nhớ thêm phản hồi reply đã được tổng hợp vào lịch sử của bạn, nếu không bước tiếp theo sẽ không biết bot đã nói gì.
Bước 3: quản lý ngữ cảnh trước khi nó phát triển
Cửa sổ ngữ cảnh là 100.000 token, được chia sẻ giữa prompt và phần phản hồi (completion). Hầu hết các chatbot không bao giờ tiến gần đến giới hạn này, nhưng chi phí tăng lên cùng với lịch sử vì bạn phải trả tiền cho toàn bộ prompt trên mỗi lượt. Một chính sách đơn giản giúp kiểm soát cả hai:
- Luôn giữ lại tin nhắn hệ thống.
- Giữ lại 10 đến 20 tin nhắn cuối cùng nguyên văn.
- Khi danh sách vượt quá giới hạn kích thước bạn chọn, chẳng hạn như 8.000 token ước tính, hãy gửi khối cũ nhất đến mô hình với hướng dẫn "tóm tắt cuộc trò chuyện này trong dưới 150 từ", và thay thế khối đó bằng bản tóm tắt dưới dạng tin nhắn hệ thống.
Một ước tính sơ bộ một token cho bốn ký tự tiếng Anh là đủ để kích hoạt. Các số liệu sử dụng trong mỗi phản hồi cho bạn con số chính xác sau đó, vì vậy bạn có thể hiệu chỉnh giới hạn.
Nếu bạn cắt ngắn bằng cách loại bỏ các tin nhắn cũ nhất, hãy loại bỏ chúng theo từng cặp user và assistant. Một phản hồi không có câu hỏi, hoặc một câu hỏi không có phản hồi, sẽ gây nhầm lẫn cho mô hình nhiều hơn bạn nghĩ.
Bước 4: cung cấp công cụ cho bot
Gọi hàm cho phép mô hình yêu cầu mã của bạn thực hiện một hành động, chẳng hạn như tra cứu đơn hàng. Bạn mô tả các hàm bằng tools, mô hình trả về một mục tool_calls, bạn chạy hàm và gửi kết quả lại dưới dạng tin nhắn role: "tool".
import json
from openai import OpenAI
client = OpenAI(base_url="https://api.abliterated.cc/v1", api_key="YOUR_KEY")
tools = [{
"type": "function",
"function": {
"name": "get_order_status",
"description": "Look up the status of an order by its id",
"parameters": {
"type": "object",
"properties": {"order_id": {"type": "string"}},
"required": ["order_id"],
},
},
}]
def get_order_status(order_id):
return {"order_id": order_id, "status": "shipped"}
messages = [{"role": "user", "content": "Where is order A1042?"}]
resp = client.chat.completions.create(
model="uncensored", messages=messages, tools=tools, tool_choice="auto"
)
msg = resp.choices[0].message
if msg.tool_calls:
messages.append(msg)
for call in msg.tool_calls:
args = json.loads(call.function.arguments)
result = get_order_status(**args)
messages.append({
"role": "tool",
"tool_call_id": call.id,
"content": json.dumps(result),
})
final = client.chat.completions.create(
model="uncensored", messages=messages, tools=tools
)
print(final.choices[0].message.content)
Luôn xác thực các đối số trước khi chạy bất kỳ hành động nào có tác dụng phụ. Mô hình đề xuất một lệnh gọi; mã của bạn sẽ quyết định có thực thi nó hay không.
Bước 5: đầu ra có cấu trúc với chế độ JSON
Khi bước tiếp theo trong chương trình của bạn cần dữ liệu thay vì văn bản, chẳng hạn như phân loại tin nhắn vào một danh mục, hãy sử dụng chế độ JSON với response_format. Hãy đề cập từ khóa JSON và các khóa dự kiến trong prompt của bạn.
curl https://api.abliterated.cc/v1/chat/completions \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "uncensored",
"response_format": {"type": "json_object"},
"messages": [
{"role": "system", "content": "Reply with JSON: {\"intent\": string, \"urgent\": boolean}"},
{"role": "user", "content": "My brakes squeal and I ride tomorrow morning."}
]
}'
Vẫn hãy bọc json.loads trong một khối try. Nếu quá trình phân tích cú pháp thất bại, hãy thử lại một lần với văn bản lỗi được nối thêm; các yêu cầu thất bại không bị tính phí.
Lưu ý về lỗi, chi phí và triển khai
Xử lý lỗi, thử lại và giới hạn tốc độ
Người dùng thực sự gửi yêu cầu vào những thời điểm không thuận tiện và mạng có thể gặp sự cố. Hãy bọc lệnh gọi sao cho một phản hồi xấu không làm sập cuộc hội thoại.
import time
from openai import OpenAI, APIError, RateLimitError
client = OpenAI(base_url="https://api.abliterated.cc/v1", api_key="YOUR_KEY")
def chat(messages, tries=3):
for attempt in range(tries):
try:
resp = client.chat.completions.create(
model="uncensored", messages=messages, temperature=0.7
)
return resp.choices[0].message.content
except RateLimitError:
time.sleep(2 ** attempt)
except APIError as exc:
if attempt == tries - 1:
raise
time.sleep(1)
return "Sorry, the assistant is busy. Please try again in a moment."
Một khóa đầy đủ cho phép 8 yêu cầu đồng thời và 300 yêu cầu mỗi phút; khóa dùng thử cho phép 2 và 60. Nếu bot của bạn phục vụ nhiều người dùng cùng lúc, hãy đặt các yêu cầu vào hàng đợi với giới hạn worker dưới 8 thay vì dựa vào việc thử lại. Vì các yêu cầu thất bại không được tính phí, việc thử lại không tốn chi phí token. Hãy giữ số lần thử lại nhỏ để một sự cố thực sự xảy ra nhanh chóng.
Ngoài ra, hãy ghi lại tiêu đề X-Request-Id cho mỗi lượt trò chuyện. Khi một phản hồi có vẻ sai, id này cho phép bạn tìm lại yêu cầu chính xác sau này.
Chi phí và triển khai
Giá là $0,15 cho mỗi 1 triệu token đầu vào và $0,50 cho mỗi 1 triệu token đầu ra. Giả sử một cuộc trò chuyện hỗ trợ sử dụng tổng cộng 2.000 token đầu vào và 400 token đầu ra.
- Đầu vào: 0,002M x $0,15 = $0,0003
- Đầu ra: 0,0004M x $0,50 = $0,0002
- Một cuộc trò chuyện: $0,0005, vậy 1.000 cuộc trò chuyện tốn $0,50
Xem mức giá hiện tại và ưu đãi nạp tiền trên trang giá. Để triển khai, hãy giữ khóa trên máy chủ của bạn, không bao giờ để trong mã trình duyệt, và theo dõi tiêu đề phản hồi X-Balance-USD để được cảnh báo trước khi tín dụng cạn kiệt. Khóa đầy đủ cho phép 8 yêu cầu đồng thời và 300 yêu cầu mỗi phút, vì vậy hãy xếp hàng các đợt tăng đột biến thay vì gửi chúng cùng một lúc. Tài liệu liệt kê mọi tham số được hỗ trợ.
Hướng dẫn khác
Hỏi đáp
Tôi có cần framework để xây dựng chatbot không?
Không. SDK OpenAI và một danh sách tin nhắn là đủ cho một bot hoạt động. Chỉ thêm framework sau này nếu bạn cần các tính năng bổ sung của nó.
API có nhớ các tin nhắn trước không?
Không. Mỗi yêu cầu đều độc lập, nên bạn phải gửi lại lịch sử mỗi lần.
Làm sao để ngăn lịch sử quá dài?
Giữ lại tin nhắn hệ thống và các lượt gần đây, đồng thời tóm tắt các lượt cũ thành một ghi chú ngắn khi danh sách vượt quá kích thước bạn đặt.
Bot có thể gọi hàm của tôi không?
Có. Bạn truyền công cụ và tool_choice, chạy hàm khi phản hồi chứa tool_calls, rồi trả kết quả dưới dạng tin nhắn công cụ.
Khóa của bạn chỉ cách một biểu mẫu
Tạo tài khoản, sao chép khóa, thay đổi base URL. Đó là toàn bộ thiết lập.