VI ▾
Lấy khóa API

Uncensored VideoAPI Sora 2: Sử dụng văn bản không kiểm duyệt cho các đường ống video

Hướng dẫn AI tác nhân LangChain với API tương thích OpenAI

Hướng dẫn AI tác nhân langchain này kết nối LangChain với một endpoint tương thích OpenAI, liên kết hai công cụ và chạy vòng lặp tác nhân mà bạn có thể đọc từng dòng. Mọi đoạn mã đều sử dụng cùng một base URL và tên mô hình uncensored.

Cập nhật

Cánh tay robot chuyển đổi giữa các khối công cụ trong vòng lặp, minh họa một tác nhân LangChain gọi công cụ

Điểm chính

  • ChatOpenAI hoạt động không thay đổi: đặt base_url, api_key và model thành uncensored.
  • API hỗ trợ gọi hàm, vì vậy bind_tools và agent được xây dựng sẵn đều hoạt động.
  • Giới hạn số lần lặp vòng lặp và xác thực các đối số công cụ; các mô hình trọng số mở đôi khi hiểu sai chúng.
  • Tuân thủ giới hạn 8 yêu cầu đồng thời trên khóa đầy đủ khi bạn chạy các tác nhân song song.

Những gì bạn cần trước khi bắt đầu

Bạn cần Python 3.10 trở lên, một khóa API và một vài gói thư viện. Khóa đến từ trang khóa API: đăng ký bằng Google hoặc bằng email và mật khẩu, sau đó nhận tín dụng dùng thử $0,50 chỉ với một cú nhấp chuột. Khóa dùng thử cho phép 2 yêu cầu đồng thời và 60 yêu cầu mỗi phút, đủ cho mọi thứ trong bài viết này nếu bạn chạy một tác nhân tại một thời điểm.

pip install langchain-openai langchain-core langgraph
export API_KEY="paste-your-key-here"

API cung cấp POST /v1/chat/completions và GET /v1/models. LangChain chỉ cần cái đầu tiên. Mô hình là một mô hình trọng số mở đơn lẻ được tinh chỉnh để trả lời mà không từ chối nội dung cho mục đích người trưởng thành hợp pháp; nó được chạy bởi một nhà cung cấp độc lập và không phải là API chính thức của bất kỳ nhà cung cấp mô hình nào. Tài liệu liệt kê các tiêu đề và giới hạn nếu bạn muốn chúng bên cạnh trình soạn thảo của bạn.

Cách các thành phần ánh xạ vào API

Bạn nên biết những gì LangChain làm trên đường truyền. Một HumanMessage trở thành một thông báo với vai trò user. Một AIMessage trở thành assistant, và khi nó chứa các lệnh gọi công cụ, những lệnh gọi đó xuất hiện trong thông báo trợ lý dưới dạng mảng tool_calls. Một ToolMessage trở thành vai trò tool với ID lệnh gọi phù hợp. Prompt hệ thống được đặt đầu tiên với vai trò system.

Sự ánh xạ đó rất quan trọng cho việc gỡ lỗi. Nếu một tác nhân hoạt động kỳ lạ, hãy in danh sách message trước mỗi lần gọi và đọc nó như một bản ghi. Bạn thường sẽ tìm thấy vấn đề trong vòng một phút: một kết quả công cụ bị trống, một ID cuộc gọi không khớp, hoặc lịch sử đã phát triển dài hơn nhiều so với dự kiến của bạn. Từ agentic có thể khiến điều này nghe giống như phép thuật, nhưng mọi bước đều là một yêu cầu chat completion thông thường.

Bước 1: Kết nối ChatOpenAI

Toàn bộ tích hợp chỉ gồm ba đối số. LangChain xây dựng các yêu cầu kiểu OpenAI tiêu chuẩn, nên máy chủ không thể phân biệt được sự khác biệt.

import os
from langchain_openai import ChatOpenAI

llm = ChatOpenAI(
    model="uncensored",
    base_url="https://api.uncensoredvideo.cc/v1",
    api_key=os.environ["API_KEY"],
    temperature=0.7,
    max_retries=2,
)

print(llm.invoke("Name three beats of a heist scene, one line each.").content)

Nếu lệnh này in ra ba dòng, thì việc kết nối đã hoạt động. Nếu bạn nhận được 401, hãy kiểm tra khóa. Nếu bạn nhận được 404, hãy kiểm tra xem URL có kết thúc bằng /v1 và không có đường dẫn bổ sung nào không. max_retries là một tùy chọn client, và nó giúp xử lý các phản hồi 429 tạm thời mang theo Retry-After: 5.

Streaming hoạt động theo cách tương tự như bạn sẽ sử dụng nó với bất kỳ mô hình OpenAI nào: gọi llm.stream(...) và lặp qua. Chunk cuối cùng mang theo usage, vì vậy bạn có thể ghi lại số lượng token cho mỗi lần gọi.

Bước 2: Xác định công cụ

Một tác nhân là một vòng lặp: mô hình đọc cuộc trò chuyện, hoặc trả lời hoặc yêu cầu một công cụ, mã của bạn chạy công cụ, và kết quả được gửi lại cho mô hình. Các công cụ bên dưới là các hàm Python đơn giản. Chúng được cố tình nhàm chán, vì mục đích là để bạn thấy các cơ chế.

from langchain_core.tools import tool

@tool
def word_count(text: str) -> int:
    """Count the words in a piece of text."""
    return len(text.split())

@tool
def spoken_minutes(words: int, words_per_minute: int = 150) -> float:
    """Estimate how many minutes a script takes to read aloud."""
    return round(words / words_per_minute, 2)

tools = [word_count, spoken_minutes]

Chuỗi tài liệu và chú thích kiểu dữ liệu trở thành mô tả công cụ và lược đồ mà mô hình nhìn thấy. Hãy viết chúng như thể bạn đang hướng dẫn một đồng nghiệp. Một chuỗi tài liệu mơ hồ là lý do phổ biến nhất khiến một agent chọn sai công cụ. Nếu bạn viết kịch bản cho video, mẫu này cũng mở rộng sang các công cụ tra cứu danh sách cảnh hoặc kiểm tra ngân sách độ dài, một chủ đề được đề cập trên trang trình tạo kịch bản Sora 2.

Bước 3: Chạy vòng lặp tác nhân bằng tay

Các hàm trợ giúp có sẵn ẩn vòng lặp. Việc viết nó một lần bởi chính bạn sẽ giúp tìm mọi lỗi sau này dễ dàng hơn.

from langchain_core.messages import HumanMessage, ToolMessage

by_name = {t.name: t for t in tools}
llm_tools = llm.bind_tools(tools)

messages = [HumanMessage(
    "Here is a draft: 'The vault door hums. Nina counts to three, "
    "then cuts the power.' How many words is it, and how long is it read aloud?"
)]

for step in range(6):
    ai = llm_tools.invoke(messages)
    messages.append(ai)
    if not ai.tool_calls:
        break
    for call in ai.tool_calls:
        result = by_name[call["name"]].invoke(call["args"])
        messages.append(ToolMessage(content=str(result), tool_call_id=call["id"]))

print(messages[-1].content)

Ba chi tiết rất quan trọng. Giới hạn range(6) ngăn chặn một mô hình bối rối lặp lại mãi mãi, và nó cũng giới hạn chi tiêu của bạn. tool_call_id phải khớp với cuộc gọi mà nó trả lời. Và mô hình có thể yêu cầu nhiều công cụ trong một phản hồi, đó là lý do tại sao vòng lặp bên trong xử lý một danh sách.

Bên dưới, yêu cầu mang một mảng tools và phản hồi mang tool_calls, với kết quả được trả lại dưới dạng messages với role: "tool". Bạn có thể buộc một công cụ cụ thể với tool_choice, mà LangChain hiển thị dưới dạng đối số cho bind_tools.

Bước 4: Sử dụng agent LangGraph được xây dựng sẵn

Khi vòng lặp thủ công trở nên rõ ràng, agent có sẵn sẽ tiết kiệm dòng mã. Nó nhận cùng mô hình và cùng các công cụ.

import os
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import create_react_agent

llm = ChatOpenAI(
    model="uncensored",
    base_url="https://api.uncensoredvideo.cc/v1",
    api_key=os.environ["API_KEY"],
)

agent = create_react_agent(llm, tools)
out = agent.invoke({"messages": [("user", "How long is a 450 word script read aloud?")]})
print(out["messages"][-1].content)

LangChain và LangGraph thay đổi API của chúng giữa các bản phát hành, và một số trợ giúp đã được đổi tên hoặc di chuyển. Nếu một lệnh import thất bại, hãy kiểm tra tài liệu LangChain hiện tại để tìm hàm tạo agent tương đương. Phần kết nối, ChatOpenAI với một base URL, vẫn giữ nguyên.

Lựa chọn giữa vòng lặp và đồ thị

Vòng lặp viết tay là đủ cho các tác nhân chọn từ một vài công cụ và dừng lại. Nó dễ đọc, dễ ghi log và không có bất ngờ về framework. Hãy chuyển sang LangGraph khi bạn cần các nhánh phụ thuộc vào trạng thái: một bước xem lại gửi công việc trở lại để thực hiện lại, một sự phê duyệt của con người trước khi một công cụ rủi ro chạy, hoặc nhiều tác nhân chuyên biệt truyền kết quả cho nhau.

Bất kể bạn chọn gì, hãy giữ mỗi node nhỏ và giao cho nó một công việc. Một node lập kế hoạch xuất ra một danh sách số ngắn dưới dạng JSON, một node thực thi chạy công cụ và một node viết tạo ra văn bản cuối cùng dễ kiểm tra hơn một prompt khổng lồ duy nhất. Chúng cũng cho phép bạn sử dụng các nhiệt độ khác nhau: thấp cho việc lập kế hoạch và sử dụng công cụ, cao hơn cho bước viết. Vì mỗi node là một lệnh gọi chat completion bình thường, cùng một khóa, URL và tên mô hình phục vụ tất cả chúng, và chi phí chỉ đơn giản là tổng của các cuộc gọi.

Một thói quen cuối cùng: in tổng số token đang chạy. Các tác nhân trông rẻ trong một bản demo có thể chi trả gấp mười lần cho một nhiệm vụ thực tế lộn xộn, và các số liệu usage trên mỗi phản hồi làm điều đó hiển thị trong lần chạy đầu tiên, trước khi nó trở thành một bất ngờ trên số dư của bạn.

Bộ nhớ, kiểm tra và đầu ra có cấu trúc

Vòng lặp trên quên mọi thứ khi script kết thúc. Bộ nhớ đơn giản nhất là chính danh sách message: hãy giữ nó giữa các lượt người dùng, thêm mỗi câu hỏi mới và cắt bớt các message cũ nhất khi nó trở nên dài. Đối với các phiên dài, hãy thay thế các message cũ bằng một bản tóm tắt ngắn được viết bởi mô hình. Vì đầu vào được tính phí theo token, một bản tóm tắt 500 token tốt hơn 20.000 token lịch sử thô về cả chi phí và trọng tâm.

Kiểm tra các tác nhân chủ yếu là kiểm tra hành vi bạn có thể quan sát. Đặt nhiệt độ thành 0 hoặc truyền một seed cố định, mà API truyền qua, vì vậy các lần chạy có thể lặp lại hơn. Sau đó, viết một vài câu hỏi nơi bạn biết công cụ nào nên được gọi, và assert trên các tên công cụ và đối số trong danh sách message, không phải trên cách diễn đạt chính xác của câu trả lời. Chạy những điều này sau mỗi lần thay đổi một prompt hoặc mô tả công cụ. Thay đổi một docstring có thể thay đổi công cụ mà mô hình chọn, và một bài kiểm tra là cách rẻ nhất để nhận ra.

Ghi log ba thứ cho mỗi lần chạy: số bước, các cuộc gọi công cụ với các đối số của chúng và usage token. Khi một lần chạy thất bại, ba dòng đó cho bạn biết liệu mô hình có chọn sai, một công cụ có thất bại hay vòng lặp đã hết bước.

Đầu ra có cấu trúc và chế độ JSON

Các tác nhân thường cần trả lại dữ liệu, không phải văn bản. API hỗ trợ chế độ JSON thông qua response_format: {"type":"json_object"}. Trong LangChain, bạn có thể yêu cầu nó với llm.bind(response_format={"type": "json_object"}). Hãy nói với mô hình trong prompt rằng câu trả lời phải là một đối tượng JSON và đặt tên các khóa bạn mong đợi, sau đó phân tích cú pháp chuỗi và xác thực nó bằng Pydantic. Đừng tin tưởng bước phân tích cú pháp luôn thành công; hãy bọc nó trong một lần thử lại gửi văn bản lỗi trở lại cho mô hình một lần.

Các lỗi thường gặp và cách khắc phục

  • Đối số công cụ sai. Một mô hình trọng số mở đôi khi gửi một chuỗi nơi bạn đã khai báo một số nguyên. Hãy xác thực các đối số, trả về một thông báo lỗi ngắn từ công cụ và để mô hình tự sửa chữa ở bước tiếp theo.
  • Vòng lặp mất kiểm soát. Luôn luôn giới hạn số lần lặp. Ghi log mỗi bước trong khi bạn phát triển.
  • Agent song song. Khóa đầy đủ cho phép 8 yêu cầu đồng thời. Nếu bạn chạy một lô, hãy đặt config={"max_concurrency": 4} trên llm.batch để chừa lại khoảng dự phòng. Vượt quá giới hạn sẽ trả về 429 với mã concurrency; vượt quá 300 yêu cầu mỗi phút sẽ trả về rate_limited.
  • Streaming cộng với công cụ. Một yêu cầu streaming giữ slot đồng thời của nó cho đến khi stream kết thúc, vì vậy đừng bắt đầu các cuộc gọi mới từ bên trong một trình xử lý stream trên một khóa dùng thử.
  • Lịch sử ngày càng dài. Mỗi bước gửi lại toàn bộ danh sách thông báo. Cửa sổ ngữ cảnh là 100.000 token, nhưng bạn phải trả tiền cho đầu vào trên mỗi lệnh gọi.

Chi phí một lần chạy tác nhân

Hãy lấy một tác nhân khiêm tốn thực hiện 4 cuộc gọi mô hình để hoàn thành một nhiệm vụ, với một prompt trung bình 3.000 token và 200 token đầu ra cho mỗi lần gọi. Đầu vào: 4 x 3.000 = 12.000 token, tương đương 12.000 x $0,15 / 1.000.000 = $0,0018. Đầu ra: 4 x 200 = 800 token, tương đương $0,0004. Một lần chạy tốn $0,0022, vì vậy 1.000 lần chạy tốn $2,20. Tín dụng dùng thử $0,50 bao gồm khoảng 227 lần chạy như vậy. Các yêu cầu thất bại hoặc bị từ chối không được tính phí và tín dụng không bao giờ hết hạn. Xem giá cả để biết số tiền nạp tiền và tiền thưởng. Trang web này chỉ chấp nhận tiền mã hóa, USDT trên TRC20 hoặc USDC trên Base.

Hỏi đáp

LangChain có cần tích hợp đặc biệt cho API này không?

Không. Lớp ChatOpenAI từ langchain-openai chấp nhận một base_url, vì vậy bạn trỏ nó vào API và sử dụng mô hình uncensored. Không cần trình bao bọc tùy chỉnh.

API có hỗ trợ gọi công cụ cho các agent không?

Có. API chấp nhận tham số tools và tool_choice, trả về tool_calls (kể cả khi truyền phát), và nhận kết quả lại dưới dạng messages với role tool.

Tại sao agent của tôi lại dừng với lỗi 429?

Bạn đã chạm vào giới hạn tốc độ yêu cầu hoặc giới hạn đồng thời. Khóa đầy đủ cho phép 8 yêu cầu đồng thời và 300 yêu cầu mỗi phút. Hãy giảm max_concurrency hoặc đợi hết thời gian Retry-After.

Tôi có thể sử dụng LangGraph thay vì vòng lặp đơn giản không?

Có. Agent có sẵn của LangGraph sử dụng cùng đối tượng ChatOpenAI và cùng danh sách công cụ, nên mã kết nối không thay đổi.

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.

Lấy khóa API