AI engineering

Hermes Agent: an agent that remembers, learns skills and answers you on WhatsApp, 24/7.

What it is and how it works, its memory, how it creates skills, how it plugs into Telegram, WhatsApp and Signal, its guardrails, how to install it, which models it supports and how to leave it running on a Hostinger or AWS server.

O que éWhat it is

Hermes Agent é um agente de IA open-source (licença MIT) da Nous Research, que o descreve como "o agente que se melhora sozinho". Na prática é um programa que você instala, aponta para um modelo de linguagem (LLM) e conversa com ele pelo terminal ou pelo celular, via Telegram, WhatsApp, Signal e outros. Ele executa comandos, edita arquivos, pesquisa na web, agenda tarefas e, o que o distingue, guarda memória entre conversas e transforma o que aprendeu em skills reutilizáveis.Hermes Agent is an open-source AI agent (MIT license) from Nous Research, which describes it as "the self-improving agent". In practice it is a program you install, point at a large language model (LLM) and talk to from the terminal or from your phone, via Telegram, WhatsApp, Signal and others. It runs commands, edits files, searches the web, schedules tasks and, what sets it apart, keeps memory across conversations and turns what it learned into reusable skills.

Não confunda o agente com os modelos. "Hermes" também é uma família de modelos da Nous (Hermes 3, Hermes 4). O Hermes Agent é o programa em volta do modelo e funciona com qualquer LLM que você configurar (seção 6). A nota sobre harness de agentes explica o que é essa camada; aqui vemos um exemplo completo dela.Do not confuse the agent with the models. "Hermes" is also a family of Nous models (Hermes 3, Hermes 4). Hermes Agent is the program around the model and works with any LLM you configure (section 6). The agent harness note explains what that layer is; here we see a complete example of it.
vocêyou Terminal / appTerminal / app TelegramTelegram WhatsApp, Signal...WhatsApp, Signal... GatewayGateway um processo,one process, vários appsmany apps AIAgent Loop do agenteAgent loop MemóriaMemory SkillsSkills CronCron SubagentesSubagents LLMLLMnuvem ou localcloud or local FerramentasToolsterminal, web, MCPterminal, web, MCP tudo em ~/.hermes (no Docker: /opt/data)all in ~/.hermes (in Docker: /opt/data) config.yaml · .env · SOUL.md · memories/ · skills/ · state.db · cron/ a mesma memória em todos os canaisthe same memory on every channel
Os apps de mensagem falam com o gateway; o gateway chama o mesmo agente, com a mesma memória e as mesmas skills, que usa o LLM e as ferramentas.The messaging apps talk to the gateway; the gateway calls the same agent, with the same memory and skills, which uses the LLM and the tools.
Nota pessoal, sobre as fontes: esta nota vem da documentação oficial (hermes-agent.nousresearch.com) e do README no GitHub, lidos em 27/10/2026, e de um tutorial da Hostinger. Eu baixei a imagem Docker oficial (4,31 GB) e vi que a primeira partida cria a estrutura de ~/.hermes (memories/, skills/, sessions/, cron/, pairing/, platforms/, SOUL.md, config.yaml), mas não rodei o agente com um modelo de verdade; os comandos são os da documentação, não saídas que eu tenha visto. O projeto muda rápido; confira a página da versão que instalar.Personal note, on sources: this note comes from the official documentation (hermes-agent.nousresearch.com) and the GitHub README, read on 2026-10-27, and from a Hostinger tutorial. I pulled the official Docker image (4.31 GB) and saw that the first start creates the ~/.hermes structure (memories/, skills/, sessions/, cron/, pairing/, platforms/, SOUL.md, config.yaml), but I did not run the agent against a real model; the commands are the documentation's, not outputs I have seen. The project moves fast; check the page for the version you install.
Fontes · verificadas em 2026-10-27Sources · checked on 2026-10-27

1. Como funciona por dentro1. How it works inside

Todas as portas de entrada (o terminal cli.py, o gateway gateway/run.py, a integração com editores, a API) acabam na mesma classe, a AIAgent. O coração dela é um loop de agente, o mesmo padrão de qualquer agente com ferramentas:All entry points (the cli.py terminal, the gateway/run.py gateway, the editor integration, the API) end up in the same class, AIAgent. Its heart is an agent loop, the same pattern as any agent with tools:

Sua mensagemYour messagechat ou terminalchat or terminal Monta o promptBuilds the promptSOUL + memória + skillsSOUL + memory + skills Chama o LLMCalls the LLMdecide o próximo passodecides the next step Executa aRuns theferramentatool RespostaAnswere sessão salvaand session saved resultado volta ao LLM; repete até terminarresult goes back to the LLM; repeats until done pede aprovação se perigosoasks approval if dangerous
Se a resposta do LLM tem uma chamada de ferramenta, o agente a executa e devolve o resultado; quando não tem, a resposta é entregue e a sessão é gravada no SQLite.If the LLM's reply contains a tool call, the agent runs it and returns the result; when it does not, the answer is delivered and the session is written to SQLite.
PeçaPieceO que fazWhat it does
Prompt do sistemaSystem promptMontado em camadas: identidade (SOUL.md), guia das ferramentas, memória, lista de skills, arquivos de contexto (AGENTS.md), data e hora, dicas da plataforma e, por último, a personalidade escolhida. As partes estáveis vêm primeiro para aproveitar o cache de prompt do provedor.Built in layers: identity (SOUL.md), tool guidance, memory, skill list, context files (AGENTS.md), date and time, platform hints and, last, the chosen personality. Stable parts come first to take advantage of the provider's prompt cache.
FerramentasToolsMais de 70, em cerca de 28 grupos (toolsets): terminal, arquivos, web, navegador, visão, geração de imagem, voz, MCP, agendamento. Cada uma se registra sozinha.Over 70, in about 28 groups (toolsets): terminal, files, web, browser, vision, image generation, voice, MCP, scheduling. Each registers itself.
Compressão de contextoContext compressionQuando a conversa passa de um limite, um modelo auxiliar resume os turnos do meio. O modelo de resumo precisa ter janela de contexto pelo menos igual à do principal, senão os turnos são descartados sem resumo.When the conversation passes a threshold, an auxiliary model summarizes the middle turns. The summary model needs a context window at least as large as the main one, or the turns are dropped without a summary.
SubagentesSubagentsInstâncias isoladas, com conversa e terminal próprios, para trabalho em paralelo.Isolated instances, with their own conversation and terminal, for parallel work.
Agendador (cron)Scheduler (cron)Tarefas em linguagem natural ("todo dia às 8h me mande um resumo"). Roda dentro do gateway, que confere a cada 60 s, e entrega o resultado no app que você escolher.Tasks in natural language ("every day at 8am send me a summary"). Runs inside the gateway, which checks every 60 s, and delivers the result to the app you choose.
Backends de terminalTerminal backendsOnde os comandos rodam: local, docker, ssh, Modal, Daytona, Vercel Sandbox (e Singularity por plugin). Importa muito para a segurança (seção 5).Where commands run: local, docker, ssh, Modal, Daytona, Vercel Sandbox (and Singularity by plugin). It matters a lot for security (section 5).

SOUL.md e AGENTS.mdSOUL.md and AGENTS.md

São dois arquivos de texto que você escreve. O ~/.hermes/SOUL.md é a identidade do agente (tom, jeito de responder) e vale para tudo. O AGENTS.md traz as instruções de um projeto (comandos, convenções). Regra da documentação: o que deve seguir você a todo lugar vai no SOUL.md; o que pertence a um projeto, no AGENTS.md. Os dois são varridos em busca de injeção de prompt antes de entrar no prompt (seção 5).They are two text files you write. ~/.hermes/SOUL.md is the agent's identity (tone, way of answering) and applies everywhere. AGENTS.md carries the instructions of one project (commands, conventions). The documentation's rule: what should follow you everywhere goes in SOUL.md; what belongs to a project, in AGENTS.md. Both are scanned for prompt injection before entering the prompt (section 5).

2. Memória2. Memory

Um LLM não lembra de nada entre chamadas; tudo o que ele "sabe" numa conversa está no prompt. A memória do Hermes é um conjunto de arquivos e um banco que ele escreve e relê, em três camadas:An LLM remembers nothing between calls; everything it "knows" in a conversation is in the prompt. Hermes's memory is a set of files and a database that it writes and rereads, in three layers:

1. Memória curada1. Curated memory MEMORY.mdnotas do agente · 2.200 car.agent notes · 2,200 chars USER.mdperfil de você · 1.375 car.profile of you · 1,375 chars sempre dentro do promptalways inside the prompt 2. Histórico pesquisável2. Searchable history ~/.hermes/state.dbSQLite + FTS5 todas as sessões (terminalevery session (terminal e apps); o agente buscaand apps); the agent searches só quando precisaonly when it needs to 3. Provedores externos3. External providers Honcho · Mem0 · HindsightSupermemory · RetainDB ... plugins opcionais, ao ladooptional plugins, alongside das camadas 1 e 2layers 1 and 2 a camada 1 é minúscula de propósito: só cabe o que vale a pena ver em toda conversalayer 1 is tiny on purpose: it only holds what is worth seeing in every conversation
Duas ideias diferentes: o que o agente sempre sabe (camada 1) e o que ele consegue consultar (camadas 2 e 3).Two different ideas: what the agent always knows (layer 1) and what it can look up (layers 2 and 3).

Camada 1: MEMORY.md e USER.mdLayer 1: MEMORY.md and USER.md

  • Ficam em ~/.hermes/memories/. O MEMORY.md guarda fatos do ambiente, convenções e lições (limite de 2.200 caracteres, uns 800 tokens); o USER.md guarda suas preferências e estilo (1.375 caracteres).They live in ~/.hermes/memories/. MEMORY.md holds environment facts, conventions and lessons (limit 2,200 characters, about 800 tokens); USER.md holds your preferences and style (1,375 characters).
  • O agente escreve com a ferramenta memory (ações add, patch e remove; não há "ler", porque o conteúdo já está no prompt). Quando estoura o limite, a ferramenta devolve erro e o agente precisa reorganizar: nada é apagado sozinho.The agent writes with the memory tool (actions add, patch and remove; there is no "read", because the content is already in the prompt). When the limit is exceeded the tool returns an error and the agent must reorganize: nothing is deleted by itself.
  • Instantâneo congelado: o conteúdo é carregado no prompt no começo da sessão. O que o agente escreve durante a sessão vai para o disco na hora, mas só aparece no prompt na próxima sessão. Isso mantém o prefixo do prompt estável e o cache do provedor funcionando.Frozen snapshot: the content is loaded into the prompt at session start. What the agent writes mid-session goes to disk immediately but only appears in the prompt in the next session. This keeps the prompt prefix stable and the provider's cache working.
  • Cada escrita é varrida em busca de padrões de injeção de prompt e exfiltração, e de caracteres Unicode invisíveis, que são bloqueados. Faz sentido: uma página web maliciosa não deve conseguir plantar uma "lembrança" que valha para sempre.Each write is scanned for prompt-injection and exfiltration patterns, and invisible Unicode characters, which are blocked. This makes sense: a malicious web page should not be able to plant a "memory" that lasts forever.
  • Para revisar antes de gravar, ligue memory.write_approval: true: as escritas ficam pendentes e você usa /memory pending, /memory approve e /memory reject.To review before saving, turn on memory.write_approval: true: writes stay pending and you use /memory pending, /memory approve and /memory reject.
# ~/.hermes/config.yaml (trecho da documentação)
memory:
  memory_enabled: true
  user_profile_enabled: true
  memory_char_limit: 2200
  user_char_limit: 1375
  write_approval: false      # true = você aprova cada escrita
skills:
  write_approval: false      # idem para skills (seção 3)

Camada 2: o histórico de sessõesLayer 2: session history

Toda conversa, do terminal ou de qualquer app, é gravada em ~/.hermes/state.db (SQLite) com busca de texto FTS5. Quando você pergunta "o que decidimos sobre o deploy semana passada?", o agente busca ali e recebe as mensagens originais, sem resumo no meio. Você também lista as sessões com hermes sessions list. Como é um banco e não o prompt, ele cresce sem custo de contexto.Every conversation, from the terminal or any app, is written to ~/.hermes/state.db (SQLite) with FTS5 full-text search. When you ask "what did we decide about the deploy last week?", the agent searches there and receives the original messages, with no summary in between. You can also list sessions with hermes sessions list. Because it is a database and not the prompt, it grows at no context cost.

Camada 3: provedores externosLayer 3: external providers

Plugins como Honcho (que monta um modelo de você ao longo do tempo), Mem0, Hindsight e Supermemory rodam ao lado das camadas 1 e 2, sem substituí-las. Configure com hermes memory setup e veja o estado com hermes memory status.Plugins such as Honcho (which builds a model of you over time), Mem0, Hindsight and Supermemory run alongside layers 1 and 2, without replacing them. Set up with hermes memory setup and check with hermes memory status.

Uma memória por casa. A memória é por perfil (hermes -p work usa ~/.hermes/profiles/work/). A documentação avisa para nunca apontar dois processos do agente para o mesmo diretório do Hermes: dois gateways gravando no mesmo state.db é pedir problema.One memory per home. Memory is per profile (hermes -p work uses ~/.hermes/profiles/work/). The documentation warns never to point two agent processes at the same Hermes directory: two gateways writing to the same state.db is asking for trouble.
Fontes · verificadas em 2026-10-27Sources · checked on 2026-10-27

3. Skills que ele mesmo cria3. Skills it creates itself

Uma skill é uma pasta com um arquivo SKILL.md (frontmatter YAML + instruções em Markdown) que ensina o agente a fazer uma tarefa. O formato segue o padrão aberto agentskills.io, o mesmo das Agent Skills da nota de harness. A diferença do Hermes é que ele escreve as próprias skills: o prompt do sistema pede que ele salve fluxos que valem repetir.A skill is a folder with a SKILL.md file (YAML frontmatter + Markdown instructions) that teaches the agent a task. The format follows the open agentskills.io standard, the same as the Agent Skills in the harness note. What is different in Hermes is that it writes its own skills: the system prompt asks it to save workflows worth repeating.

Tarefa difícilHard taskmuitos passosmany steps Dá certoWorksou você corrigeor you correct it skill_managecreate → SKILL.mdcreate → SKILL.md Próxima vezNext timecarrega a skillloads the skill patchcorrige em usofixes in use a skill melhora a cada usothe skill improves with each use
Os gatilhos listados na documentação: um fluxo de vários passos que vale repetir, um beco sem saída em que ele achou o caminho, ou uma correção sua.The triggers listed in the documentation: a multi-step workflow worth repeating, a dead end where it found the way, or a correction from you.
# ~/.hermes/skills/devops/deploy-site/SKILL.md  (exemplo, no formato da documentação)
---
name: deploy-site
description: Publica o site estático no servidor e confere se subiu
version: 1.0.0
platforms: [linux]
metadata:
  hermes:
    tags: [deploy]
    category: devops
    requires_toolsets: [terminal]
---
# Deploy do site
## Quando usar
Quando o usuário pedir para publicar ou atualizar o site.
## Procedimento
1. Rode os testes: `npm test`.
2. Faça o build e envie com `rsync`.
3. Confira com `curl -I` que a página responde 200.
## Armadilhas
- O build falha se a pasta `dist/` estiver suja: apague antes.
## Verificação
`curl -I https://meusite.com` deve devolver `HTTP/2 200`.
  • Ferramenta skill_manage: ações create, patch (correção pontual, a preferida), delete, write_file e remove_file para arquivos de apoio (references/, scripts/...).The skill_manage tool: actions create, patch (a targeted fix, the preferred one), delete, write_file and remove_file for support files (references/, scripts/...).
  • Divulgação progressiva para não gastar contexto: o prompt só leva a lista (nome e descrição, uns 3 mil tokens no total); o SKILL.md inteiro só é carregado quando a skill é usada, e os arquivos de referência só quando necessários. Você também as chama na mão com /nome-da-skill.Progressive disclosure so as not to spend context: the prompt only carries the list (name and description, about 3k tokens in total); the whole SKILL.md is loaded only when the skill is used, and reference files only when needed. You can also call them by hand with /skill-name.
  • Revisão humana: com skills.write_approval: true, as skills novas ficam em ~/.hermes/pending/skills/ até você aprovar (/skills pending, /skills diff <id>, /skills approve <id>). Eu recomendo ligar isto no começo: uma skill é código que roda com as suas permissões.Human review: with skills.write_approval: true, new skills sit in ~/.hermes/pending/skills/ until you approve (/skills pending, /skills diff <id>, /skills approve <id>). I recommend turning this on at first: a skill is instructions that run with your permissions.
  • Skills de terceiros vêm de um hub (hermes skills browse, search, install). Todo install passa por um scanner (exfiltração, injeção de prompt, comandos destrutivos, cadeia de suprimentos). Há níveis de confiança (builtin, official, trusted, community), e o --force nunca passa por cima de um veredito dangerous.Third-party skills come from a hub (hermes skills browse, search, install). Every install goes through a scanner (exfiltration, prompt injection, destructive commands, supply chain). There are trust levels (builtin, official, trusted, community), and --force never overrides a dangerous verdict.
Nota pessoal, não verificada nas fontes: o SKILL.md acima é um exemplo que eu escrevi seguindo o formato da documentação; não é uma skill que o Hermes gerou. A qualidade do que ele cria sozinho depende do modelo, e skills ruins se acumulam: revise de vez em quando a pasta ~/.hermes/skills/.Personal note, not verified in the sources: the SKILL.md above is an example I wrote following the documentation's format; it is not a skill Hermes generated. The quality of what it creates on its own depends on the model, and bad skills pile up: review the ~/.hermes/skills/ folder from time to time.
Fontes · verificadas em 2026-10-27Sources · checked on 2026-10-27

4. Telegram, WhatsApp, Signal e o resto4. Telegram, WhatsApp, Signal and the rest

O gateway é um processo em segundo plano que se conecta a todos os apps configurados. Cada app tem um adaptador que recebe as mensagens, e todas passam por uma sessão por conversa e chegam ao mesmo agente. Por isso a mesma memória e as mesmas skills valem no celular e no terminal. As plataformas da documentação:The gateway is a background process that connects to all configured apps. Each app has an adapter that receives messages, and all of them go through one session per conversation and reach the same agent. That is why the same memory and skills apply on the phone and in the terminal. The platforms in the documentation:

GrupoGroupPlataformasPlatforms
Chat e timesChat and teamsTelegram, Discord, Slack, Google Chat, Mattermost, Matrix, Microsoft Teams, Feishu/Lark, DingTalk, WeCom, LINE, QQ...
MensageirosMessengersWhatsApp (ponte Baileys ou Cloud API / Baileys bridge or Cloud API), Signal, SMS (Twilio), Email, SimpleX
AppleBlueBubbles, Photon (iMessage)
OutrosOtherHome Assistant (plugin), ntfy, IRC, Webhooks, API Server

A configuração é guiada: hermes gateway setup pergunta qual plataforma você quer e pede os dados. Os três apps que você citou:Setup is guided: hermes gateway setup asks which platform you want and requests the details. The three apps you mentioned:

Telegram

  1. No Telegram, abra o @BotFather, envie /newbot, escolha um nome e um usuário que termine em bot. Ele devolve o token (segredo: se vazar, /revoke).In Telegram, open @BotFather, send /newbot, choose a name and a username ending in bot. It returns the token (secret: if it leaks, /revoke).
  2. Descubra o seu ID numérico (não o @usuário) com o @userinfobot.Find your numeric ID (not the @username) with @userinfobot.
  3. Em ~/.hermes/.env coloque TELEGRAM_BOT_TOKEN e TELEGRAM_ALLOWED_USERS (seu ID). Sem a lista, o gateway nega todo mundo.In ~/.hermes/.env set TELEGRAM_BOT_TOKEN and TELEGRAM_ALLOWED_USERS (your ID). Without the list, the gateway denies everyone.
  4. Rode hermes gateway e mande uma mensagem ao bot. Use /sethome no chat para ele receber os resultados das tarefas agendadas.Run hermes gateway and message the bot. Use /sethome in the chat so it receives the scheduled tasks' results.

O Telegram é o melhor para um servidor: por padrão o gateway usa polling (ele pergunta ao Telegram se há mensagens), ou seja, só conexões de saída. Não precisa abrir porta nem ter domínio. O modo webhook (TELEGRAM_WEBHOOK_URL) existe para plataformas que acordam a máquina com tráfego de entrada.Telegram is the best fit for a server: by default the gateway uses polling (it asks Telegram whether there are messages), meaning outbound connections only. No need to open a port or own a domain. Webhook mode (TELEGRAM_WEBHOOK_URL) exists for platforms that wake the machine on inbound traffic.

WhatsApp

Há dois caminhos. A ponte Baileys (hermes whatsapp) emula uma sessão do WhatsApp Web: você escaneia um QR code em Configurações → Dispositivos conectados, não precisa de conta Meta nem de URL pública, mas tem risco de banimento, porque o WhatsApp não suporta bots de terceiros fora da API oficial. A Cloud API (oficial, da Meta) evita esse risco, mas exige conta Business e um webhook público.There are two paths. The Baileys bridge (hermes whatsapp) emulates a WhatsApp Web session: you scan a QR code in Settings → Linked Devices, need no Meta account or public URL, but it carries a ban risk, because WhatsApp does not support third-party bots outside the official API. The Cloud API (official, from Meta) avoids that risk, but requires a Business account and a public webhook.

# ~/.hermes/.env  (ponte Baileys)
WHATSAPP_ENABLED=true
WHATSAPP_MODE=bot                    # "bot" (número próprio do bot) ou "self-chat"
WHATSAPP_ALLOWED_USERS=5511999999999 # código do país, sem "+"
WHATSAPP_GROUP_POLICY=pairing        # grupos: pairing | allowlist | open
WHATSAPP_REQUIRE_MENTION=true        # em grupos, só responde a @menções
Cuidados da própria documentação: use um número dedicado, não o seu pessoal; não mande mensagens em massa nem para quem não falou com você primeiro; e proteja ~/.hermes/platforms/whatsapp/session como uma senha (chmod 700), porque ela guarda as credenciais da conta. Se vazar, desconecte o aparelho em Dispositivos conectados. Atualizações do protocolo do WhatsApp podem quebrar a ponte; atualize o Hermes e refaça o pareamento.Cautions from the documentation itself: use a dedicated number, not your personal one; do not send bulk messages or message people who did not write first; and protect ~/.hermes/platforms/whatsapp/session like a password (chmod 700), because it holds the account credentials. If it leaks, unlink the device under Linked Devices. WhatsApp protocol updates can break the bridge; update Hermes and re-pair.

Signal

O Signal depende de um programa separado, o signal-cli (precisa de Java 17+), que roda como serviço local e que o Hermes acessa por HTTP. Você vincula o signal-cli ao seu número como aparelho secundário e deixa o daemon rodando:Signal depends on a separate program, signal-cli (needs Java 17+), which runs as a local service that Hermes reaches over HTTP. You link signal-cli to your number as a secondary device and leave the daemon running:

signal-cli link -n "HermesAgent"                      # escaneie o QR em Signal > Aparelhos vinculados
signal-cli --account +5511999999999 daemon --http 127.0.0.1:8080

# ~/.hermes/.env
SIGNAL_HTTP_URL=http://127.0.0.1:8080
SIGNAL_ACCOUNT=+5511999999999
SIGNAL_ALLOWED_USERS=+5511999999999

Detalhes da documentação: mensagens passam de 8.000 caracteres são divididas em partes numeradas; só uma instância do signal-cli deve escutar cada número; e ~/.local/share/signal-cli/ guarda as credenciais da conta.Documentation details: messages over 8,000 characters are split into numbered parts; only one signal-cli instance should listen on each number; and ~/.local/share/signal-cli/ holds the account credentials.

Quem pode falar com o bot: pareamento de DMWho can talk to the bot: DM pairing

Um bot de chat é público por natureza: qualquer um que achar o nome pode mandar mensagem, e esse bot executa comandos. Por isso o gateway nega por padrão. Há duas formas de liberar alguém: uma lista (TELEGRAM_ALLOWED_USERS, WHATSAPP_ALLOWED_USERS, GATEWAY_ALLOWED_USERS...) ou o pareamento: um desconhecido manda mensagem, o bot responde com um código de 8 caracteres, e você, no servidor, aprova:A chat bot is public by nature: anyone who finds the name can message it, and this bot runs commands. So the gateway denies by default. There are two ways to let someone in: a list (TELEGRAM_ALLOWED_USERS, WHATSAPP_ALLOWED_USERS, GATEWAY_ALLOWED_USERS...) or pairing: a stranger messages, the bot replies with an 8-character code, and you, on the server, approve:

hermes pairing list
hermes pairing approve telegram XKGH5N7P
hermes pairing revoke telegram 123456789

Dá para separar administradores de usuários comuns por plataforma (allow_admin_from, user_allowed_commands), e o /whoami mostra o seu nível. Outras coisas úteis do gateway: se um adaptador falha várias vezes, um circuit breaker o pausa (retome com /platform resume <nome>); um watchdog encerra o processo se o loop travar, para o supervisor reiniciá-lo; e as respostas finais ficam num registro no state.db e são reenviadas após uma queda.You can split admins from regular users per platform (allow_admin_from, user_allowed_commands), and /whoami shows your tier. Other useful gateway behaviours: if an adapter fails repeatedly, a circuit breaker pauses it (resume with /platform resume <name>); a watchdog exits the process if the loop stalls, so the supervisor restarts it; and final replies are kept in a ledger in state.db and resent after a crash.

Fontes · verificadas em 2026-10-27Sources · checked on 2026-10-27

5. Guardrails5. Guardrails

Um agente que executa comandos a partir de mensagens de chat é, por definição, perigoso: um erro do modelo, um texto malicioso numa página que ele leu ou um desconhecido no bot podem virar um rm -rf. A documentação descreve oito camadas. As que mais importam:An agent that runs commands from chat messages is dangerous by definition: a model mistake, malicious text on a page it read or a stranger on the bot can become an rm -rf. The documentation describes eight layers. The ones that matter most:

1. Quem fala1. Who talksallowlist eallowlist andpareamento;pairing;padrão: negardefault: deny 2. O que lê2. What it readsvarre AGENTS.md,scans AGENTS.md,memória, skills;memory, skills;bloqueio SSRFSSRF blocking 3. O que executa3. What it runsaprovação deapproval ofcomandos;commands;lista negra fixafixed blocklist 4. O que escreve4. What it writes~/.ssh, ~/.aws,~/.ssh, ~/.aws,.env sempre.env alwaysbloqueadosblocked 5. Onde roda5. Where it runscontêiner semcontainer with noprivilégios;privileges;segredos filtradossecrets filtered as quatro primeiras são políticas (guarda-corpos); só a quinta é uma fronteira de verdade (sandbox)the first four are policies (guardrails); only the fifth is a real boundary (sandbox) a própria documentação diz: "é uma camada de política, não um sandbox"the documentation itself says: "this is a policy layer, not a sandbox"
A ordem de uma mensagem do celular até o efeito no servidor.The order of a message from the phone to the effect on the server.

Aprovação de comandosCommand approval

Em ~/.hermes/config.yaml, a chave approvals.mode tem três valores: smart (padrão: um modelo auxiliar avalia o risco; baixo risco passa, perigoso é negado, incerto vira pergunta para você), manual (sempre pergunta) e off (equivale ao modo --yolo). Comandos que disparam a aprovação incluem rm recursivo, chmod 777, DROP/TRUNCATE, curl | sh, kill -9, escritas em /etc/ e em ~/.ssh/. No chat você responde yes ou no; no terminal, once, session, always ou deny. Se você não responder em approvals.timeout (300 s por padrão), o pedido é negado.In ~/.hermes/config.yaml, the approvals.mode key has three values: smart (default: an auxiliary model rates the risk; low risk passes, dangerous is denied, uncertain becomes a question to you), manual (always asks) and off (same as --yolo). Commands that trigger approval include recursive rm, chmod 777, DROP/TRUNCATE, curl | sh, kill -9, writes to /etc/ and ~/.ssh/. In chat you answer yes or no; in the terminal, once, session, always or deny. If you do not answer within approvals.timeout (300 s by default), the request is denied.

# ~/.hermes/config.yaml
approvals:
  mode: manual            # para um servidor exposto, comece com "manual"
  timeout: 300
  cron_mode: deny         # tarefas agendadas sem ninguém para aprovar: negar
  deny:                   # regras suas, avaliadas antes de qualquer modo
    - "rm -rf *"
    - "*curl*|*sh*"

Dois detalhes importantes. Primeiro, há uma lista negra fixa (rm -rf /, fork bomb, mkfs no disco raiz, dd sobre disco) que vale até no modo --yolo. Segundo, tarefas sem ninguém por perto (agendadas, webhooks) usam cron_mode, unattended_mode etc., todos deny por padrão: um comando perigoso numa tarefa das 3h da manhã é negado, não executado.Two important details. First, there is a fixed blocklist (rm -rf /, fork bomb, mkfs on the root disk, dd over a disk) that applies even in --yolo mode. Second, tasks with nobody around (scheduled, webhooks) use cron_mode, unattended_mode etc., all deny by default: a dangerous command in a 3am task is denied, not run.

Escrita de arquivos, segredos e injeção de promptFile writes, secrets and prompt injection

  • Escrita: as ferramentas write_file e patch não gravam em ~/.ssh/, ~/.aws/, ~/.kube/, /etc/sudoers nem nos segredos do próprio Hermes (.env, vault/, pairing/), sem pedir aprovação.Writes: the write_file and patch tools do not write to ~/.ssh/, ~/.aws/, ~/.kube/, /etc/sudoers nor Hermes's own secrets (.env, vault/, pairing/), without asking for approval.
  • Segredos: o execute_code remove variáveis com KEY, TOKEN, SECRET, PASSWORD no nome; o backend Docker e o SSH não herdam variáveis do host; processos MCP só recebem variáveis seguras mais as que você declara; e erros de MCP têm tokens (ghp_, sk-, Bearer) trocados por [REDACTED] antes de chegar ao LLM.Secrets: execute_code strips variables with KEY, TOKEN, SECRET, PASSWORD in the name; the Docker and SSH backends do not inherit host variables; MCP processes only get safe variables plus the ones you declare; and MCP errors have tokens (ghp_, sk-, Bearer) replaced with [REDACTED] before reaching the LLM.
  • Injeção de prompt: AGENTS.md, .cursorrules e SOUL.md são varridos (instruções do tipo "ignore as anteriores", comentários HTML escondidos, tentativas de ler .env, exfiltração por curl, Unicode invisível) e bloqueados se suspeitos. Comandos que enviam segredos por curl são sinalizados.Prompt injection: AGENTS.md, .cursorrules and SOUL.md are scanned ("ignore previous instructions", hidden HTML comments, attempts to read .env, curl exfiltration, invisible Unicode) and blocked if suspicious. Commands that send secrets via curl are flagged.
  • Rede: a proteção SSRF bloqueia endereços privados, loopback e o endpoint de metadados da nuvem (169.254.169.254) nas ferramentas de URL, e há uma lista de domínios proibidos (security.website_blocklist). Isso importa na AWS: sem ela, uma página maliciosa poderia induzir o agente a ler as credenciais da instância.Network: SSRF protection blocks private addresses, loopback and the cloud metadata endpoint (169.254.169.254) in URL tools, and there is a domain blocklist (security.website_blocklist). This matters on AWS: without it, a malicious page could trick the agent into reading the instance credentials.

Onde roda: a única fronteira de verdadeWhere it runs: the only real boundary

O backend de terminal local executa os comandos como o seu usuário, sem isolamento. Os backends de contêiner (docker, Modal, Daytona...) isolam de verdade: no Docker, o Hermes usa --cap-drop ALL, no-new-privileges, limite de processos (256) e /tmp em memória, com limites de CPU, memória e disco configuráveis. Nesses backends a verificação de comandos perigosos é dispensada, porque o contêiner é a fronteira. A documentação lista o que fazer em produção:The local terminal backend runs commands as your user, with no isolation. The container backends (docker, Modal, Daytona...) isolate for real: with Docker, Hermes uses --cap-drop ALL, no-new-privileges, a process limit (256) and an in-memory /tmp, with configurable CPU, memory and disk limits. On those backends the dangerous-command check is skipped, because the container is the boundary. The documentation lists what to do in production:

  • Allowlists explícitas; evite GATEWAY_ALLOW_ALL_USERS=true; use pareamento onde der.Explicit allowlists; avoid GATEWAY_ALLOW_ALL_USERS=true; use pairing where possible.
  • Backend de contêiner, com limites de CPU, memória e disco.A container backend, with CPU, memory and disk limits.
  • Segredos em ~/.hermes/.env com chmod 600; terminal.cwd numa pasta sem nada sensível.Secrets in ~/.hermes/.env with chmod 600; terminal.cwd in a folder with nothing sensitive.
  • Não rodar o gateway como root; auditar o command_allowlist; olhar ~/.hermes/logs/; rodar hermes update com frequência.Do not run the gateway as root; audit the command_allowlist; watch ~/.hermes/logs/; run hermes update often.
Aviso sobre o --yolo. Ele desliga as aprovações para a sessão. Num bot que atende o celular, nunca o deixe ligado de forma permanente. Como o modo smart usa outro LLM para julgar risco, ele reduz o ruído, mas não é garantia: para um agente exposto à internet, comece em manual.Warning about --yolo. It turns off approvals for the session. On a bot serving your phone, never leave it permanently on. Because smart mode uses another LLM to judge risk, it reduces noise but is no guarantee: for an agent exposed to the internet, start with manual.
Nota pessoal, não verificada nas fontes: a conclusão de que "só o contêiner é fronteira de verdade" é minha leitura da própria documentação (que chama a lista de negação de "guarda-corpo, não sandbox"). Ligue isto à nota de harness e guardrails (a "trifeta letal": dados privados + conteúdo não confiável + comunicação externa): um agente com memória, web e shell tem as três.Personal note, not verified in the sources: the conclusion that "only the container is a real boundary" is my reading of the documentation itself (which calls the denylist a "guardrail, not a sandbox"). Tie this to the harness and guardrails note (the "lethal trifecta": private data + untrusted content + external communication): an agent with memory, web and shell has all three.
Fontes · verificadas em 2026-10-27Sources · checked on 2026-10-27

6. Instalar e escolher o modelo6. Installing and choosing the model

InstalaçãoInstallation

# Linux, macOS ou WSL2
curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash

# Windows (PowerShell)
iex (irm https://hermes-agent.nousresearch.com/install.ps1)

# depois
source ~/.bashrc      # ou ~/.zshrc
hermes                # abre o assistente na primeira vez

# conferir e reconfigurar
hermes doctor
hermes model          # escolher provedor e modelo
hermes gateway setup  # conectar Telegram, WhatsApp, Signal...
hermes update
Leia antes de rodar um curl | bash. É o método oficial, mas executa um script da internet. Baixe o install.sh primeiro, leia, e só então rode. Na documentação, o instalador baixa Python 3.14, Node.js, ripgrep e FFmpeg gerenciados por ele, instala o Chromium (para a automação do navegador) e cria ~/.hermes; --skip-browser e --non-interactive existem. Há também apps para macOS (Apple Silicon) e Windows, e um pacote para Android/Termux.Read before running a curl | bash. It is the official method, but it runs a script from the internet. Download install.sh first, read it, and only then run it. Per the documentation, the installer fetches Python 3.14, Node.js, ripgrep and FFmpeg managed by itself, installs Chromium (for browser automation) and creates ~/.hermes; --skip-browser and --non-interactive exist. There are also apps for macOS (Apple Silicon) and Windows, and a package for Android/Termux.

Quais LLMs ele suportaWhich LLMs it supports

Quase todos: o Hermes não é preso a um fornecedor. Você escolhe com hermes model, ou troca no meio da conversa com /model provedor:modelo. A tabela traz os principais da documentação:Almost all of them: Hermes is not tied to one vendor. You choose with hermes model, or switch mid-conversation with /model provider:model. The table lists the main ones from the documentation:

Provedor (id)Provider (id)CredencialCredential
anthropicANTHROPIC_API_KEY
openai-apiOPENAI_API_KEY (OPENAI_BASE_URL opcional)
gemini / vertexGEMINI_API_KEY / conta de serviçoservice account
bedrockcadeia de credenciais da AWS (boto3)AWS credentials chain (boto3)
openrouterOPENROUTER_API_KEY (centenas de modelos)(hundreds of models)
nousOAuth (hermes setup --portal): o Nous Portal, com 200+ modelos e ferramentas hospedadasOAuth (hermes setup --portal): Nous Portal, with 200+ models and hosted tools
deepseek, zai (GLM), kimi-coding, minimax, alibaba (Qwen), xai, nvidia, huggingface, fireworks...uma chave por provedor, em ~/.hermes/.envone key per provider, in ~/.hermes/.env
customqualquer endpoint compatível com a API da OpenAI: Ollama, vLLM, llama.cppany OpenAI-compatible endpoint: Ollama, vLLM, llama.cpp
# ~/.hermes/config.yaml: modelo principal e reserva se o principal cair
model:
  provider: "anthropic"
  default: "claude-sonnet-4-6"
fallback_providers:
  - provider: openrouter
    model: anthropic/claude-sonnet-4

# modelo local (Ollama): a documentação exige 64 mil tokens de contexto, no mínimo
model:
  provider: custom
  default: qwen2.5-coder:32b
  base_url: http://localhost:11434/v1
  context_length: 64000          # e suba o servidor com OLLAMA_CONTEXT_LENGTH=64000
  • Contexto mínimo de 64 mil tokens: o Hermes recusa, na partida, um modelo com janela menor. Com Ollama, o contexto padrão costuma ser bem menor, então defina-o no servidor. No vLLM use --enable-auto-tool-choice --tool-call-parser hermes, e no llama.cpp --jinja (necessário para chamada de ferramentas).64k tokens minimum context: Hermes refuses, at startup, a model with a smaller window. With Ollama the default context is usually much smaller, so set it on the server. On vLLM use --enable-auto-tool-choice --tool-call-parser hermes, and on llama.cpp --jinja (required for tool calling).
  • Modelo pequeno local não é o mesmo que um de ponta. Um agente faz muitas chamadas de ferramenta seguidas; modelos fracos erram o formato ou se perdem. Para um bot que mexe em servidor, use um modelo forte. Veja a nota de LLMs open-source para rodar modelos locais e alugar GPU.A small local model is not the same as a frontier one. An agent makes many tool calls in a row; weak models get the format wrong or lose the thread. For a bot that touches a server, use a strong model. See the open-source LLMs note for running local models and renting a GPU.
  • Custo: um agente que roda 24/7 com tarefas agendadas gasta tokens sem você estar olhando. Use /usage, defina um limite de gasto no painel do provedor e prefira cache de prompt (o Hermes monta o prompt justamente para isso).Cost: an agent running 24/7 with scheduled tasks spends tokens while you are not looking. Use /usage, set a spend limit in the provider's dashboard and rely on prompt caching (Hermes builds the prompt exactly for that).
Nota pessoal, sobre as fontes: a página da documentação diz que o login OAuth da Anthropic exige um plano Claude Max com créditos extras, e que o Claude Pro não serve; para o caminho simples use uma chave de API. Os ids de modelo (claude-sonnet-4-6, qwen2.5-coder:32b) são os do exemplo da documentação e envelhecem: use o que o seu provedor listar hoje.Personal note, on sources: the documentation page says Anthropic's OAuth login requires a Claude Max plan with extra credits, and that Claude Pro does not work; for the simple path use an API key. The model ids (claude-sonnet-4-6, qwen2.5-coder:32b) are the documentation's examples and age: use what your provider lists today.
Fontes · verificadas em 2026-10-27Sources · checked on 2026-10-27

7. Deixar rodando 24/7 (Hostinger ou AWS)7. Running 24/7 (Hostinger or AWS)

Para o agente responder sempre, ele precisa rodar numa máquina que fica ligada: um servidor virtual (VPS). O desenho é simples e, graças ao polling do Telegram, não precisa de nenhuma porta aberta:For the agent to always answer, it must run on a machine that stays on: a virtual server (VPS). The design is simple and, thanks to Telegram polling, needs no open port:

Seu celularYour phoneTelegram Servidores doTelegram'sTelegramservers VPS (Hostinger ou EC2)VPS (Hostinger or EC2) hermes gateway runcontêiner, restart: unless-stoppedcontainer, restart: unless-stopped/opt/data ← ~/.hermes entrada: só SSH (ou nenhuma)inbound: SSH only (or none) API do LLMLLM APIHTTPSHTTPS polling (saída)polling (outbound) as setas saem do servidor; ninguém na internet inicia uma conexão com elethe arrows leave the server; nobody on the internet starts a connection to it
O servidor só faz conexões de saída (para o Telegram e para o LLM). Sem portas de entrada abertas, a superfície de ataque é pequena.The server only makes outbound connections (to Telegram and to the LLM). With no inbound ports open, the attack surface is small.

Tamanho do servidorServer size

Com um modelo na nuvem (API), o servidor não roda o LLM, só o agente. As fontes divergem: o container usa cerca de 1 GB de RAM, 2 a 4 GB se você ligar a automação de navegador; o tutorial da Hostinger recomenda no mínimo 2 vCPU e 8 GB; um guia de VPS fala em uns 2 GB para modelos na nuvem. Eu começaria com 2 vCPU e 4 GB e subiria se usar navegador. Não rode o LLM local no mesmo VPS barato: modelo de verdade pede GPU (veja a nota de LLMs).With a cloud model (API), the server does not run the LLM, only the agent. Sources differ: the container uses about 1 GB of RAM, 2 to 4 GB if you turn on browser automation; the Hostinger tutorial recommends at least 2 vCPU and 8 GB; a VPS guide mentions about 2 GB for cloud models. I would start with 2 vCPU and 4 GB and go up if you use the browser. Do not run the local LLM on the same cheap VPS: a real model needs a GPU (see the LLMs note).

Passo a passo (serve para Hostinger e AWS)Step by step (works for Hostinger and AWS)

  1. Crie o servidor com Ubuntu 24.04 e acesso por chave SSH. Detalhes por provedor logo abaixo.Create the server with Ubuntu 24.04 and SSH key access. Provider details just below.
  2. Endureça o básico: usuário comum com sudo (nada de operar como root), login root por SSH desligado, senha por SSH desligada, firewall liberando só o SSH, fail2ban e atualizações automáticas de segurança.Harden the basics: a regular user with sudo (no operating as root), SSH root login off, SSH password login off, a firewall allowing only SSH, fail2ban and automatic security updates.
  3. Instale o Docker pelo repositório oficial dele e ponha seu usuário no grupo docker.Install Docker from its official repository and add your user to the docker group.
  4. Configure uma vez, com o assistente dentro de um contêiner (ele grava a chave do modelo em ~/.hermes/.env).Configure once, with the wizard inside a container (it writes the model key to ~/.hermes/.env).
  5. Suba o gateway com --restart unless-stopped, para ele voltar sozinho após uma queda ou reinício do servidor.Start the gateway with --restart unless-stopped, so it comes back by itself after a crash or server reboot.
  6. Mande uma mensagem pelo celular e confira os logs.Message it from your phone and check the logs.
# no servidor (Ubuntu), como usuário comum
sudo ufw default deny incoming && sudo ufw allow OpenSSH && sudo ufw enable
sudo apt update && sudo apt install -y fail2ban unattended-upgrades

mkdir -p ~/.hermes
# 1) assistente de configuração: informe o provedor e a chave do modelo
docker run -it --rm -v ~/.hermes:/opt/data nousresearch/hermes-agent setup

# 2) credenciais do Telegram (token do BotFather e o seu ID)
cat >> ~/.hermes/.env <<'EOF'
TELEGRAM_BOT_TOKEN=123456:ABC...
TELEGRAM_ALLOWED_USERS=123456789
EOF
chmod 600 ~/.hermes/.env

compose.yaml (baseado no exemplo oficial, sem publicar portas, já que só usamos o chat):compose.yaml (based on the official example, publishing no ports since we only use chat):

services:
  hermes:
    image: nousresearch/hermes-agent:stable   # "stable" em vez de "latest" também é aceito
    container_name: hermes
    restart: unless-stopped
    command: gateway run
    volumes:
      - ~/.hermes:/opt/data
    environment:
      - HERMES_UID=1000      # dono da pasta ~/.hermes no host (confira com: id -u)
      - HERMES_GID=1000
    deploy:
      resources:
        limits:
          memory: 4G
          cpus: "2.0"
docker compose up -d
docker compose logs -f                 # deve mostrar o adaptador do Telegram conectado

# monitorar e operar
docker exec hermes hermes gateway status
docker exec -u hermes hermes hermes pairing list

# atualizar (os dados ficam em ~/.hermes, que é um volume)
docker compose pull && docker compose up -d
Não publique as portas 8642 e 9119. A 8642 é a API do gateway e a 9119 é o painel web. Para chat, nenhuma das duas é necessária. Se quiser o painel, ligue-o só em 127.0.0.1 e acesse por túnel SSH (ssh -L 9119:127.0.0.1:9119 usuario@servidor). Se expuser a API, defina API_SERVER_KEY forte. Nunca rode dois contêineres sobre o mesmo ~/.hermes.Do not publish ports 8642 and 9119. 8642 is the gateway API and 9119 is the web dashboard. For chat, neither is needed. If you want the dashboard, bind it only to 127.0.0.1 and reach it through an SSH tunnel (ssh -L 9119:127.0.0.1:9119 user@server). If you expose the API, set a strong API_SERVER_KEY. Never run two containers over the same ~/.hermes.
O contêiner do Hermes não é o backend Docker. Rodando o agente no contêiner, os comandos dele rodam dentro desse contêiner (backend local dentro dele), o que já o separa do servidor. Isso é diferente do backend docker da seção 5, que cria um contêiner por tarefa. As aprovações de comando continuam valendo no primeiro caso. Mantenha o approvals.mode em smart ou manual e não monte o docker.sock do host dentro dele: quem controla o socket controla a máquina.The Hermes container is not the Docker backend. Running the agent in the container, its commands run inside that container (the local backend inside it), which already separates it from the server. This differs from the section 5 docker backend, which creates a container per task. Command approvals still apply in the first case. Keep approvals.mode at smart or manual and do not mount the host's docker.sock into it: whoever controls the socket controls the machine.

Hostinger

  • Modelo pronto: a Hostinger oferece um template de Hermes Agent para VPS. Ao criar o VPS (ou em VPS → OS & Panel → Operating System → Change OS, procurando "Hermes Agent"), ele instala sozinho, e você abre o projeto no Docker Manager e acessa o terminal web. Atualizar é o menu de três pontos do projeto → Update.Ready-made template: Hostinger offers a Hermes Agent VPS template. When creating the VPS (or in VPS → OS & Panel → Operating System → Change OS, searching "Hermes Agent"), it installs itself, and you open the project in Docker Manager and reach the web terminal. To update, use the project's three-dot menu → Update.
  • Do zero: escolha um VPS com Ubuntu, acesse por SSH e siga o passo a passo acima. É o mesmo caminho do tutorial deles.From scratch: pick an Ubuntu VPS, connect over SSH and follow the step-by-step above. It is the same path as their tutorial.
  • Se usar o painel, o firewall da Hostinger também pode bloquear tudo menos o SSH; faça nos dois lugares (painel e ufw).If you use the panel, Hostinger's firewall can also block everything but SSH; do it in both places (panel and ufw).
Nota pessoal, discrepância nas fontes: o tutorial da Hostinger indica liberar o usuário do Telegram em gateway → telegram → allowed_user_ids no config.yaml, mas a documentação oficial de segurança e de Telegram usa a variável TELEGRAM_ALLOWED_USERS no .env. Usei a oficial. Também não vi preços; confira o plano na Hostinger.Personal note, a discrepancy in the sources: the Hostinger tutorial says to allow the Telegram user at gateway → telegram → allowed_user_ids in config.yaml, but the official security and Telegram documentation uses the TELEGRAM_ALLOWED_USERS variable in .env. I used the official one. I also did not see prices; check the plan at Hostinger.

AWS

Não encontrei um guia oficial do Hermes para a AWS. O que segue é a minha adaptação do mesmo passo a passo, e não foi testado:I did not find an official Hermes guide for AWS. What follows is my adaptation of the same step-by-step, and it is untested:

  • Instância EC2 (ou Lightsail, mais simples) com Ubuntu 24.04, tipo com 2 vCPU e 4 GB (a família t3/t4g serve) e um volume EBS criptografado de uns 30 GB. Não precisa de Elastic IP: o agente só faz conexões de saída.An EC2 instance (or Lightsail, simpler) with Ubuntu 24.04, a 2 vCPU and 4 GB type (the t3/t4g family works) and an encrypted EBS volume of about 30 GB. No Elastic IP needed: the agent only makes outbound connections.
  • Security group sem nenhuma regra de entrada. Para administrar, use o SSM Session Manager (anexe à instância um perfil IAM com AmazonSSMManagedInstanceCore) em vez de abrir a porta 22. Se preferir SSH, libere a 22 só para o seu IP.A security group with no inbound rules. To administer, use SSM Session Manager (attach an IAM profile with AmazonSSMManagedInstanceCore to the instance) instead of opening port 22. If you prefer SSH, allow 22 only from your IP.
  • IMDSv2 obrigatório nas opções de metadados da instância. Combina com a proteção SSRF do Hermes (seção 5): um agente que lê páginas da web é exatamente o tipo de coisa que tenta alcançar o 169.254.169.254.Require IMDSv2 in the instance metadata options. It pairs with Hermes's SSRF protection (section 5): an agent that reads web pages is exactly the kind of thing that tries to reach 169.254.169.254.
  • Modelo pelo Bedrock, sem chave nenhuma: o provedor bedrock usa a cadeia de credenciais da AWS, então um perfil IAM da instância com permissão mínima (bedrock:InvokeModel* nos modelos que você usa) dispensa guardar uma chave de API no .env. É o mesmo princípio da nota de OIDC: credencial temporária em vez de segredo fixo.Model through Bedrock, with no key at all: the bedrock provider uses the AWS credentials chain, so an instance IAM profile with minimal permission (bedrock:InvokeModel* on the models you use) removes the need to store an API key in .env. It is the same principle as the OIDC note: temporary credentials instead of a fixed secret.
  • Cuidado com o perfil IAM: tudo o que o perfil permite, o agente (e quem o enganar) consegue fazer. Dê só o Bedrock, nada de S3 amplo ou administração.Watch the IAM profile: whatever the profile allows, the agent (and anyone who tricks it) can do. Give only Bedrock, no broad S3 or admin.
  • Depois, é o mesmo: instalar o Docker, setup, .env e docker compose up -d. Os logs podem ir ao CloudWatch com o driver de log do Docker, e um alarme de custo (AWS Budgets) protege contra um agente em loop.After that, it is the same: install Docker, setup, .env and docker compose up -d. Logs can go to CloudWatch with Docker's log driver, and a cost alarm (AWS Budgets) protects against an agent in a loop.

Hostinger ou AWS?Hostinger or AWS?

HostingerAWS
ComeçoGetting startedTemplate pronto + Docker Manager; minutosReady template + Docker Manager; minutesVocê monta tudo (EC2, rede, IAM)You assemble everything (EC2, network, IAM)
Credenciais do modeloModel credentialsChave de API no .envAPI key in .envPerfil IAM + Bedrock: sem chave guardadaIAM profile + Bedrock: no stored key
Acesso administrativoAdmin accessSSH / terminal webweb terminalSSM, sem porta abertaSSM, no open port
Custo e previsibilidadeCost and predictabilityMensalidade fixa de VPSFixed monthly VPS feePago por uso; defina alarme de custoPay per use; set a cost alarm
Bom paraGood forBot pessoal, simples e baratoA personal bot, simple and cheapQuem já está na AWS e quer IAM e logs integradosThose already on AWS wanting integrated IAM and logs

8. Checklist8. Checklist

  • Modelo forte e com 64 mil tokens de contexto ou mais; limite de gasto no provedor.A strong model with 64k tokens of context or more; a spend limit at the provider.
  • Allowlist ou pareamento em toda plataforma; GATEWAY_ALLOW_ALL_USERS desligado.Allowlist or pairing on every platform; GATEWAY_ALLOW_ALL_USERS off.
  • approvals.mode: manual (ou smart com atenção); nunca --yolo permanente.approvals.mode: manual (or smart with care); never a permanent --yolo.
  • Agente em contêiner, sem docker.sock, sem root, sem portas publicadas.Agent in a container, no docker.sock, no root, no published ports.
  • Segredos só em ~/.hermes/.env (chmod 600); no WhatsApp, a pasta da sessão com chmod 700 e número dedicado.Secrets only in ~/.hermes/.env (chmod 600); on WhatsApp, the session folder with chmod 700 and a dedicated number.
  • skills.write_approval e memory.write_approval ligados no começo; revisar ~/.hermes/skills/ de vez em quando.skills.write_approval and memory.write_approval on at first; review ~/.hermes/skills/ from time to time.
  • Servidor: SSH por chave, firewall só com o necessário, fail2ban, atualizações automáticas, restart: unless-stopped.Server: SSH keys, firewall with only what is needed, fail2ban, automatic updates, restart: unless-stopped.
  • Na AWS: sem entrada no security group, SSM, IMDSv2, perfil IAM mínimo, alarme de custo.On AWS: no inbound in the security group, SSM, IMDSv2, minimal IAM profile, cost alarm.
  • Backup de ~/.hermes (é a memória, as skills e as sessões do agente) e hermes update ou docker compose pull regularmente.Back up ~/.hermes (it is the agent's memory, skills and sessions) and run hermes update or docker compose pull regularly.
Limites desta nota. A documentação do Hermes, o README e o tutorial da Hostinger foram lidos em 27/10/2026. Eu não rodei o Hermes com um modelo real: só baixei a imagem oficial e vi a estrutura de pastas criada na primeira partida; nenhum outro comando desta nota foi executado por mim, e a seção da AWS é minha adaptação, sem teste. O projeto muda rápido (chaves de configuração, tags de imagem, plataformas); confira a documentação da versão que instalar antes de depender de um detalhe.Limits of this note. The Hermes documentation, the README and the Hostinger tutorial were read on 2026-10-27. I did not run Hermes against a real model: I only pulled the official image and saw the folder structure created on first start; no other command in this note was executed by me, and the AWS section is my untested adaptation. The project moves fast (configuration keys, image tags, platforms); check the documentation for the version you install before relying on a detail.