PT ▾
Obter chave de API

Uncensored VideoAPI Sora 2: Usando Texto Sem Censura em Pipelines de Vídeo

Tutorial de agentes de IA com LangChain e API compatível com OpenAI

Este tutorial de agentes de IA com LangChain conecta LangChain a um endpoint compatível com OpenAI, vincula duas ferramentas e executa um loop de agente que você pode ler linha a linha. Cada snippet usa a mesma base URL e o nome do modelo uncensored.

Atualizado

Braço robótico alternando entre cubos de ferramentas em loop, ilustrando um agente LangChain chamando ferramentas

Pontos principais

  • ChatOpenAI funciona sem alterações: defina base_url, api_key e model para uncensored.
  • A API suporta chamada de funções, então bind_tools e o agente pré-construído funcionam.
  • Limite iterações do loop e valide argumentos de ferramentas; modelos de pesos abertos às vezes os interpretam errado.
  • Respeite 8 requisições simultâneas com chave completa ao executar agentes em paralelo.

O que você precisa antes de começar

Você precisa do Python 3.10 ou mais recente, uma chave de API e alguns pacotes. A chave vem da página da chave de API: entre com Google ou com e-mail e senha, depois resgate o crédito de teste grátis de $0,50 com um clique. A chave de teste permite 2 requisições simultâneas e 60 por minuto, o que é suficiente para tudo neste artigo se você executar um agente por vez.

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

A API expõe POST /v1/chat/completions e GET /v1/models. O LangChain só precisa do primeiro. O modelo é um único modelo de pesos abertos ajustado para responder sem recusas de conteúdo para uso adulto legal; ele é executado por um provedor independente e não é a API oficial de nenhum fornecedor de modelo. A documentação lista os cabeçalhos e limites se você quiser tê-los ao lado do seu editor.

Como as peças mapeiam para a API

Ajuda saber o que o LangChain faz na rede. Um HumanMessage torna-se uma mensagem com role user. Um AIMessage torna-se assistant, e quando carrega chamadas de ferramentas, elas aparecem na mensagem do assistente como um array tool_calls. Um ToolMessage torna-se role tool com o ID de chamada correspondente. O prompt de sistema vai primeiro como role system.

Esse mapeamento é importante para depuração. Se um agente se comportar estranhamente, imprima a lista de mensagens antes de cada chamada e leia como uma transcrição. Você geralmente encontra o problema em um minuto: um resultado de ferramenta vazio, um ID de chamada que não corresponde ou um histórico que cresceu muito além do esperado. A palavra agentic pode soar como mágica, mas cada etapa é uma requisição de chat padrão.

Passo 1: Conectar ChatOpenAI

Toda a integração tem três argumentos. O LangChain constrói solicitações padrão estilo OpenAI, então o servidor não consegue diferenciar.

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)

Se isso imprimir três linhas, a infraestrutura funciona. Se você receber 401, verifique a chave. Se receber 404, verifique se a URL termina em /v1 e não tem caminho extra. max_retries é uma opção do cliente, e ajuda com as respostas temporárias 429 que carregam Retry-After: 5.

O streaming funciona da mesma forma que você usaria com qualquer modelo OpenAI: chame llm.stream(...) e itere. O último chunk carrega o uso, então você pode registrar a contagem de tokens por chamada.

Passo 2: Definir ferramentas

Um agente é um loop: o modelo lê a conversa, ou responde ou pede uma ferramenta, seu código executa a ferramenta e o resultado volta para o modelo. As ferramentas abaixo são funções Python simples. São deliberadamente simples, porque o objetivo é ver a mecânica.

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]

A docstring e as anotações de tipo tornam-se a descrição e o esquema da ferramenta que o modelo vê. Escreva-os como se estivesse instruindo um colega. Uma docstring vaga é a razão mais comum para um agente escolher a ferramenta errada. Se você escrever scripts para vídeo, o mesmo padrão escala para ferramentas que consultam listas de tomadas ou verificam um orçamento de duração, um tópico abordado na página do gerador de scripts Sora 2.

Passo 3: Executar o loop do agente manualmente

Os helpers pré-construídos escondem o loop. Escrevê-lo uma vez você mesmo torna cada bug posterior mais fácil de encontrar.

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)

Três detalhes importam. O limite range(6) impede que um modelo confuso entre em loop para sempre, e também limita seu gasto. O tool_call_id deve corresponder à chamada que responde. E o modelo pode solicitar várias ferramentas em uma única resposta, é por isso que o loop interno lida com uma lista.

Nos bastidores, a requisição carrega um array tools e a resposta carrega tool_calls, com resultados retornados como mensagens com role: "tool". Você pode forçar uma ferramenta específica com tool_choice, que o LangChain expõe como argumento para bind_tools.

Passo 4: Use o agente LangGraph pré-construído

Uma vez que o loop manual faz sentido, o agente pré-construído economiza linhas. Ele usa o mesmo modelo e as mesmas ferramentas.

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 e LangGraph alteram suas APIs entre lançamentos, e alguns helpers foram renomeados ou movidos. Se uma importação falhar, verifique a documentação atual do LangChain para o construtor de agente equivalente. A parte da conexão, ChatOpenAI com uma base URL, permanece a mesma.

Escolhendo entre um loop e um grafo

O loop escrito à mão é suficiente para agentes que escolhem entre algumas ferramentas e param. É fácil de ler, fácil de logar e não tem surpresas de framework. Mova para LangGraph quando precisar de branches que dependem de estado: uma etapa de revisão que envia trabalho de volta para outra passagem, aprovação humana antes de uma ferramenta arriscada, ou vários sub-agentes especializados que passam resultados uns aos outros.

O que você escolher, mantenha cada node pequeno e dê a ele um trabalho. Um node de planejamento que produz uma lista numerada curta em JSON, um node de execução que roda ferramentas, e um node de escrita que produz o texto final são mais fáceis de testar do que um prompt gigante único. Eles também permitem usar diferentes temperaturas: baixa para planejamento e uso de ferramentas, maior para a etapa de escrita. Como cada node é uma chamada normal de chat completion, a mesma chave, URL e nome de modelo servem todos eles, e o custo é simplesmente a soma das chamadas.

Um último hábito: imprima o total de tokens em execução. Agentes que parecem baratos em demo podem gastar dez vezes mais em uma tarefa real bagunçada, e os números de uso em cada resposta tornam isso visível na primeira execução, antes que vire surpresa no seu saldo.

Memória, teste e saída estruturada

O loop acima esquece tudo quando o script termina. A memória mais simples é a própria lista de mensagens: mantenha-a entre turnos do usuário, anexe cada nova pergunta e remova as mensagens mais antigas quando ficar longa. Para sessões longas, substitua mensagens antigas por um resumo curto escrito pelo modelo. Como a entrada é cobrada por token, um resumo de 500 tokens vence 20.000 tokens de histórico bruto tanto em custo quanto em foco.

Testar agentes é principalmente sobre verificar comportamento observável. Defina temperature para 0 ou passe um seed fixo, que a API repassa, para execuções mais repetíveis. Então escreva algumas perguntas onde você sabe qual ferramenta deve ser chamada, e verifique os nomes das ferramentas e os argumentos na lista de mensagens, não a redação exata da resposta. Execute isso após cada mudança em um prompt ou descrição de ferramenta. Mudar uma docstring pode mudar qual ferramenta o modelo escolhe, e um teste é a maneira mais barata de notar.

Registre três coisas em cada execução: o número de etapas, as chamadas de ferramentas com seus argumentos e o uso de tokens. Quando uma execução falha, essas três linhas dizem se o modelo escolheu mal, uma ferramenta falhou, ou o loop ficou sem etapas.

Saída estruturada e modo JSON

Agentes frequentemente precisam devolver dados, não texto corrido. A API suporta modo JSON através de response_format: {"type":"json_object"}. No LangChain você pode pedir isso com llm.bind(response_format={"type": "json_object"}). Diga ao modelo no prompt que a resposta deve ser um objeto JSON e nomeie as chaves que espera, depois faça o parse da string e valide com Pydantic. Não confie que o parse sempre tenha sucesso; envolva em um retry que envia o texto de erro de volta para o modelo uma vez.

Armadilhas e como corrigi-las

  • Argumentos de ferramenta ruins. Um modelo de pesos abertos às vezes envia uma string onde você declarou um inteiro. Valide argumentos, retorne uma mensagem de erro curta da ferramenta e deixe o modelo corrigir-se no próximo passo.
  • Loops descontrolados. Sempre limite iterações. Registre cada etapa enquanto desenvolve.
  • Agentes paralelos. Uma chave completa permite 8 requisições simultâneas. Se você executa um lote, defina config={"max_concurrency": 4} no llm.batch para deixar folga. Exceder o limite retorna 429 com o código concurrency; exceder 300 requisições por minuto retorna rate_limited.
  • Streaming mais ferramentas. Uma solicitação streaming mantém seu slot de concorrência até o fim do stream, então não inicie novas chamadas de dentro de um manipulador de stream em uma chave de teste.
  • Histórico crescendo. Cada etapa reenvia a lista completa de mensagens. A janela de contexto é de 100.000 tokens, mas você paga pela entrada em cada chamada.

Quanto custa uma execução de agente

Pegue um agente modesto que faz 4 chamadas de modelo para concluir uma tarefa, com um prompt médio de 3.000 tokens e 200 tokens de saída por chamada. Entrada: 4 x 3.000 = 12.000 tokens, que é 12.000 x $0,15 / 1.000.000 = $0,0018. Saída: 4 x 200 = 800 tokens, que é $0,0004. Uma execução custa $0,0022, então 1.000 execuções custam $2,20. O crédito de teste de $0,50 cobre cerca de 227 dessas execuções. Solicitações falhas ou recusadas não são cobradas, e o crédito nunca expira. Veja preços para valores de recarga e bônus. Este site aceita apenas cripto, USDT na TRC20 ou USDC na Base.

Perguntas e respostas

O LangChain precisa de integração especial para esta API?

Não. A classe ChatOpenAI do langchain-openai aceita uma base_url, então você a aponta para a API e usa o modelo uncensored. Nenhum adaptador personalizado é necessário.

A API suporta chamada de funções para agentes?

Sim. Ela aceita ferramentas e tool_choice, retorna tool_calls (também em streaming), e recebe resultados de volta como mensagens com role tool.

Por que meu agente para com erro 429?

Você atinge ou o limite de taxa de requisições ou o limite de concorrência. Uma chave completa permite 8 requisições simultâneas e 300 por minuto. Reduza max_concurrency ou aguarde o período Retry-After.

Posso usar LangGraph em vez do loop simples?

Sim. O agente pré-construído do LangGraph usa o mesmo objeto ChatOpenAI e a mesma lista de ferramentas, então o código de conexão não muda.

Sua chave está a um formulário de distância

Crie uma conta, copie a chave e altere a URL base. Essa é toda a configuração.

Obter chave de API