No processo de construção de um sistema de IA agente, eu vou primeiro construir a parte "agente" e "sistema", tocando muito pouco na IA. Há várias razões para isso. A auditoria é uma delas. Quero saber exactamente o que está a acontecer e porquê. Eu acho que a IA é, na maioria das vezes, desnecessária para tanto (1) tomada de ação e (2) tomada de decisão para mim neste momento. Veja Automação é mais útil do que inteligência artificial, para algum raciocínio de estilo livre sobre o tema.
Você pode pensar no sistema de software como um animal. Músculos, esqueleto e o resto da estrutura vão muito longe, muito antes que a inteligência em um animal se torne útil ou desejável. Eu levava um boi ou uma mula sobre um macaco, para o trabalho de parto, na maioria das vezes. Então vamos desenvolver a estrutura primeiro - os músculos e ossos - antes de desenvolver o cérebro.
Já tenho um rascunho de um sistema que pode ser convertido em agente. Na verdade, tenho dois. Um é o cliente de e-mail. O outro é um bot comercial - ver Construindo uma Plataforma de Comércio Agente.
Eu tenho um cliente de e-mail (uma plataforma de e-mail inteira na verdade) e ele pode ser convertido em agente. Isso significa que o cliente de e-mail responderá automaticamente aos e-mails. Como seria divertido! Estou surpreso por nunca ter feito isto antes. Na verdade, trabalhei durante anos neste projecto, a fazer intervalos muito longos. E outras pessoas e empresas também têm trabalhado nisso, tenho certeza que clientes de e-mail sofisticados já existem, de código aberto ou proprietários. Vou fazer o meu, tanto como um exercício e porque preciso dele. E eu não vou simplesmente dar trabalho a outra pessoa e simplesmente pagar uma taxa API. Não, eu mesmo faço o trabalho, e sou dono do produto acabado.
No sistema de e-mail, as peças são (0) recebendo e processando e-mails, (0) mantendo o controle de conversas anteriores e todo o histórico de conversas com este leadset, (0) gerando um e-mail de resposta (talvez através de um modelo rico), (0) e seguindo uma intenção de mover o lead para baixo um funil de vendas.
♪ ♪ ♪ ♪ ♪ ♪
Muito bem, vamos começar. Vamos de simples para complexo para poupar tempo e dor de cabeça. Vamos rever a arquitetura da plataforma de negociação, já que já está praticamente feito. Além disso, vamos fazer isso em rubi em trilhos, principalmente, como uma questão de preferência pessoal. Se você está começando do zero eu provavelmente tenho que recomendar python, já que tanto código de IA é python. E eu definitivamente recomendo contra digitação, eu sugiro que você use javascript puro porque é muito mais claro e mais leve.
Digamos que a configuração já foi feita. Voltaremos a fazer o esquema assim que estabelecermos o passo comum. Por enquanto, assuma que tudo já está funcionando.
Em termos simples, o e-mail agente faz o seguinte:
Upon receiving an email,
Evaluate if any action needs to be taken.
Examples are: add/remove tags, auto-respond, or (importantly) take an office action.
Evaluation is semantically equivalent to taking the action.Isso também parece muito simples. Aqui, digo que decidir que se deve tomar uma medida é o mesmo que tomar essa ação. Parece-me razoável, e flui no espírito de rubi-em-trilhos: o método é o mesmo que o resultado de chamar o método. Onde está a parte agente?
♪ ♪ ♪ ♪ ♪ ♪
Vejamos os sistemas de agentes existentes para ver como são construídos. Muitos deles são sistemas de telefone: digamos que você ligar para o seu banco, mas o telefone tenta falar com você sem envolver um representante de serviço ao cliente humano. Como funcionam esses sistemas? Eu vou pular o material de linguagem natural: análise de voz, geração de voz e LLM foram muito bem feitos pelos gigantes da indústria, e eu não posso nem reinventar essas coisas, nem realmente melhorar. Vou usar o LLM disponível e rotinas de síntese/análise. Presumo que o simples texto em inglês seja a interface universal. Isso pode ser expandido em yaml ou json - que é novamente um contêiner semântico mínimo com aparência de linguagem, mas muito mais estruturado do que o inglês. A interface yaml/json então converte em código, particularmente para integrações API - mas essa interface também pode ser limpa e compreensível. Eu não preciso de IA para escrever o código do conector API, vamos apenas dizer que ele pode ser escrito por pessoas.
Contexto
O sistema agentic antigo tem contexto para o usuário: ele sabe quem é o usuário, o que está em sua conta, e o que o usuário disse ou fez anteriormente, de alguma forma. Para mim, esta informação é dados estruturados do Leadset. Cada pessoa (endereço de e-mail) pertence à sua empresa (leaderset), e as muitas conversões são todas retrieváveis referenciando esta pessoa (email). Informações relevantes também são recuperáveis de todas as conversas de todos os colegas de trabalho (empresa, leadset). Isto foi implementado.
Intenção
O antigo sistema de agentes opera com intenção. O sistema lê a intenção do cliente (por exemplo: check balance, boletim de ocorrência roubado, fazer um pagamento ou cometer suicídio assistido pelo governo). Por agora, vamos ter todas as possíveis intenções codificadas. Em seguida, o sistema toma uma das ações possíveis. Parece que uma ação disponível se correlaciona muito de perto com uma intenção. Talvez cada intenção corresponda a uma ou várias ações. Como escreveríamos isso em pseudocódigo?
## won't quite work:
Upon receiving an email,
Decide the intent (confirmable/overrideable), then
Take action relevant to the intent.No entanto, meu sistema de email não é um chatbot de atendimento ao cliente. O cliente de email não reage à intenção do remetente - ele tem intenção própria. O sistema tem de ter os seus próprios objectivos. Eu chamo a ideia de funil de vendas, por enquanto. Uma vez que tudo isto está a ser feito para gerar receitas, estou a pôr isto em primeiro lugar nas vendas.
Várias Definições Pragmáticas de Bots de Email
Vamos criar várias definições de bots de email que fazem sentido e são pragmáticos. Vamos projetar um ou vários funis de vendas, ou ações que um bot agente pode tomar. Vamos fazê-lo em inglês. Lembre-se que podemos converter para yml/json, em seguida, para ruby interface chamadas, em seguida, para implementação de código real. Aqui vamos nós. Alguns agentes já precisam de mim.
- AniversárioBot
- SpamCocktailBot
- EmailFluffBot
- ColdcallBot
E definições de pseudocódigo para cada separadamente.
AniversárioBot
BirthdayBot
When it's someone's birthday as determined by tags and the clock,
Generate an original birthday letter and send it.ColdcallBot
ColdcallBot
For each tagged lead (in the campaign)
periodically (every day)
If I bothered them 0 times (n_impressions),
send the main pitch.
mark that I've bothered them 1 time.
If I bothered them 1 time,
send the 2nd reminder
mark that I've bothered them 2 times.
If I bothered them 2 times,
send the 3rd sales pitch
mark that I've bothered them 2 times.
If I bothered them 3 times,
remove tag, add tag `closed`
When receiving an email in a relevant conversation,
delete previously scheduled reminders
remove tag, add tag `closing-manual`SpamCocktailBot
SpamCocktailBot
When receiving an email from a spam lead (new or existing),
Delete all previous follow-ups to this lead.
Create a semi-meaningful reply and send it.
Schedule to follow up in 2 days.EmailFluffBot
EmailFluffBot
Periodically for each lead tagged to be conversed with,
Taking previous conversations into account,
Send them a generated email based on the general intent of the bot.♪ ♪ ♪ ♪ ♪ ♪
Como é que eu manteria o controle de quantas vezes cheguei a uma pista? Seria um nome específico para a campanha per-leader. Nós cronometramos tudo no nome e enquanto isso por si só não garante singularidade nome, ele vem muito perto disso, e é muito semântico e utilizável. Um exemplo de nome de campanha (slug) é `20260320-diretor' ou '20260320 KY diretor fri call' ou algo semelhante, onde eu entrar em contato com todos os decisores de nível de diretor em Kentucky, hoje (diferente de fazer a mesma coisa amanhã). O comando Seach teria então o parâmetro de configuração:
this_lead.memory ||= {}
this_lead.memory['20260320 KY director coldcall'] ||= {}
this_lead.memory['20260320 KY director coldcall']['n_impressions'] ||= 0
this_lead.memory['20260320 KY director coldcall']['n_impressions'] += 1A palavra `memory` acima não significa nada, mas há também `this lead.config` que é separada, e os itens de memória não devem estar na raiz. Memória é Contexto, mas eu uso a palavra Contexto em outro lugar já.
E enviar o principal, 2o e 3o lançamentos são EmailTemplates. Este objeto já foi construído, e tem um contexto para o lead, então é um e-mail transacional com templating rico e substituição variável, como o nome do lead.
Intenção pode ser facilmente implementada com marcação (que já existe). Ter tags por exemplo `intent-they-salespitch-me` pertence à tag `intents`, atribuir esta tag para o líder ou conversa, e lá vai, já foi feito.
Possíveis intenções no e- mail:
- Eles vendem-me
- Eles incomodam-me sem motivo.
- spam
- automatizado... periódico
- um amigo próximo
- um verdadeiro ser humano
- um cliente potencial
- um recrutador
Então, posso atribuir a intenção à liderança e à conversa só por marcar.
Mais uma coisa. Temos de conceptualizar um funil de vendas. Ver o artigo sobre Funil de vendas: Definição, Modelos e Estágios.
♪ ♪ ♪ ♪ ♪ ♪
É uma boa ideia escrever as balas que planeias usar antes do tempo, na fase de planeamento, e não mudá-las mais tarde. Há pouca validação de lesmas, então você deve ser exato em como você acessa objetos. Eu gosto de começar cada lesma com a data em formato yyymmdd, ou formato yyyymm. Isto funcionou bem para mim, especialmente porque a ordenação alfabética também classifica por data.
Precisas de todos os modelos de email. Os modelos são:
- 20260320-coldcall-intro
- 20260320-coldcall-intro-1
- 20260320-coldcall-intro-2
Precisas de todas as lesmas. São eles:
- 20260320-call-active
- 20260320-call-done
A bala para esta campanha pode ser: `20260320-coldcall'. Reparem que evito espaços em lesmas. As lesmas devem ser codificadas.
EmailTemplate's
Então o meu bot de e-mail ai agentic vai enviar uma sequência de e-mails para pistas frias. Vamos escrever o conteúdo para os e-mails. Este funil é para decisores técnicos, executivos como CTO em suas empresas. Primeiro, o bot vai se apresentar e pedir permissão para continuar. Em seguida, a intenção será capturada, que é uma das seguintes: (1) `no-stop`, (2) `yes-continua' e (3) `no-response'. Se eles responderem positivamente, 'sim-continua', na verdade eu já deveria mudar o processo para manual, já que já seria um cliente interessado. Na verdade, obter uma única pessoa para responder 'sim-continua' resultará em conclusão bem sucedida desta tarefa. Se eles responderem `no-stop`, o bot envia uma mensagem final agradável `tmpl-fin-neg'. Se não houver resposta, a mensagem "tmpl-intro-2" é enviada. Depois disso, se não houver resposta, a mensagem 'tmpl-fin-neg' é enviada. É o bot completo e o funil completo. Vamos rever.
Existem duas maneiras de criar os modelos de email. Podes escrevê-las e salvá-las. Ou você pode usar GPT para escrever e salvá-los. Este artigo é sobre o bot de email, ao invés do agente de LLM conversacional, então eu vou pular a segunda, opção mais complicada, e apenas escrever o modelo do zero. Na verdade, eu ainda vou usar um GPT, mas vai copiar-colar o texto manualmente.
20260320-coldcall-intro
prompt: Write a cold-approach email directed at CTO's and other technical decision-makers of technology companies, asking them if they'd like to hear about the technology services (such as software development or feature implementation) that Wasya Co offers.Assunto: Soluções tecnológicas de exploração para [Nome da empresa]
Olá [Primeiro nome],
Espero que esta mensagem o encontre bem. Estou ligando da Wasya Co, onde ajudamos as empresas de tecnologia a acelerar seus projetos através do desenvolvimento de software especializado e implementação de recursos sob medida.
Eu adoraria entender suas prioridades tecnológicas atuais e explorar se nossos serviços poderiam apoiar sua equipe em alcançá-las de forma mais eficiente. Aceitaria uma breve chamada para discutir isto?
Ansioso pelos seus pensamentos,
[Seu nome]
[Sua posição]
Wasya Co
[Informações de contacto]
20260320-coldcall-intro-1
prompt: write a follow-up to the previous, if he doesn't reply in 2 daysObjecto: Acompanhamento do apoio tecnológico à [Nome da empresa]
Olá [Primeiro nome],
Eu queria seguir em meu email anterior sobre como Wasya Co pode ajudar [Nome da empresa] com desenvolvimento de software e implementação de recursos.
Se você estiver aberto a uma conversa rápida, ficarei feliz em discutir como nossas soluções podem ajudar sua equipe a alcançar seus objetivos de forma mais rápida e eficiente. Por favor, deixe-me saber um tempo que funciona para você, ou eu ficaria feliz em enviar algumas informações breves para você rever em sua conveniência.
Estou ansioso para ouvir de você,
[Seu nome]
[Sua posição]
Wasya Co
[Informações de contacto]
20260320-coldcall-intro-2
prompt: write a final, closing follow-up saying to reach out to me if anything changesAssunto: Último seguimento – Wasya Apoio à co-tecnologia
Olá [Primeiro nome],
Eu queria chegar a uma última vez em relação ao desenvolvimento de software de Wasya Co e serviços de implementação de recursos. Eu entendo completamente se agora não é a hora certa.
Se suas prioridades mudarem ou você quiser explorar como podemos apoiar sua equipe no futuro, por favor, não hesite em entrar em contato – eu ficaria feliz em me conectar sempre que for conveniente para você.
Obrigado pelo seu tempo e consideração,
[Seu nome]
[Sua posição]
Wasya Co
[Informações de contacto]
Crie os modelos de email. Vamos pular a mensagem 'tmpl-fin-neg', já que o silêncio vai servir muito bem por enquanto.
Vou combinar código de rubi com usar a UI. A UI acomoda especificamente blocos de avaliação de código, em certos lugares. Embora menos seguro do que apontar e clicar, ele me oferece duas vantagens. Primeiro, não tenho de imaginar toda a UI que acho que vou precisar no futuro. Apenas callbacks de forma livre vão muito longe, e para um usuário técnico (especialista) que será suficiente. Abaixo da linha, o sistema irá oferecer vários tempos de execução (por exemplo, você será capaz de escrever código javascript ou rubi, em seu preferencE) bem como UI para não escrever código em tudo. Em segundo lugar, oferece-me uma enorme flexibilidade. Enquanto as variáveis corretas estiverem expostas (e elas estiverem), posso ser muito sofisticada no que faço com elas.

Clique no link `[+]` para começar a criar um novo EmailTemplate.
Note que o sujeito, assim como o corpo, permite variáveis de modelo erb. As variáveis disponíveis estão listadas.

Clique no link RTEditor no rodapé para abrir o editor de texto rico em uma janela separada.

A razão pela qual o editor de texto rico não é build no formulário, é que como um usuário técnico, você pode querer colocar mais do que tags html no corpo do e-mail. Especificamente, você pode usar erb (ruby) templating para inserir variáveis dinâmicas no texto. As variáveis disponíveis estão listadas na dica. Por exemplo, você pode escrever:
Hello <%= @lead.name -%>,Para personalizar a saudação. Para permitir isso, atualmente, você deve escrever texto simples (que pode incluir código html ou outro código). Mas você ainda pode escrever texto rico no editor fornecido separadamente, em seguida, copie-paste a fonte na forma do modelo de e-mail.
Terminar colando os valores e clique em Salvar.

Estados-Membros das máquinas
Os estados da máquina atual state são:
- "Começar"
- "Sem parar"
- "sem resposta-1"
- "sem resposta-2"
- "Sim-continuar"
- "fin"
Os estados máquinas e estado, embora não mencionado por este termo neste artigo antes, referem-se ao estado memorizado. O estado do líder é persistido ao redor, e o líder tem um dicionário de estado. Se você salvou algo na memória deste chumbo há um ano, ele ainda estará lá. Portanto, você pode, ou não, querer separar as variáveis para esta cambina em seu próprio hash:
## if you don't anticipate conflicts:
lead.memory['current_state'] = 'no-response-1'
## if you want to compartmentalize:
lead.memory['20260320-coldcall'] ||= {}
lead.memory['20260320-coldcall']['current_state'] = 'no-response-1'que realmente se correlaciona com a variável `this leader.memory['20260320 KY director coldcall']['n impressions']` como tal:
n impressões:estado atual:0(início)- Não.(sem parar)1(sem resposta- 1)2(sem resposta-2)- Não.(sim-continua)3(fin)Vou usar o estado atual, em vez de n impressões, pois acredito que é mais preciso. Ou posso usar os dois. Agora, vamos implementar este bot na plataforma wco email. Uma vez implementados, carregaremos cerca de 100 leads como dados de teste e lançaremos a campanha!
\<>
OfficeActionTemplate (OAT)
Agora, vamos configurar o bot, que consiste em duas partes. Um deles é um OfficeActionTemplate, que envia o EmailTemplate especificado acima. O outro é um EmailFilter, que age sobre uma resposta da liderança.
Vamos criar a OAT, que é a batata e a carne desta bot/campanha. No Pseudocode pode parecer algo assim:
OfficeActionTemplate
if leads.count == 0
report to self: the campaign has ended
this_oat.unschedule()
For each lead in the tag `a20260320-active-leads`,
case lead.memory['current_state']
when
(begin)
send: a20260320-tmpl-intro
lead.memory['current_state'] = no-response-1
(no-stop)
(no-response-1)
send: a20260320-tmpl-intro-1
lead.memory['current_state'] = no-response-2
(no-response-2)
send: a20260320-tmpl-intro-2
lead.memory['current_state'] = no-stop
lead.tags.delete a20260320-active-leads
lead.tags.add a20260320-done-leads
(yes-continue)
(fin)
next_at( Time.now + 2.days )E o código:
tag = Wco::Tag.find_by({ slug: '20260320-coldcall-active' })
leads = tag.leads
if leads.count == 0
@oat.update({ status: 'inactive' }) ## oat == office action template
ApplicationMailer.notify_self({ subject: "Campaign 20260320-coldcall-active has finished." })
else
leads.each do |lead|
lead.memory['current_state'] ||= 'begin'
lead.memory['n_impressions'] ||= 0
case lead.memory['current_state']
when 'begin':
WcoEmail::EmailAction.create({
lead: lead,
template: EAT.find_by({ slug: '20260320-tmpl-begin' }), ## EAT == EmailActionTemplate
perform_at: Time.now })
lead.memory['current_state'] = 'no-response-1'
when 'no-stop':
lead.remove_tag tag
when 'yes-continue':
lead.remove_tag tag
ApplicationMailer.notify_self({
subject: "Campaign 20260320-coldcall-active lead #{lead.id} replied yes-continue!",
body: "Lead: #{lead.inspect}
" })
when 'fin':
lead.remove_tag tag
when 'no-response-1':
WcoEmail::EmailAction.create({
lead: lead,
template: EAT.find_by({ slug: '20260320-tmpl-cont-1' }), ## EAT == EmailActionTemplate
perform_at: Time.now })
lead.memory['current_state'] = 'no-response-2'
when 'no-response-2':
WcoEmail::EmailAction.create({
lead: lead,
template: EAT.find_by({ slug: '20260320-tmpl-cont-2' }),
perform_at: Time.now })
lead.memory['current_state'] = 'fin'
else:
ApplicationMailer.notify_self({
subject: "Campaign 20260320-coldcall-active something went wrong with lead #{lead.id}.",
body: "Lead: #{lead.inspect}
Oat: #{@oat.inspect}" })
end
end
endVamos colar na UI. É um pouco complicado e técnico, no entanto, fazer uma IU sem o código será ainda mais complicado, e só será feito no futuro se a demanda do cliente suficiente é demonstrada.

Vamos passar a criar um filtro de e- mail.
EmailFilter
O EmailFilter é outra parte deste bot. Trata das respostas (se houver) dos leads.
EmailFilter
if lead.tags.include? a20260320-active-leads
intent = induce_intent()
lead.memory['current_state'] = intent
case intent:
when 'yes-continue':
notify self: Email.find('this-lead-is-interested', lead:, )
when 'no-stop':
lead.tags.delete a20260320-active-leads
lead.tags.add a20260320-done-leads
default:
notify_self: Email.find('for-review', lead:, )E é basicamente isto. A única coisa a fazer é colocar 100 pistas nesta etiqueta de teste... e lançá-la!
Aqui está como importar e-mails para uma tag:
\<>
E para lançar a campanha, simplesmente crie o OfficeAction fora do modelo.
Óptimo! Agora que foi lançado, vamos monitorar o processo. Eu me adicionei como um desses leads, então eu vou testar o fluxo de trabalho participando de ambos os lados da campanha. Vou responder sim-continuar e no-stop, para testar o fluxo de trabalho.
\<>
O fluxo de trabalho acima é um exemplo de como configurar um Email Agent no sistema wco email. Não usamos IA para isto, só a parte de indução.
comments
Please login to post comments:Many technologists rush to add AI into routine email workflows, but automation and well-structured rules often deliver far more reliability and transparency than agentic AI. Sometimes, a 'dumb' system is all a real business needs.