LLM Client
O LLMClient realiza chamadas LLM diretas dentro de uma action. Use quando a action precisa classificar, gerar texto ou tomar decisões com base em IA — independente do ciclo principal do agente.
Use o LLMClient quando a action precisa de um resultado LLM antes de retornar para o agente. Para a maioria das ações, o LLM do próprio agente já processa o retorno de ResponseToAgent. O LLMClient é para casos como:
- Classificação de intenção dentro da action
- Geração de texto estruturado (JSON, resumos)
- Seleção programática entre opções
- Chamadas LLM com parâmetros diferentes do modelo principal do agente
Inicialização
from actions_sdk.core.types.action_context import ActionContext
from actions_sdk.features.llm import LLMClient
ctx: ActionContext
llm = LLMClient(ctx)
Funciona com ActionContext e TaskContext. Extrai ctx.llm_config e ctx.tracer automaticamente.
Métodos
completion(system_prompt, user_prompt)
Realiza uma chamada de completion ao LLM com retry automático.
llm = LLMClient(ctx)
# Resposta em texto livre
resposta = llm.completion(
system_prompt="Você é um classificador de intenções.",
user_prompt="Quero cancelar meu pedido.",
generation_name="classificar-intencao",
)
texto = resposta.get("content") # str
# Resposta estruturada em JSON
resultado = llm.completion(
system_prompt="Classifique a intenção. Responda com JSON: {\"intencao\": \"...\", \"confianca\": 0.0}",
user_prompt="Preciso de ajuda com meu pedido.",
response_format={"type": "json_object"},
generation_name="classificar-intencao-json",
)
intencao = resultado.get("intencao") # str
confianca = resultado.get("confianca") # float
Parâmetros:
| Parâmetro | Tipo | Padrão | Descrição |
|---|---|---|---|
system_prompt | str | — | Instrução de sistema para o LLM |
user_prompt | str | — | Mensagem do usuário |
response_format | dict | None | None | Formato estruturado: {"type": "json_object"} |
model | str | None | ctx.llm_config.model | Modelo a usar |
temperature | float | 0.3 | Temperature da geração (0.0 a 1.0) |
max_tokens | int | None | None | Limite de tokens na resposta |
generation_name | str | "llm-completion" | Nome para o span de rastreamento (Langfuse) |
Retorna:
- Com
response_format:dict— JSON parseado da resposta - Sem
response_format:{"content": "texto_da_resposta"}
Exceções:
LLMClientError— após esgotar todas as tentativas de retry
Retry automático
O LLMClient realiza retry com exponential backoff automaticamente. O número de tentativas é configurado em ctx.llm_config.max_retries.
Para desabilitar retry:
# No motor, ao criar o contexto:
# LLMConfig(max_retries=0)
Erros e Exceções
| Exceção | Quando ocorre | Como tratar |
|---|---|---|
LLMClientError | Após esgotar todas as tentativas | Capture e retorne ResponseToAgent com ERROR |
from actions_sdk.features.llm.client import LLMClientError
try:
resposta = llm.completion(
system_prompt="...",
user_prompt="...",
)
except LLMClientError as erro:
return ResponseToAgent(
status=ResponseStatus.ERROR,
instruction=f"Falha na chamada LLM: {erro}",
)
Exemplo completo
Baseado na action gerar_piada do agente de homologação:
import traceback
from actions_sdk.core.types.action_context import ActionContext
from actions_sdk.core.types.responses import ResponseStatus, ResponseToAgent
from actions_sdk.features.conversational.state import StateManager
from actions_sdk.features.llm import LLMClient
from actions_sdk.features.tracing import ActionSpan
ctx: ActionContext
SYSTEM_PROMPT = (
"Você é um comediante talentoso. Crie uma piada curta, engraçada e inofensiva "
"sobre o tema fornecido. Responda apenas com a piada, sem introduções."
)
CHAVE_PROGRESSO = "action.llm.progresso"
GENERATION_NAME = "action-gerar-piada"
def gerar_piada(tema: str):
span = ActionSpan(ctx)
state = StateManager(ctx)
span.event("action.llm.inicio", {"tema": tema})
try:
llm = LLMClient(ctx)
resultado = llm.completion(
system_prompt=SYSTEM_PROMPT,
user_prompt=f"Crie uma piada sobre: {tema}",
generation_name=GENERATION_NAME,
)
piada = resultado.get("content", "")
state.update(CHAVE_PROGRESSO, "SUCESSO ✓")
span.event("action.llm.sucesso", {"tema": tema, "chars": len(piada)})
return ResponseToAgent(
status=ResponseStatus.SUCCESS,
instruction=f"LLMClient.completion() concluído.\nPiada gerada:\n{piada}",
state_updates=state.get_full_state(),
)
except Exception as erro:
state.update(CHAVE_PROGRESSO, "ERRO ✗")
span.event("action.llm.erro", {"erro": str(erro)})
return ResponseToAgent(
status=ResponseStatus.ERROR,
instruction=f"Falha na chamada LLM: {traceback.format_exc()}",
state_updates=state.get_full_state(),
)