Prompt Manager — Cliente Python
prompt-manager-client é a biblioteca que as aplicações de IA importam para buscar seus prompts na API do Prompt Manager em tempo de execução. Os prompts se atualizam ao vivo: quando alguém commita e publica uma nova versão na UI, a aplicação passa a usá-la em segundos, sem redeploy.
Ela é deliberadamente pequena — três coisas públicas:
PromptManager— cliente síncrono (requests)AsyncPromptManager— cliente assíncrono (httpx), mesma interface comawaitPrompt— o prompt imutável e totalmente resolvido que uma busca retorna
Instalação
O pacote vive neste repositório, em client/. Adicione-o como dependência de path/git, por exemplo com uv:
uv add "prompt-manager-client @ git+ssh://git@bitbucket.org/avisourgente/prompt-manager.git#subdirectory=client"
Requer Python ≥ 3.10. Dependências: requests, httpx, cachetools.
Começo rápido
Crie um cliente por processo na inicialização (ele guarda o cache e a sessão HTTP) e reutilize-o:
from prompt_manager import PromptManager
pm = PromptManager(
application="superchat", # o nome da sua aplicação no manager
environment="prod", # qual deployment seguir
fallback_dir="prompts_fallback", # opcional: snapshots offline (veja abaixo)
)
# Uma chamada: busca (com cache) + preenche variáveis + relata o uso
text = pm.render(
"resposta_juridica",
variables={"pergunta": pergunta, "contexto": contexto},
request_id=request_id, # campos opcionais de observabilidade —
user=user_email, # eles vinculam o caso real ao prompt
metadata={"tenant": tenant}, # na tela de "Registros" do manager
)
render() retorna a string final pronta para enviar ao modelo. Se o prompt define mensagens de chat, você provavelmente quer get_prompt() (abaixo).
Onde o cliente se conecta (base_url)
O endereço da API é resolvido nesta ordem:
- o argumento
base_urldo construtor, se informado; - a variável de ambiente
PROMPT_MANAGER_URL; - o padrão de produção:
http://promptmanager-prod.datalawyer.local.
Ou seja: em produção você não configura nada, e deployments de staging/dev redirecionam todos os clientes com uma única variável de ambiente:
export PROMPT_MANAGER_URL=http://localhost:8000 # ex.: stack de dev local
Async
from prompt_manager import AsyncPromptManager
pm = AsyncPromptManager(application="superchat", environment="prod")
async def handle(question: str) -> str:
return await pm.render("resposta_juridica", variables={"pergunta": question})
Use-o como async context manager (async with AsyncPromptManager(...) as pm:) ou mantenha-o pela vida do processo; ao sair, ele descarrega os relatos de uso pendentes e fecha seu cliente httpx (a menos que você tenha passado o seu próprio).
Trabalhando com o objeto Prompt
get_prompt() retorna o prompt resolvido sem renderizá-lo:
prompt = pm.get_prompt("resposta_juridica")
prompt.template # texto resolvido completo (fragmentos, controles e exemplos já expandidos)
prompt.variables # as variáveis de runtime que o template ainda espera
prompt.version # número da versão commitada que esta resolução usou
prompt.hash # hash do snapshot — registre-o para rastrear qualquer chamada de LLM até o prompt exato
prompt.suggested_model # modelo + parâmetros sugeridos pelo autor do prompt
prompt.suggested_params
prompt.fragment_versions # quais versões de fragmentos foram embutidas
prompt.fewshots # quais bancos de exemplos foram injetados, e quantos exemplos cada um contribuiu
rendered = prompt.render(pergunta="...", contexto="...")
render (tanto no cliente quanto no Prompt) valida os valores: nomes de variáveis desconhecidos, variáveis obrigatórias faltando e {{placeholders}} restantes levantam PromptValidationError. Valores dict/list são codificados em JSON automaticamente.
Mensagens de chat
Um template resolvido pode conter linhas com marcadores de papel {% system %} / {% user %} / {% assistant %}. O cliente mantém o template plano (os marcadores sobrevivem intactos ao render()); para prompts com múltiplas mensagens, divida você mesmo o texto renderizado nessas linhas de marcador: uma nova mensagem começa em cada marcador, e o conteúdo antes do primeiro marcador pertence a system. A resposta do /fetch da API também carrega um array messages já dividido, se você preferir consumi-lo diretamente.
Ambientes
O environment informado na construção é o padrão; qualquer chamada pode sobrescrevê-lo:
pm.get_prompt("resposta_juridica", environment="staging")
"default" é especial: ele sempre segue a versão commitada mais recente, sem precisar de deployment explícito. Ambientes nomeados (prod, staging, …) servem a versão que foi fixada neles pela UI — e caem para a versão mais recente se o prompt nunca foi fixado ali.
Ablação de few-shots (A/B sem exemplos)
fewshots=False resolve o mesmo prompt com todos os bancos de exemplos desligados — é assim que uma aplicação mede o que os exemplos realmente valem:
com_exemplos = pm.render("classificador", variables=v) # normal
sem_exemplos = pm.render("classificador", variables=v, fewshots=False) # ablação
As duas resoluções têm cache e ETag separados.
Cache, resiliência e fallback offline
O cliente é construído para que a API de prompts nunca seja um ponto único de falha:
- Cache com TTL (padrão 45 s,
ttl=no construtor): buscas repetidas dentro da janela não custam nada. - Revalidação por ETag: expirado o TTL, o cliente revalida com
If-None-Match; um prompt inalterado custa um 304, não um novo download. - Último valor conhecido: se a API estiver inacessível, o cliente registra um warning e continua servindo o último prompt buscado com sucesso (por chave nome/ambiente/fewshots), pela vida do processo.
- Arquivos de fallback locais: se a API estiver inacessível e nada foi buscado ainda (ex.: logo após um cold start), o cliente carrega
<fallback_dir>/<nome>.<ambiente>.json, depois<fallback_dir>/<nome>.json.
Só quando os quatro falham ele levanta PromptUnavailableError.
Gere os snapshots de fallback com a CLI incluída (commite-os no seu repositório ou embuta-os na sua imagem, atualizando a cada deploy):
uv run prompt-manager pull --app superchat --env prod --out prompts_fallback/
(--url sobrescreve o endereço da API; caso contrário valem PROMPT_MANAGER_URL / o padrão de produção, igual à biblioteca.)
Relato de uso
Cada render() dispara (fire-and-forget) um relato para POST /api/v1/usage com a identidade do prompt (nome, versão, hash do snapshot) e os valores de variáveis com que foi preenchido. A UI do manager os lê de volta para que os prompts possam ser testados contra casos reais de produção em vez de casos inventados.
- Nunca bloqueia nem quebra um render — falhas são logadas em nível debug e descartadas.
- Passe
request_id,useremetadatapara tornar os casos gravados filtráveis. - Desabilite completamente com
report_usage=False(ex.: em testes), ou no servidor deixandoOPENSEARCH_HOSTvazio.
Referência do construtor
| Parâmetro | Padrão | Significado |
|---|---|---|
application |
(obrigatório) | Nome da aplicação registrada no manager |
base_url |
$PROMPT_MANAGER_URL, senão http://promptmanager-prod.datalawyer.local |
Raiz da API do Prompt Manager |
environment |
"default" |
Ambiente padrão de todas as chamadas |
ttl |
45 |
Segundos que um prompt buscado é servido sem revalidação |
fallback_dir |
None |
Diretório com snapshots offline do prompt-manager pull |
timeout |
10 |
Timeout HTTP em segundos |
session / client |
None |
Traga seu próprio requests.Session / httpx.AsyncClient |
report_usage |
True |
Relata as variáveis de cada render para a tela de Registros |
Release files for prompt-manager-client-dl 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| prompt_manager_client_dl-0.1.0.tar.gz | 20.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| prompt_manager_client_dl-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 31.4 kB
Release files / prompt_manager_client_dl-0.1.0.tar.gz
| Download URL | prompt_manager_client_dl-0.1.0.tar.gz |
|---|---|
| Size | 20.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
96266edea28b5d6677356fcc5054ac7eaca7e775302ca1da53a991fa2784104e
|
|
BLAKE2b-256 checksum How to use checksums |
222e6beb62f044b0dc4fa7bf7dcb48ff3ee1d2926dd2e57d0383d802a595acb2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.12
|
Release files / prompt_manager_client_dl-0.1.0-py3-none-any.whl
| Download URL | prompt_manager_client_dl-0.1.0-py3-none-any.whl |
|---|---|
| Size | 11.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9779b45c0700f9b12fbebccf3a0ae2c554ffe1dd004216dec8fcf14a8ecd664b
|
|
BLAKE2b-256 checksum How to use checksums |
d3c27ffef8a3edc2a5c1fef1e05b4b56d82d7d34df9be5d7c9a957c25dc6bd84
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.12
|