Codex é poderoso, mas ainda precisa de quem sabe programar

Faz tempo que eu quero compartilhar a minha experiência com o Codex. Tenho usado a ferramenta para alguns experimentos e fui, aos poucos, aprendendo como tirar o melhor proveito dela. Mas acredito que a minha primeira experiência pode ajudar na discussão da “mágica” destas ferramentas e que faz com que muitas pessoas diga que a carreira de engenharia de software acabou, que as pessoas programadoras serão substituídas e etc.

O meu teste foi bem simples: pedi para o Codex criar um pequeno serviço de “reasoning” usando o chatGPT. A ideia era que o serviço recebesse uma mensagem de texto, incluísse essa mensagem num script e fizesse uma chamada para a API do chatGPT com o objetivo de identificar a intenção da mensagem enviada pelo cliente. O prompt que eu utilizei foi:

Let’s create a reasoning service. This service runs as an AWS lambda, is triggered via an http request and its infrastructure is defined using sam-cli. The lambda function receives a message in string format, makes a request for ChatGPT api to identify message intent. The API should return one of the following intents: help with an order, question about a product or other. The program language to be used is Python.

A ideia não era simular uma pessoa programadora interagindo com a ferramenta, mas acredito que fui bastante técnica. Vamos ver o código gerado:

def detect_intent(message: str) -> str:
    """Call the ChatGPT API to classify a message."""
    if openai is None:
        raise RuntimeError("openai package is required")

    api_key = os.getenv("OPENAI_API_KEY")
    if not api_key:
        raise RuntimeError("OPENAI_API_KEY environment variable not set")

    openai.api_key = api_key
    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages=[
            {"role": "system", "content": _PROMPT},
            {"role": "user", "content": message},
        ],
        max_tokens=1,
        temperature=0,
    )
    intent = response.choices[0].message.content.strip()
    if intent not in INTENTS:
        intent = "other"
    return intent


def lambda_handler(event: Dict[str, Any], context: Any) -> Dict[str, str]:
    """AWS Lambda entry point."""
    message = event.get("message")
    if not isinstance(message, str):
        return {"intent": "other"}

    try:
        intent = detect_intent(message)
    except Exception:
        intent = "other"

    return {"intent": intent}

Mas por que isso não é o suficiente?

Embora funcional, o código gerado não contempla uma séria de boas práticas que eu consideraria essenciais para um código de produção. Exemplo:

  • Context propagation: O código não lida com context propagation, algo fundamental em chamadas HTTP encadeadas. Tanto o cliente quanto o Lambda e até a própria API do ChatGPT têm timeouts. Sem propagação de contexto não é possível encerrar a chamada da API de forma segura se o cliente já tiver desistido.
  • Gerenciamento da API key: o código simplesmente assumiu que a api-key estaria disponível em variável de ambiente. O ideal é utilizar um cofre de senhas como o AWS Secret Manager para evitar a exposição da chave. O Codex não perguntou sobre isso e nem sugeriu mesmo o serviço sendo um lambda e sendo tão fácil conectar com o próprio serviço da AWS.
  • Logs de erro: Não há log de erros que nos permitiria fazer a investigação de problemas. Um try/except sem log é sinônimo de caos quando algo dá errado em produção.
  • Tratamento de erros com códigos HTTP apropriados: O retorno do lambda não diferencia tipos de erros. Em APIs, precisamos retornar status como 400, 404, 500 e etc para que o cliente possa interpretar o que aconteceu.
  • Testes: nem preciso dizer que não escreveu nenhum teste. 🫠

Fui iterando com o Codex, refinando o prompt e explicitando cada um destes pontos acima e outros mais. No final, eu consegui algo mais próximo do que eu consideraria colocar em produção. Mas, sinceramente, talvez tivesse sido mais rápido escrever o código eu mesma.

Ah, então você está dizendo que estas ferramentas não servem para nada? Que só pessoas humanas são capazes de codificar e etc?

Não. Como qualquer ferramenta, há a curva de aprendizado. Precisei entender o que eu precisava ou não especificar, qual o nível de detalhamento necessário, quais boas práticas não são óbvias para a ferramenta.

Já ouvi pessoas programadoras compartilhando que conseguiram construir jogos web simples com o Codex em 30 minutos. Talvez seja possível. Mas eu tenho dúvidas se eu conseguiria fazer algo pela primeira vez (não tenho expertise em front-end) numa ferramenta nova em apenas 30minutos.

Mas imagine o cenário onde a empresa tem esqueletos de lambdas bem definidos: para chamadas de API Gateway, consumo fila SQS, eventos do EventBridge… com padrões claros de logs e tratamentos de erros. Neste contexto, é possível treinar o Codex com os padrões e treinar as pessoas engenheiras para escrever prompts eficazes. A produtividade tende a aumentar muito.

Mas veja, isso funciona num ambiente onde pessoas experientes, com conhecimento de boas práticas, usam o Codex como uma ferramenta para turbinar sua produtividade. Não é (ainda) o cenário onde o PM escreve uma feature e o Codex entrega pronto em produção.

Como diria o meme: “Torcedores, calma.” Esse dia pode até chegar. Mas, pelo menos na minha experiência, ainda não estamos lá.

Deixe um comentário

Este site utiliza o Akismet para reduzir spam. Fica a saber como são processados os dados dos comentários.

Site no WordPress.com.

EM CIMA ↑