Descobrir Modelos com o Python SDK e a API REST

Explore o catálogo de modelos do OCI Generative AI, filtre modelos para seu aplicativo e inspecione metadados de modelo com solicitações Python SDK e REST assinadas.

Visão Geral

A API de Descoberta de Modelo reúne identificadores de modelo, recursos, compatibilidade de API, parâmetros de configuração e disponibilidade regional. Use esses metadados para escolher modelos para um assistente de chat, um aplicativo de pesquisa ou um workflow multimodal antes de gravar uma solicitação de inferência.

Os aplicativos podem consultar o catálogo para criar interfaces de seleção de modelo e atualizar as opções disponíveis. As informações do ciclo de vida regional ajudam a planejar atualizações e avaliar substituições reportadas.

MetadataO que relataComo utilizá-lo
Identidade e provedorIdentificadores de modelo e informações do fornecedor.Localize um provedor e copie um ID de modelo exato.
Tarefas e modalidadesRecursos de modelo e tipos suportados de entrada para saída.Identifique candidatos para bate-papo, incorporações, reclassificação ou fluxos de trabalho multimodais.
Compatibilidade da APIRecursos de API de inferência reportados para o modelo.Selecione uma API que o modelo suporta.
Disponibilidade regionalDomínios, regiões e modos de atendimento sob demanda ou dedicados.Localize candidatos para o seu local de implantação e modo de atendimento.
Acesso hospedado ou proxyA classificação de acesso do modelo.Revise a documentação apropriada de implantação e tratamento de dados.
ParâmetrosNomes, tipos, intervalos, padrões e descrições relatados.Crie formulários de configuração e verifique as definições com base nos metadados retornados.
Ciclo de vidaDatas de descontinuação e baixa por região e modo de serviço, além de substituições quando fornecidas.Identificar implantações afetadas e avaliar candidatos à migração.
FiltrosID do modelo, realm, região, recurso, recurso de API, modo de serviço, tipo de acesso e status do ciclo de vida.Crie um seletor de modelo focado ou automatize pesquisas de catálogo.

Os modelos individuais podem não preencher todos os campos. O Discovery ajuda você a selecionar e configurar modelos. Ele não chama inferência, concede acesso ou qualidade de modelo de benchmark. Valide um modelo selecionado e qualquer substituição sugerida com a carga de trabalho do aplicativo.

Neste tutorial, você se autentica com uma sessão do OCI IAM, consulta descoberta com o Python SDK, envia a mesma solicitação por meio de REST e tenta dez exemplos práticos. Você também aprende a listar modelos já importados para seu compartimento.

Observação

A operação é ListModelDiscovery. É diferente do ponto final list_models(), list_imported_models() e do ponto final /models compatível com OpenAI. Enviar uma solicitação de descoberta para Chicago não restringe os resultados do catálogo para Chicago. Use um filtro region para selecionar a região do catálogo.

Antes de Começar

Para concluir este tutorial, você precisa:

  • Uma conta do OCI e um compartimento onde você pode inspecionar modelos. ListModelDiscovery requer GENERATIVE_AI_MODEL_INSPECT. Consulte Permissões do Modelo.
  • Para obter exemplos de modelo importado, a permissão para inspecionar modelos importados no compartimento selecionado e um recurso importado existente a ser encontrado. Consulte Permissões de Modelo Importadas.
  • Python 3.11 ou posterior, uv e uma CLI do OCI instalada. Os comandos usam um shell compatível com Bash no macOS, Linux ou Subsistema Windows para Linux.
  • Um browser para autenticação de sessão da CLI do OCI e acesso ao ponto final de serviço. Esses exemplos usam o Meio-Oeste dos EUA (Chicago) no realm comercial OC1.

Os exemplos usam a assinatura de solicitação do OCI IAM com um token de sessão e sua chave privada. Uma chave de API do OCI Generative AI é uma credencial separada e não substitui o signatário usado aqui.

1. Prepare o Ambiente e Entre

  1. Crie e ative um ambiente virtual Python e instale os pacotes:
    uv venv --python 3.11 .venv
    source .venv/bin/activate
    uv pip install --upgrade oci requests

    Se o ambiente já existir, ative-o antes de instalar ou atualizar os pacotes.

  2. Verifique se o SDK instalado fornece o método de descoberta e se a CLI do OCI está disponível:
    python -c 'import oci; print(oci.__version__); print(hasattr(oci.generative_ai.GenerativeAiClient, "list_model_discovery"))'
    oci --version

    A verificação do método deve imprimir True. Se ele imprimir False, instale uma versão do SDK que inclua o list_model_discovery.

  3. Defina o perfil de exemplo, a região de ponto final e o compartimento para este shell:
    export OCI_DISCOVERY_PROFILE=GENAI_DISCOVERY
    export OCI_DISCOVERY_REGION=us-chicago-1
    export OCI_COMPARTMENT_ID='<your-compartment-ocid>'

    Substitua o placeholder do compartimento por um compartimento que você possa acessar. GENAI_DISCOVERY é o nome do perfil de exemplo. Os scripts leem essas variáveis de ambiente sem usar um compartimento padrão.

  4. Crie uma sessão da CLI e conclua o acesso ao browser:
    oci session authenticate \
      --profile-name "$OCI_DISCOVERY_PROFILE" \
      --region "$OCI_DISCOVERY_REGION"

    A CLI armazena o perfil em ~/.oci/config. Os exemplos do Python carregam o token de sessão e a chave privada do perfil com SecurityTokenSigner. Quando a sessão expirar, autentique-se novamente e reinicie o script ou a sessão Python interativa. Consulte Autenticação baseada em token para a CLI.

2. Descoberta de Consulta com o Python SDK

Este exemplo localiza modelos de chat sob demanda atuais na região selecionada. Ele segue a paginação e imprime IDs modelo, fornecedores e recursos. As funções auxiliares são reutilizadas em exemplos posteriores.

  1. Salve o seguinte código como model_discovery.py em seu diretório de trabalho:
    """Query OCI Generative AI model metadata with an IAM session."""
    
    import os
    import re
    import unicodedata
    from pathlib import Path
    
    import oci
    
    
    def load_session():
        config = oci.config.from_file(
            profile_name=os.environ["OCI_DISCOVERY_PROFILE"]
        )
        config["region"] = os.environ["OCI_DISCOVERY_REGION"]
        token = Path(config["security_token_file"]).expanduser().read_text(
            encoding="utf-8"
        ).strip()
        private_key = oci.signer.load_private_key_from_file(
            str(Path(config["key_file"]).expanduser()),
            config.get("pass_phrase"),
        )
        signer = oci.auth.signers.SecurityTokenSigner(token, private_key)
        return config, signer
    
    
    def make_client():
        config, signer = load_session()
        return oci.generative_ai.GenerativeAiClient(config, signer=signer)
    
    
    def fetch_models(client, compartment_id, source="discovery", **filters):
        if source not in {"discovery", "imported"}:
            raise ValueError("source must be discovery or imported")
        operation = (
            client.list_model_discovery
            if source == "discovery"
            else client.list_imported_models
        )
        items = []
        while True:
            response = operation(compartment_id=compartment_id, **filters)
            items.extend(oci.util.to_dict(response.data)["items"])
            next_page = response.headers.get("opc-next-page")
            if not next_page:
                return items
            filters["page"] = next_page
    
    
    def normalized(value):
        value = unicodedata.normalize("NFKC", str(value)).casefold()
        return " ".join(re.findall(r"[^\W\d_]+|\d+", value))
    
    
    def search_models(models, query):
        terms = [normalized(term) for term in query.split()]
        terms = [term for term in terms if term]
    
        def matches(model):
            values = [
                model.get(field)
                for field in ("model_id", "id", "display_name", "vendor", "version")
            ]
            values.extend(
                value for value in (model.get("data_source") or {}).values()
                if isinstance(value, str)
            )
            candidates = [normalized(value) for value in values if value]
            return all(
                any(
                    re.search(
                        (r"(?<!\d)" if term[0].isdigit() else "")
                        + re.escape(term),
                        value,
                    )
                    for value in candidates
                )
                for term in terms
            )
    
        return [model for model in models if matches(model)]
    
    
    def show(models):
        print(f"{len(models)} matching model(s)")
        for model in models:
            name = (
                model.get("model_id")
                or model.get("display_name")
                or model.get("id")
            )
            capabilities = ", ".join(model.get("capabilities") or [])
            vendor = model.get("vendor") or "not reported"
            print(f"{name} | vendor={vendor} | capabilities={capabilities}")
    
    
    if __name__ == "__main__":
        client = make_client()
        models = fetch_models(
            client,
            os.environ["OCI_COMPARTMENT_ID"],
            region=[os.environ["OCI_DISCOVERY_REGION"]],
            capability=["CHAT"],
            serving_mode=["ON_DEMAND"],
            is_deprecated=False,
            is_on_demand_retired=False,
        )
        show(models)
  2. Execute o script no ambiente ativado:
    python model_discovery.py
  3. Revise os modelos correspondentes e copie um identificador que você deseja inspecionar.

    Os resultados dependem do catálogo atual e de seus filtros. Um resultado vazio não é um teste de autenticação ou uma prova de que um modelo não pode ser importado.

    O SDK deriva seu ponto final de gerenciamento do config["region"]. O argumento region=[...] separado filtra a disponibilidade do catálogo. Nenhum valor configura um ponto final de inferência.

    Para obter detalhes do método, consulte GenerativeAiClient.list_model_discovery.

Você tem uma consulta de descoberta paginada e funções reutilizáveis para pesquisa local e inventário de modelo importado.

3. Chamar a API REST de Descoberta Diretamente

Uma solicitação direta expõe o método HTTP, o caminho, os parâmetros de consulta e os cabeçalhos de resposta. Ele chama a mesma operação de descoberta do SDK. A solicitação ainda requer autorização do OCI IAM.

GET /20231130/modelDiscovery?compartmentId=<your-compartment-ocid>
  1. Defina o ponto final público de gerenciamento de Chicago:
    export OCI_DISCOVERY_ENDPOINT=https://generativeai.us-chicago-1.oci.oraclecloud.com

    Este exemplo usa o ponto final de Chicago OC1. Para outra região ou realm, use o ponto final de gerenciamento apropriado na referência de API e atualize OCI_DISCOVERY_REGION para o filtro de catálogo. O Discovery usa a API de gerenciamento, não um URL de inferência de chat.

  2. Envie uma solicitação assinada com a CLI do OCI:
    oci raw-request \
      --profile "$OCI_DISCOVERY_PROFILE" \
      --auth security_token \
      --http-method GET \
      --target-uri "${OCI_DISCOVERY_ENDPOINT}/20231130/modelDiscovery?compartmentId=${OCI_COMPARTMENT_ID}&region=${OCI_DISCOVERY_REGION}&capability=CHAT&servingMode=ON_DEMAND&isDeprecated=false&isOnDemandRetired=false"

    A CLI assina a solicitação e exibe a resposta. Para recuperar outra página, informe o valor opc-next-page retornado como o parâmetro de consulta page codificado por URL. O exemplo de Python abaixo segue a paginação automaticamente.

  3. Salve o seguinte código como model_discovery_rest.py ao lado de model_discovery.py:

    O script importa o auxiliar de assinatura de sessão do exemplo do SDK. Ele envia solicitações HTTP por meio de requests e imprime IDs de status e solicitação para erro padrão.

    """Call Model Discovery over HTTP with OCI request signing."""
    
    import os
    import sys
    
    import requests
    
    from model_discovery import load_session
    
    
    def fetch_rest_models(signer, endpoint, compartment_id, region):
        url = endpoint.rstrip("/") + "/20231130/modelDiscovery"
        params = {
            "compartmentId": compartment_id,
            "region": [region],
            "capability": ["CHAT"],
            "servingMode": ["ON_DEMAND"],
            "isDeprecated": "false",
            "isOnDemandRetired": "false",
        }
        items = []
        while True:
            response = requests.get(
                url,
                params=params,
                headers={"Accept": "application/json"},
                auth=signer,
                timeout=(10, 30),
                allow_redirects=False,
            )
            request_id = response.headers.get("opc-request-id", "not reported")
            print(
                f"HTTP {response.status_code} | request ID: {request_id}",
                file=sys.stderr,
            )
            if 300 <= response.status_code < 400:
                raise RuntimeError("Check the service endpoint. Redirect not followed.")
            response.raise_for_status()
            items.extend(response.json()["items"])
            next_page = response.headers.get("opc-next-page")
            if not next_page:
                return items
            params["page"] = next_page
    
    
    if __name__ == "__main__":
        _, signer = load_session()
        models = fetch_rest_models(
            signer,
            os.environ["OCI_DISCOVERY_ENDPOINT"],
            os.environ["OCI_COMPARTMENT_ID"],
            os.environ["OCI_DISCOVERY_REGION"],
        )
        print(f"{len(models)} matching model(s)")
        for model in models:
            print(f"{model['modelId']} | vendor={model.get('vendor') or 'not reported'}")
  4. Execute o exemplo REST:
    python model_discovery_rest.py
  5. Compare os identificadores de modelo com os resultados do SDK.

    Use o mesmo perfil, compartimento, região de ponto final e filtros para a comparação. Os resultados podem mudar à medida que o catálogo é alterado.

    Os campos de resposta REST usam camelCase, como modelId. A saída oci.util.to_dict() do SDK usa snake_case, como model_id. Para filtros REST com valor de lista, repita a chave de consulta, por exemplo, region=us-chicago-1&region=us-ashburn-1. Os codificadores de pacote requests são listados em params dessa forma.

4. Prepare os exemplos práticos

  1. Salve essa configuração como model_discovery_recipes.py ao lado de model_discovery.py:
    import json
    import os
    from collections import Counter
    from pathlib import Path
    
    from model_discovery import fetch_models, make_client, search_models, show
    
    client = make_client()
    compartment_id = os.environ["OCI_COMPARTMENT_ID"]
    region = os.environ["OCI_DISCOVERY_REGION"]
    
    
    def fetch(source="discovery", **filters):
        return fetch_models(client, compartment_id, source=source, **filters)
  2. Inicie o Python com a configuração carregada:
    python -i model_discovery_recipes.py

    A opção -i mantém o Python aberto. Execute qualquer exemplo nas seções a seguir nessa sessão. Como alternativa, anexe um exemplo ao arquivo de configuração e execute-o sem -i.

Escolha Filtros no Catálogo Retornado

Antes de selecionar filtros, inspecione os valores reportados para os modelos na sua região:

catalog = fetch(region=[region])
for field in ("capabilities", "api_capability", "model_access", "vendor"):
    counts = Counter()
    for model in catalog:
        values = model.get(field) or []
        if isinstance(values, str):
            values = [values]
        counts.update(set(values))
    print(field, dict(sorted(counts.items())))

for field in ("realm", "region", "serving_modes"):
    counts = Counter()
    for model in catalog:
        values = set()
        for availability in model.get("availability") or []:
            value = availability.get(field)
            if isinstance(value, list):
                values.update(value)
            elif value:
                values.add(value)
        counts.update(values)
    print(field, dict(sorted(counts.items())))

Cada contagem é o número de entradas de modelo retornadas associadas a um valor. Um modelo pode contribuir para vários valores de capacidade ou disponibilidade. As contagens refletem os filtros de consulta.

Argumento SDKExemplo ou finalidade
region, realmListas de identificadores de região ou valores de realm. Utilizar valores reportados pelo catálogo.
model_idUm identificador de modelo exato.
capabilityUma lista como ["CHAT"], ["TEXT_EMBEDDINGS"] ou ["TEXT_RERANK"].
api_capabilityUma lista de identificadores de API reportados pelo catálogo.
serving_mode["ON_DEMAND"] ou ["DEDICATED"].
model_access["HOSTED"] ou ["PROXY"].
is_deprecatedFalse exclui modelos obsoletos.
is_on_demand_retired, is_dedicated_retiredUse False para o modo de serviço cujos modelos desativados você deseja excluir.
page, limitToken de paginação e tamanho de página solicitado. O exemplo segue opc-next-page até que todas as páginas sejam recuperadas.

Use search_models() para correspondência de substring local após extrair todas as páginas. A pesquisa não é um parâmetro de ListModelDiscovery. Revise a referência de operação para obter o vocabulário completo do filtro.

Dez Exemplos Práticos de Python

1. Procurar Modelos nos Dois Modos de Porção

Filtre pela região de implantação pretendida. A omissão de serving_mode deixa os modelos sob demanda e dedicados elegíveis.

catalog = fetch(region=[region])
show(catalog)

2. Localizar Modelos por Nome Parcial ou Fornecedor

Pesquise os metadados retornados localmente. Cada termo separado por espaço deve corresponder a um campo pesquisável. A correspondência ignora maiúsculas e minúsculas e pontuação. O filtro model_id do serviço requer um identificador exato.

catalog = fetch(region=[region])
show(search_models(catalog, "grok"))

Altere o termo de pesquisa para um profissional de saúde ou família de modelos em seus resultados.

3. Localizar Modelos de Chat sob Demanda Atuais

Exclua modelos e modelos obsoletos baixados para serviço sob demanda.

show(fetch(
    region=[region],
    capability=["CHAT"],
    serving_mode=["ON_DEMAND"],
    is_deprecated=False,
    is_on_demand_retired=False,
))

4. Localizar Modelos para Serviço Dedicado

Aplique o filtro de retirada para serviço dedicado. Esta consulta pesquisa o catálogo de descoberta. Para listar recursos importados, use o exemplo 8.

show(fetch(
    region=[region],
    serving_mode=["DEDICATED"],
    is_deprecated=False,
    is_dedicated_retired=False,
))

5. Encontrar modelos de incorporação e reclassificação

Consulte cada recurso separadamente. A descoberta usa TEXT_EMBEDDINGS e TEXT_RERANK. Os recursos de modelo importado utilizam um vocabulário de capacidade diferente, incluindo EMBEDDING e RERANK.

for capability in ("TEXT_EMBEDDINGS", "TEXT_RERANK"):
    print("\nCapability:", capability)
    show(fetch(region=[region], capability=[capability]))

6. Localizar Modelos de Proxy com um Recurso de API Reportado

Leia os identificadores de API retornados pelo catálogo e copie um valor para filtrar os modelos de proxy. Revise as notas de chamada externa e o tratamento de dados para um modelo selecionado.

catalog = fetch(region=[region], model_access=["PROXY"])
api_values = sorted({
    api for model in catalog for api in model.get("api_capability") or []
})
print(api_values)
if api_values:
    api = input("Enter an API capability from the list: ").strip()
    if api in api_values:
        show(fetch(
            region=[region],
            model_access=["PROXY"],
            api_capability=[api],
        ))
    else:
        print("Enter an exact value from the returned list.")
else:
    print("No API capabilities were reported for these results.")

7. Inspecionar Parâmetros de Modelo e Detalhes do Ciclo de Vida

Copie um identificador de modelo exato de seus resultados. Inspecione as entradas de disponibilidade completas para manter cada região associada a seus modos de serviço, datas do ciclo de vida e substituições relatadas.

model_id = input("Enter an exact model ID from your results: ").strip()
for model in fetch(model_id=model_id):
    print(model["model_id"])
    for field in (
        "api_capability", "modality_support", "parameters", "availability"
    ):
        print(field)
        print(json.dumps(model.get(field), indent=2, default=str))

Um campo pode ficar vazio ou não ser reportado. Avalie qualquer substituição sugerida com seu aplicativo antes de migrar.

8. Encontrar um Modelo Qwen Importado

Use source="imported" para consultar importações existentes no compartimento e na região do cliente. Este exemplo procura um modelo Qwen 3.6 35B. Ele retornará uma correspondência somente se você tiver importado um modelo de correspondência e puder inspecionar esse recurso. Consulte Modelos Qwen 3.6 Compatíveis para obter compatibilidade de importação.

imports = fetch(source="imported")
selected = search_models(imports, "qwen 3.6 35B")
show(selected)
for model in selected:
    print("Imported resource OCID:", model["id"])
    print("Resource state:", model.get("lifecycle_state"))

O OCID retornado identifica o recurso de modelo importado. Um estado de recurso ACTIVE não estabelece que um ponto final de inferência tenha sido implantado. Para obter as etapas de implantação, consulte Gerenciando Modelos Importados.

9. Comparar Descoberta com Recursos Importados

Compare as duas origens quando um modelo aparece no inventário importado, mas não na descoberta. Os resultados da descoberta e os recursos importados para seu compartimento respondem a diferentes perguntas.

print("Discovery catalog for the selected region:")
show(search_models(fetch(region=[region]), "qwen"))
print("\nImported resources in this compartment and client region:")
show(search_models(fetch(source="imported"), "qwen"))

Se os resultados importados estiverem vazios, verifique o compartimento, a região do cliente e as permissões. A consulta importada-modelo não verifica outros compartimentos ou regiões.

10. Exportar Modelos Importados Correspondentes

Grave os metadados completos dos recursos importados selecionados em um arquivo JSON local.

selected = search_models(fetch(source="imported"), "qwen 3.6 35B")
Path("qwen-imports.json").write_text(
    json.dumps({"items": selected}, indent=2, default=str),
    encoding="utf-8",
)
print(f"Saved {len(selected)} matching resource(s) to qwen-imports.json")

Verificar o Resultado e a Solução de Problemas

Uma solicitação bem-sucedida retorna metadados de modelo ou uma lista vazia quando nenhuma entrada corresponde. Revise identificadores, recursos, parâmetros e disponibilidade antes de criar uma solicitação de inferência.

SintomaO que verificar
O SDK não tem método list_model_discovery.Faça upgrade do oci no ambiente virtual ativo e repita a verificação do método.
Uma solicitação assinada retorna HTTP 401.Valide ou recrie a sessão da CLI, verifique o perfil selecionado e reinicie o Python para que ele leia o novo token.
O serviço relata um erro de autorização.Verifique as permissões do IAM e o OCID do compartimento. O estoque importado requer permissão para inspecionar recursos importados-modelo.
Um filtro de ID de modelo exato não retorna resultados.Procure ou pesquise localmente primeiro e, em seguida, copie um identificador da resposta. Verifique os filtros de região e ciclo de vida.
A resposta inclui disponibilidade fora da região do ponto final.Defina o filtro de descoberta region explicitamente e inspecione cada entrada de disponibilidade. A região do ponto final sozinha não restringe os resultados do catálogo.
Um modelo importado não foi retornado.Verifique a região, o compartimento, as permissões e o nome para exibição do recurso do cliente. Use list_imported_models() para inventário importado.
Somente parte do catálogo é retornada.Siga o opc-next-page. Os exemplos de Python nesta página recuperam todas as páginas.
A solicitação REST falha enquanto o SDK é bem-sucedido.Use o mesmo perfil e compartimento. Verifique o ponto final de gerenciamento, o caminho e os nomes de consulta camelCase e, em seguida, verifique o status e o ID da solicitação.

Para o comando da CLI gerado, consulte list-model-discovery. Para recursos importados, consulte ListImportedModels. Para os campos de metadados retornados pela descoberta, consulte ModelDiscovery.