Pular para o conteúdo principal

Tutorial da API Qwen 3.7 Max: construa um agente de produtividade autoconsciente

Aprenda a criar um agente de produtividade com o Qwen 3.7 Max via OpenRouter, que planeja, pesquisa, escreve e faz autoavaliação do próprio resultado em um app Streamlit.
Atualizado 17 de set. de 2026  · 15 min lido

Explorar com IA

ChatGPTClaudePerplexity

A maioria dos demos de IA ainda parece um chatbot: você faz uma pergunta, o modelo responde e a interação termina. Mas trabalho de produtividade de verdade raramente acontece em um passo só. Um assistente útil precisa destrinchar um pedido vago, reunir contexto, comparar opções, produzir um artefato utilizável e, depois, conferir seu próprio trabalho antes de entregar.

Qwen 3.7 Max é um modelo agentic da equipe Qwen, projetado para cargas de trabalho centradas em agentes, incluindo programação, tarefas de produtividade de escritório e execução de longo horizonte. É um modelo agent-first pensado não só para responder bem a um único prompt, mas para manter coerência em um fluxo de trabalho mais longo envolvendo planejamento, uso de ferramentas, escrita e autocorreção. 

Neste tutorial, vamos construir um agente de produtividade compacto usando Qwen 3.7 Max e Streamlit. O app recebe um pedido de negócio vago, como preparar uma análise competitiva de bancos de dados vetoriais, e transforma em um arquivo competitive_analysis.md caprichado.

Ao final deste tutorial, você vai entender como:

  • Construir um fluxo de agente com cinco etapas fixas

  • Usar enable_thinking=True e preserve_thinking=True

  • Adicionar pesquisa paralela leve

  • Escrever e ajustar um artefato em Markdown

  • Criar uma interface simples em Streamlit em torno do fluxo

O código completo está disponível no repositório do GitHub. 

O projeto é propositalmente enxuto, com a lógica principal dividida em agent.py para o app Streamlit e thinking_agent.py para o fluxo de backend.

Se você está começando com IA agentic, recomendo iniciar pela nossa trilha de habilidades AI Agent Fundamentals.

O que é o Qwen 3.7 Max?

Qwen 3.7 Max é o novo modelo carro-chefe da Alibaba, lançado em 20 de maio de 2026. Ele é feito para fluxos de trabalho agentic. Isso significa que, em vez de ser projetado só para chat de um turno, é otimizado para tarefas que exigem planejamento, uso de ferramentas, codificação, automação de escritório, raciocínio com contexto longo e execução em múltiplas etapas. 

A equipe Qwen o descreve como um modelo para a “era dos agentes”, com pontos fortes em agentes de código, assistentes de produtividade, workflows baseados em MCP e tarefas autônomas de longo horizonte.

O interessante neste modelo não é só o desempenho bruto em benchmarks, mas a capacidade de manter consistência em uma tarefa de múltiplos turnos, onde cada turno tem um propósito diferente, incluindo:

  • planejamento
  • sintetização de evidências
  • redação longa
  • autocrítica
  • revisão

No X, usuários observaram que o modelo está no mesmo nível do Opus 4.7 e do GPT 5.5 em tarefas de codificação de longo horizonte.

Publicação no X comparando Qwen 3.7 Max com Opus 4.7

Pontos fortes e desempenho em benchmarks do Qwen 3.7 Max

O Qwen 3.7 Max tem ótimo desempenho em benchmarks de agentes e raciocínio. Em avaliações de agentes de código, ele marca 

  • 69,7 no Terminal-Bench 2.0-Terminus
  • 60,6 no SWE-bench Pro
  • 78,3 no SWE-bench Multilingual
  • 47,2 no NL2Repo
  • 53,5 no SciCode

Em benchmarks de agente geral, ele alcança 

  • 60,8 no MCP-Mark
  • 76,4 no MCP-Atlas
  • 67,2 no CoWorkBench
  • 87,0 no SpreadSheetBench-v1

Qwen 3.7 max em benchmarks

Fonte: blog de desenvolvedores Qwen

Para você ter uma ideia do que isso significa: todos esses resultados ficam à frente das pontuações do DeepSeek V4 Pro; a maioria por pouco, mas para codificação de longo horizonte há uma diferença bem significativa entre os dois (47,2 vs 35,5 no NL2Repo).

Isso nos leva a um exemplo marcante do lançamento: a execução de otimização de kernel de longo horizonte do Qwen 3.7 Max. Segundo relatos, o Qwen 3.7 Max rodou por cerca de 35 horas, fez 1.158 chamadas de ferramenta, concluiu 432 avaliações de kernel e gerou um ganho médio geométrico de 10,0x em relação a uma implementação de referência em Triton. 

Isso é importante porque mostra o modelo sendo avaliado em melhoria iterativa baseada em ferramentas, e não apenas em perguntas estáticas de benchmark.

Resumindo, o Qwen 3.7 Max é uma ótima escolha para este demo porque foi feito para fluxos em que o modelo precisa raciocinar, usar ferramentas, preservar contexto e aprimorar um artefato em múltiplos turnos.

Construindo um agente de produtividade que preserva o raciocínio com Qwen 3.7 Max

Neste projeto, vamos demonstrar três ideias práticas:

  • Um pedido vago do usuário pode ser convertido em um workflow estruturado em múltiplas etapas.
  • Saídas de ferramentas podem ser reinseridas no processo de raciocínio em vez de serem despejadas em um prompt único e gigante.
  • Um modelo pode reler e melhorar sua própria saída via chain-of-thought prompting antes de entregar o artefato final ao usuário.

Visão geral do projeto

Vamos construir um aplicativo simples com uma caixa de entrada e um botão, onde o usuário digita um pedido vago como:

I need to prepare a competitive analysis of the top 3 vector databases
for a team presentation next week. I have no idea where to start.

Demo

Em seguida, o agente executa um fluxo de cinco turnos fixos:

User prompt
Turn 1: Plan the work
Parallel research for Pinecone, Weaviate, and Qdrant
Turn 2: Summarize research
Turn 3: Build comparison matrix
Turn 4: Write competitive_analysis.md
Turn 5: Self-review and patch the markdown file
Streamlit file preview

A interface mostra cada etapa como um cartão de progresso. Conforme o fluxo avança, os cartões passam de aguardando para concluído. No fim, o usuário pode inspecionar cada estágio: planejamento, pesquisa, síntese, rascunho, autoavaliação e visualização final do arquivo.

Isso deixa o fluxo de trabalho do agente visível, em vez de esconder tudo atrás de uma única resposta de chat.

O repositório é propositalmente pequeno. As principais partes são:

  • thinking_agent.py: contém a lógica do agente no backend, como chamadas de modelo, prompts, preservação do raciocínio, pesquisa, novas tentativas, escrita de arquivos e autoavaliação.

  • agent.py: traz a interface em Streamlit, incluindo layout da página, caixa de prompt, barra de progresso, cartões de etapas, seletor de resultados, visualização de Markdown e botão de download.

  • requirements.txt: lista as dependências de runtime necessárias para o demo

O backend gira em torno de uma classe ThinkingAgent que executa uma sequência fixa de cinco turnos e retorna registros estruturados de cada etapa. A UI não precisa saber como funcionam as chamadas de modelo, novas tentativas ou fanout de pesquisa. Ela só precisa renderizar cada turno quando ele chega.

O código completo deste tutorial está no GitHub.

Observação: usei o OpenRouter para acessar o Qwen 3.7 Max, mas você também pode usar o modelo pela plataforma oficial de API do Qwen

Passo 1: preparação do ambiente

Antes de construir o agente de produtividade com Qwen 3.7 Max, precisamos configurar um ambiente Python leve com Streamlit, o cliente compatível com OpenAI e httpx para buscas web simples.

Neste tutorial, vamos usar o OpenRouter como gateway de modelo, mas o backend está escrito usando o formato de API compatível com OpenAI. Isso significa que a mesma estrutura pode ser adaptada depois para o Alibaba Cloud Model Studio ou qualquer outro provedor compatível.

Neste passo, vamos:

  • Criar um ambiente virtual

  • Instalar as dependências necessárias

  • Definir a OPENROUTER_API_KEY ou QWEN_API_KEY

  • Confirmar que o app pode ser iniciado com Streamlit

Crie e ative um ambiente virtual:

python3 -m venv .venv
source .venv/bin/activate

Instale as dependências do projeto:

pip install -r requirements.txt

O arquivo requirements.txt é propositalmente enxuto:

httpx>=0.23.0
openai>=1.30.0
streamlit>=1.45.0

Usamos streamlit para construir a interface web interativa, openai para chamar o Qwen 3.7 Max via uma API compatível com OpenAI e httpx para buscar resultados de pesquisa ao vivo, de forma leve, na etapa de pesquisa.

Passo 2: configurar o cliente do Qwen 3.7 Max

O backend usa o SDK Python da OpenAI porque o OpenRouter expõe um endpoint compatível com OpenAI. O arquivo thinking_agent.py define alguns padrões:

from openai import OpenAI
DEFAULT_MODEL = "qwen/qwen3.7-max"
DEFAULT_BASE_URL = "https://openrouter.ai/api/v1"
DEFAULT_REFERER = "https://qwen.ai"
DEFAULT_TITLE = "Qwen3.7-Max Productivity Agent"

Depois criamos um cliente:

def build_client(
   api_key: str | None = None,
   base_url: str | None = None,
   referer: str = DEFAULT_REFERER,
   title: str = DEFAULT_TITLE,
) -> OpenAI:
   return OpenAI(
       base_url=base_url or DEFAULT_BASE_URL,
       api_key=api_key,
       default_headers={
           "HTTP-Referer": referer,
           "X-Title": title,
       },
   )

A função build_client() centraliza toda a configuração específica do provedor. O restante do app não precisa saber se o pedido está passando pelo OpenRouter, Alibaba Cloud Model Studio ou outro endpoint compatível.

Com o cliente configurado, o backend pode chamar o Qwen 3.7 Max usando o formato padrão de chat completions.

Agora, vamos construir o fluxo central do ThinkingAgent.

Passo 3: fluxo do agente em cinco turnos

Com o cliente do modelo configurado, podemos definir o fluxo central do backend. Em vez de pedir ao Qwen 3.7 Max para gerar um relatório completo de uma vez, dividimos a tarefa em cinco estágios controlados.

  • Planejamento: transforma o prompt vago em um plano de tarefas estruturado.

  • Pesquisa: coleta e resume evidências de trechos externos.

  • Síntese: constrói uma matriz de comparação a partir da pesquisa.

  • Rascunho: escreve o primeiro relatório competitive_analysis.md.

  • Autoavaliação: revisa e ajusta o relatório antes de devolver o arquivo final.

class ThinkingAgent:
   def run(
       self,
       goal: str,
       preserve_thinking: bool = True,
       data_mode: str = "live",
       on_turn: Callable[[TurnRecord], None] | None = None,
   ) -> ThinkingRunResult:
       history = [{"role": "system", "content": SYSTEM_PROMPT}]
       turns = []
       backend = self._build_search_backend(data_mode)
       turn1 = self._run_turn(
           history=history,
           turn_index=1,
           phase="planning",
           user_prompt=_planning_prompt(goal),
           preserve_thinking=preserve_thinking,
       )
       search_results = self._run_research(backend)
       turn2 = self._run_turn(
           history=history,
           turn_index=2,
           phase="research",
           user_prompt=_research_prompt(goal, search_results),
           preserve_thinking=preserve_thinking,
       )


       turn3 = self._run_turn(
           history=history,
           turn_index=3,
           phase="synthesis",
           user_prompt=_synthesis_prompt(),
           preserve_thinking=preserve_thinking,
       )
       turn4 = self._run_turn(
           history=history,
           turn_index=4,
           phase="draft",
           user_prompt=_draft_prompt(goal),
           preserve_thinking=preserve_thinking,
       )
       turn5 = self._run_turn(
           history=history,
           turn_index=5,
           phase="self_review",
           user_prompt=_self_review_prompt(draft_markdown),
           preserve_thinking=preserve_thinking,
       )

O método run() é o loop principal de orquestração. Ele começa com um system prompt, cria um histórico de conversa, constrói um backend de pesquisa e depois executa os cinco turnos, um a um.

Cada chamada a _run_turn() tem uma fase específica. Isso facilita depurar o fluxo porque cada chamada do modelo tem uma responsabilidade clara. O turno de planejamento planeja. O de pesquisa interpreta trechos externos. O de síntese cria estrutura. O de rascunho escreve. O de autoavaliação melhora o resultado.

A etapa de pesquisa fica entre o Turno 1 e o Turno 2 porque o modelo primeiro precisa entender a tarefa antes que informações externas sejam incorporadas ao fluxo.

No próximo passo, vamos adicionar a lógica específica do Qwen para preservar o raciocínio e ajudar o modelo a manter continuidade entre os turnos.

Passo 4: preservar o raciocínio entre turnos

O principal motivo para usarmos o Qwen 3.7 Max neste demo é o suporte a fluxos que preservam o raciocínio. O agente não trata cada chamada ao modelo como um prompt isolado. Em vez disso, ele pode preservar o raciocínio de turnos anteriores e passar esse contexto adiante.

Neste passo, vamos:

  • Ativar o raciocínio do modelo.
  • Preservar o raciocínio entre turnos.
  • Anexar as saídas do assistente de volta ao histórico compartilhado.
response = self.client.chat.completions.create(
   model=self.config.model,
   messages=request_messages,
   extra_body={
       "enable_thinking": True,
       "preserve_thinking": preserve_thinking,
   },
)

A flag enable_thinking=True permite que o Qwen 3.7 Max produza conteúdo de raciocínio durante a resposta. Já a flag preserve_thinking controla se esse conteúdo de raciocínio deve ser mantido para turnos posteriores.

Depois que o modelo responde, o backend extrai tanto a resposta visível quanto o conteúdo de raciocínio:

message = response.choices[0].message
assistant_content = _normalize_text(getattr(message, "content", ""))
reasoning_content = _extract_reasoning_content(message)
The visible answer is what the app can show to the user. The reasoning content is used internally to help the next turn stay aligned with the earlier plan.
Then the backend appends the assistant message back into the conversation history:
```python
assistant_message = {
   "role": "assistant",
   "content": assistant_content,
}
if preserve_thinking and reasoning_content:
   assistant_message["reasoning_content"] = reasoning_content
history.append(assistant_message)

Se o turno de planejamento decidir que o relatório final deve comparar bancos de dados vetoriais por modelo de implantação, escalabilidade, experiência do desenvolvedor, busca híbrida e prontidão corporativa, os turnos seguintes podem continuar usando esses critérios. Sem isso, cada turno pode se desalinhar. A etapa de síntese pode escolher critérios diferentes do planejamento, ou a autoavaliação pode julgar o relatório por outro objetivo.

Em seguida, vamos adicionar a camada de pesquisa que dá ao agente contexto externo antes de ele escrever o relatório.

Passo 5: adicionar pesquisa paralela com fallback de dados

Antes de o modelo escrever uma análise competitiva, ele precisa de contexto externo. Neste demo, mantemos o escopo da pesquisa fixo comparando três bancos de dados vetoriais: Pinecone, Weaviate e Qdrant.

Neste passo, vamos:

  • Definir os bancos de dados-alvo.
  • Executar as chamadas de pesquisa em paralelo.
  • Recorrer a dados determinísticos de fixture se a busca ao vivo falhar.
DATABASES = ("Pinecone", "Weaviate", "Qdrant")

A lista de alvos é fixa propositalmente. Isso mantém o demo estável e mais fácil de explicar. Depois, você pode estender o projeto para o modelo escolher dinamicamente os alvos de comparação.

Em seguida, o backend dispara as pesquisas em paralelo:

from concurrent.futures import ThreadPoolExecutor, as_completed
with ThreadPoolExecutor(max_workers=3) as executor:
   future_map = {
       executor.submit(backend.search, database, query): database
       for database, query in queries.items()
   }
   for future in as_completed(future_map):
       database = future_map[future]
       results[database] = future.result()

O ThreadPoolExecutor inicia uma busca por banco de dados. Isso é mais rápido que executar as pesquisas sequencialmente, porque as pesquisas de Pinecone, Weaviate e Qdrant rodam em paralelo.

try:
   results[database] = future.result()
except Exception as exc:
   fallback = FixtureSearchBackend().search(database, queries[database])
   fallback.warning = (
       f"Live search failed for {database} ({exc}). "
       "Fallback demo research was used."
   )
   results[database] = fallback

Se a busca ao vivo funcionar, o agente usa trechos recentes. Se falhar, o app ainda conclui o fluxo usando snippets de pesquisa determinísticos embutidos. O princípio de design aqui é degradação graciosa. O agente não deve quebrar só porque uma dependência externa falhou.

No próximo passo, vamos enviar esses resultados de pesquisa ao Qwen 3.7 Max para ele sintetizar uma matriz de comparação.

Passo 6: gerar a síntese e a matriz de comparação

Com os trechos de pesquisa em mãos, o próximo trabalho é a síntese. Esta etapa transforma informações dispersas em uma comparação estruturada que dá suporte ao relatório final.

Neste passo, vamos:

  • Enviar o contexto da pesquisa de volta ao Qwen 3.7 Max.
  • Pedir ao modelo que crie uma comparação estruturada.
  • Depois renderizar essa saída na interface do Streamlit.
turn3 = self._run_turn(
   history=history,
   turn_index=3,
   phase="synthesis",
   user_prompt=_synthesis_prompt(),
   preserve_thinking=preserve_thinking,
)

Quando este código roda, o histórico da conversa já contém o pedido original do usuário, a saída do planejamento, os resumos de pesquisa e, opcionalmente, o raciocínio preservado dos turnos anteriores.

Isso significa que o prompt de síntese não precisa repetir toda a tarefa. Ele pode focar em um trabalho: converter a pesquisa em uma matriz de comparação pronta para decisão.

Uma boa síntese deve comparar as opções em dimensões como:

  • modelo de implantação
  • escalabilidade
  • experiência do desenvolvedor
  • suporte a busca híbrida
  • prontidão corporativa
  • melhor caso de uso

Depois, vamos usar essa estrutura sintetizada para escrever o primeiro relatório em Markdown.

Passo 7: escrever o relatório em Markdown

Após planejamento, pesquisa e síntese, o agente tem contexto suficiente para escrever o primeiro entregável completo. Neste demo, o entregável é um arquivo Markdown chamado competitive_analysis.md.

Neste passo, vamos:

  • Pedir ao Qwen 3.7 Max para escrever o primeiro rascunho do relatório.
  • Remover cercas de código Markdown desnecessárias.
  • Salvar o rascunho em disco.
  • Registrar a ação de escrita como um evento de ferramenta.
turn4 = self._run_turn(
   history=history,
   turn_index=4,
   phase="draft",
   user_prompt=_draft_prompt(goal),
   preserve_thinking=preserve_thinking,
)

O turno de rascunho usa todo o contexto anterior, incluindo o objetivo original do usuário, o plano, a pesquisa e a matriz de síntese.

A resposta do modelo é então limpa e gravada em disco:

draft_markdown = _strip_markdown_fences(turn4.assistant_content)
report_path = run_output_dir / "competitive_analysis.md"
report_path.write_text(draft_markdown)

O helper _strip_markdown_fences() é útil porque modelos costumam envolver saídas em Markdown com cercas de três crases. Isso é ok em chat, mas não é o ideal ao escrever direto em um arquivo .md.

O backend também registra a ação de escrita:

turn4.tool_events.append(
   ToolEvent(
       name="write_file",
       status="completed",
       input_payload={"path": str(report_path)},
       output_payload={
           "description": "Initial draft written to disk.",
       },
   )
)

Esse evento de ferramenta ajuda a UI a mostrar que o backend criou um arquivo real, não apenas mais uma resposta de texto. Neste ponto, o app já tem um relatório utilizável. Mas adicionamos mais um turno de modelo para melhorar a qualidade antes de exibir o artefato final.

No próximo passo, vamos pedir ao Qwen 3.7 Max para revisar e ajustar o próprio rascunho.

Passo 8: autoavaliação e ajuste do relatório

O último turno do modelo é uma etapa de autoavaliação. Em vez de entregar imediatamente o primeiro rascunho, o agente relê o relatório, confere com o objetivo original e escreve uma versão aprimorada.

Neste passo, vamos:

  • Enviar o Markdown do rascunho de volta ao modelo.
  • Pedir ao modelo para identificar pontos fracos.
  • Gerar uma versão revisada.
  • Sobrescrever o relatório com a versão final melhorada.
turn5 = self._run_turn(
   history=history,
   turn_index=5,
   phase="self_review",
   user_prompt=_self_review_prompt(draft_markdown),
   preserve_thinking=preserve_thinking,
)

O prompt de autoavaliação pede ao modelo para checar questões práticas, como se a recomendação está clara, se os critérios de comparação são consistentes e se o relatório é útil para uma apresentação em time.

A saída revisada é gravada de volta no mesmo arquivo:

final_markdown = _strip_markdown_fences(turn5.assistant_content)
report_path.write_text(final_markdown)

O agente também pode registrar o evento final de escrita:

turn5.tool_events.append(
   ToolEvent(
       name="write_file",
       status="completed",
       input_payload={"path": str(report_path)},
       output_payload={
           "description": "Self-reviewed final report written to disk.",
       },
   )
)

Essa etapa transforma o app de um gerador simples em um pequeno fluxo editorial. O que o usuário vê não é o primeiro rascunho; é a versão revisada e ajustada.

Agora, vamos conectar esse fluxo de backend ao app em Streamlit.

Passo 9: construir a interface de progresso no Streamlit

Agora saímos da lógica de backend e vamos para a interface do usuário. O app em Streamlit deve permitir que o usuário digite um prompt, rode o fluxo e acompanhe cada etapa sendo concluída.

Observação: este código fica no arquivo agent.py porque controla o que o usuário vê e clica.

Neste passo, vamos:

  • Configurar a página do Streamlit.

  • Criar a entrada de prompt.

  • Adicionar um botão de execução.

  • Chamar a função ThinkingAgent.run().

  • Atualizar a UI conforme os turnos forem concluindo.

def render_streamlit_app() -> None:
   st.set_page_config(
       page_title="Qwen3.7-Max Demo Agent",
       page_icon=":material/psychology:",
       layout="wide",
       initial_sidebar_state="collapsed",
   )

O app usa layout amplo porque a UI inclui cartões de etapa, indicadores de progresso e painéis de resultados.

A área de input é simples:

goal = st.text_area(
   "Prompt",
   value=DEFAULT_GOAL,
   height=120,
   label_visibility="collapsed",
)

run_clicked = st.button("Run Demo", use_container_width=True)

O usuário só precisa informar a tarefa. O app não pede para configurar temperatura, modo de busca, ID do modelo ou ajustes de raciocínio. Esses detalhes ficam no backend.

Quando o usuário clica no botão, o agent.py cria o agente de backend e o executa:

agent = ThinkingAgent(config=config)

result = agent.run(
   goal=goal,
   preserve_thinking=True,
   data_mode="live",
   on_turn=on_turn,
)

É aqui que os dois arquivos se encontram. O agent.py aciona o fluxo, mas o thinking_agent.py é dono do comportamento do agente. O callback da UI atualiza a página a cada turno:

def on_turn(turn: TurnRecord) -> None:
   partial_turns.append(turn)

   progress_placeholder.progress(
       len(partial_turns) / len(phase_order),
       text=f"Completed {_phase_label(turn.phase)}",
   )

   with steps_placeholder.container():
       _render_step_cards(partial_turns, result_ready=False)

O callback recebe um TurnRecord concluído e atualiza a barra de progresso e os cartões de etapa. Durante a execução, os cartões funcionam como indicadores de status. Após a conclusão, eles viram visualizações clicáveis de resultados.

Agora, vamos renderizar o relatório final em Markdown e disponibilizá-lo para download.

Passo 10: visualizar e baixar o relatório final

Quando o backend termina, a UI precisa exibir o relatório final. O backend já criou o arquivo Markdown, então o agent.py só precisa lê-lo, renderizá-lo e expor um botão de download.

Neste passo, vamos:

  • Checar se o arquivo do relatório existe.
  • Ler o conteúdo final em Markdown.
  • Mostrar um botão de download.
  • Renderizar o Markdown no app Streamlit
def _render_file_preview(report_path: str) -> None:
   path = Path(report_path)

   if not path.exists():
       st.info("No file was written yet.")
       return
   content = path.read_text()
   st.caption(f"Created file: {path.name}")
   st.download_button(
       "Download competitive_analysis.md",
       data=content,
       file_name=path.name,
       use_container_width=True,
   )
   st.markdown(content)

A função começa verificando se o arquivo existe. Isso evita que o app quebre caso o backend tenha falhado antes de escrever o relatório. Depois, lê o conteúdo em Markdown e cria um botão de download. Por fim, renderiza o Markdown diretamente na página do Streamlit.

Há uma separação limpa de responsabilidades onde:

  • thinking_agent.py escreve o relatório

  • agent.py pré-visualiza e baixa o relatório

No próximo passo, vamos adicionar tratamento básico de erros para o demo se comportar melhor quando rotas do provedor falharem ou acontecerem limites de taxa.

Passo 11: tratamento de erros e rate limits

Provedores de modelo podem dar timeout, retornar falhas temporárias ou impor limites de taxa. Se expusermos esses erros brutos diretamente aos usuários, o app passa impressão de inacabado.

Este passo é dividido entre os dois arquivos. A lógica de novas tentativas fica em thinking_agent.py porque faz parte da chamada de modelo no backend. A mensagem de erro fica em agent.py porque controla o que o usuário vê.

Neste passo, vamos:

  • Repetir falhas temporárias do provedor no backend.
  • Detectar erros do tipo rate limit.
  • Exibir uma mensagem mais amigável na UI do Streamlit
delays = (1.0, 2.0)

for attempt_index in range(len(delays) + 1):
   try:
       return self.client.chat.completions.create(...)
   except Exception as exc:
       if not _is_retryable_provider_error(exc):
           raise

       if attempt_index >= len(delays):
           raise

       time.sleep(delays[attempt_index])

O backend tenta a chamada ao modelo, captura falhas recuperáveis, espera um pouco e tenta de novo. Atrasos curtos bastam para suavizar instabilidades temporárias do provedor sem fazer o usuário esperar demais.

def _friendly_rate_limit_message(exc: Any) -> str:
   return (
       "Qwen 3.7 Max is temporarily rate-limited upstream. "
       "Please wait 30 to 60 seconds and try again."
   )

Isso mantém JSON bruto do provedor ou stack traces fora da UI. O usuário recebe uma explicação clara e um próximo passo prático.

Com este passo final, já podemos rodar o app completo e testar o fluxo ponta a ponta.

Passo 12: rodar o demo

Agora que o fluxo de backend e a interface em Streamlit estão conectados, podemos executar o app completo.

Neste passo, vamos:

  • Iniciar o app em Streamlit.
  • Inserir o prompt padrão de produtividade.
  • Executar o fluxo em cinco etapas.
  • Pré-visualizar e baixar o relatório final em Markdown

Inicie o app:

streamlit run agent.py

Use o prompt padrão:

I need to prepare a competitive analysis of the top 3 vector databases
for a team presentation next week. I have no idea where to start.

Ao clicar em Run Demo, o app percorre todo o fluxo:

  • Planejamento: cria um plano estruturado.

  • Pesquisa: coleta trechos sobre Pinecone, Weaviate e Qdrant.

  • Síntese: monta uma matriz de comparação.

  • Rascunho: escreve o primeiro relatório em Markdown.

  • Autoavaliação: ajusta o relatório.

  • Pré-visualização: mostra o arquivo final competitive_analysis.md.

O relatório final é salvo em:

output/showcase_runs/<timestamp>/with_preserve/competitive_analysis.md

No fim, você deve ver a pré-visualização do relatório e um botão de download na interface do Streamlit.

Conclusão

Neste tutorial, construímos um agente de produtividade compacto com Qwen 3.7 Max que executa um fluxo fixo e interpretável: do planejamento, pesquisa e síntese à redação e autoavaliação. No caminho, mostramos por que preservar o raciocínio entre turnos pode ser útil para tarefas agentic de longo fôlego.

A versão atual usa apenas Streamlit, chamadas de modelo compatíveis com OpenAI, uma camada leve de pesquisa e saída em Markdown. Isso torna fácil estudar, modificar e reutilizar nos seus próprios experimentos.

Há várias extensões naturais a partir daqui:

  • Deixar o modelo escolher os alvos de comparação em vez de usar uma lista fixa

  • adicionar execuções lado a lado “com preserve_thinking” vs “sem preserve_thinking

  • Expor uso de tokens e estimativas de custo na UI

  • gerar um esboço de slides ou gráfico junto com o relatório em Markdown

  • Substituir scraping do DuckDuckGo por uma API de busca mais robusta

Se você quiser ir além de um fluxo fixo e aprender a construir aplicações de IA para produção — do prompt engineering ao RAG e sistemas agentic — nossa trilha de habilidades AI Engineering with LangChain é um ótimo próximo passo.

Perguntas frequentes do tutorial da API Qwen 3.7 Max

Quando devo usar preserve_thinking=True com o Qwen 3.7 Max?

preserve_thinking=True ajuda os turnos seguintes a permanecerem alinhados com decisões anteriores em fluxos de múltiplos turnos. No nosso exemplo, se o turno de planejamento escolhe critérios específicos de comparação, os turnos de síntese e autoavaliação podem continuar usando o mesmo raciocínio em vez de se desviar.

O Qwen 3.7 Max é apenas para agentes de código?

Não. Codificação é um dos seus grandes pontos fortes, mas o modelo também é indicado para agentes de produtividade, automação de escritório, workflows baseados em MCP, tarefas multilíngues, raciocínio com contexto longo e uso de ferramentas de longo horizonte.

O app demo usa busca real na web?

Sim, o caminho padrão atual tenta fazer scraping ao vivo via DuckDuckGo. Se isso falhar, recorre a uma pesquisa de fixture embutida.

O modelo cria subagentes no nosso app demo?

Não. O app usa uma sessão única de modelo. A parte “paralela” acontece na camada de pesquisa, onde o backend lança três buscas web simultâneas e alimenta os resultados de volta na mesma sessão do modelo.

Por que separamos agent.py e thinking_agent.py?

agent.py mantém a UI do Streamlit limpa. thinking_agent.py concentra o fluxo de backend, construção de prompts, novas tentativas e lógica de pesquisa para que o comportamento do agente possa ser testado de forma independente da interface.


Aashi Dutt's photo
Author
Aashi Dutt
LinkedIn
Twitter

Sou Especialista Google Developers em ML (Gen AI), tricampeã no Kaggle e Embaixadora Women Techmakers, com mais de três anos de experiência na área de tecnologia. Cofundei uma startup de saúde em 2020 e atualmente faço um mestrado em ciência da computação na Georgia Tech, com foco em aprendizado de máquina.

Tópicos
Agentes de IA
Inteligência Artificial

Aprenda IA agentic com a DataCamp!

Programa

Fundamentos de agentes de IA

6 h
Descubra como os agentes de IA podem transformar sua forma de trabalhar e gerar valor para sua organização!
Ver detalhesRight Arrow
Iniciar Curso
Ver maisRight Arrow
Relacionado

Tutorial

Criando agentes LangChain para automatizar tarefas em Python

Um tutorial abrangente sobre a criação de agentes LangChain com várias ferramentas para automatizar tarefas em Python usando LLMs e modelos de bate-papo usando OpenAI.

Tutorial

Tutorial da API de assistentes da OpenAI

Uma visão geral abrangente da API Assistants com nosso artigo, que oferece uma análise aprofundada de seus recursos, usos no setor, orientação de configuração e práticas recomendadas para maximizar seu potencial em vários aplicativos de negócios.
Zoumana Keita 's photo

Zoumana Keita

14 min

Tutorial

Como usar o Midjourney: Um guia abrangente para a criação de obras de arte geradas por IA

Descubra o poder do Midjourney, uma ferramenta de IA generativa para criar obras de arte impressionantes. Saiba como começar, escrever prompts eficazes e otimizar seu uso com nosso guia passo a passo.
Kurtis Pykes 's photo

Kurtis Pykes

12 min

Tutorial

Como criar aplicativos LLM com o tutorial LangChain

Explore o potencial inexplorado dos modelos de linguagem grandes com o LangChain, uma estrutura Python de código aberto para criar aplicativos avançados de IA.
Moez Ali's photo

Moez Ali

12 min

Tutorial

Introdução ao Q-learning: um tutorial para iniciantes

Aprenda o algoritmo de aprendizado por reforço sem modelo mais popular com um tutorial em Python.
Abid Ali Awan's photo

Abid Ali Awan

11 min

Tutorial

Um guia para iniciantes na engenharia de prompts do ChatGPT

Descubra como fazer com que o ChatGPT forneça os resultados que você deseja, fornecendo a ele as entradas necessárias.
Matt Crabtree's photo

Matt Crabtree

6 min

Ver MaisVer Mais