Funções do Aplicativo Android: Ensinar Agentes IA a Usar Seu App
Introdução
Por grande parte da história do Android, construímos aplicativos para pessoas.
Um usuário abre um app, olha uma tela, encontra um botão, navega por um menu, insere alguns dados e finalmente realiza uma ação. Esse modelo funciona bem quando o usuário é humano.
Funciona muito menos bem quando o usuário é um agente IA.
Um agente que deseja interagir com um aplicativo pode tentar entender o que está exibido na tela, identificar elementos de interface do usuário (UI), navegar por eles e reproduzir os mesmos passos que um humano faria. Mas isso transforma uma operação simples em uma sequência frágil de interações visuais.
Funções do Aplicativo Android introduzem um modelo diferente.
Ao invés de pedir ao agente para entender como usar sua UI, seu aplicativo pode descrever o que ele pode fazer.
Isso é uma mudança significativa. Estamos passando de: Mostre-me a tela correta para Execute essa função
O problema da ilha digital
A maioria dos aplicativos é, efetivamente, ilhas de lógica empresarial cercadas por uma interface do usuário.
Um aplicativo de notícias sabe como recuperar artigos. Um aplicativo bancário sabe como transferir dinheiro. Um aplicativo de compras sabe como adicionar produtos a um pedido.
Mas essas capacidades geralmente são acessíveis através de telas projetadas para humanos.
Do ponto de vista de um agente IA, a funcionalidade está escondida atrás de navegação, botões, texto, imagens, rolagem, diálogos e outros elementos da interface do usuário.
Considere um pedido simples: “Dê-me as últimas receitas culinárias do The New York Times.”
Um agente operando apenas através da UI pode ter que encontrar o aplicativo, abri-lo, esperar carregar, localizar a seção de alimentos, rolar pelo conteúdo, interpretar o que aparece na tela e extrair as informações relevantes.
Isso é particularmente importante com agentes baseados em LLM. O modelo pode ser bom para raciocinar sobre o que ele vê, mas pedir repetidamente a um modelo probabilístico para navegar por uma UI não é uma interface ideal entre sistemas de software e pode levar a erros.
Mesmo que uma aplicação já saiba como recuperar a informação, deve haver um modo mais direto de perguntá-la.
De suposições para execução estruturada
Gerações anteriores de assistentes eram frequentemente baseadas em intenções pré-definidas, palavras-chave e integrações.
Modelos de linguagem modernos (LLMs) mudaram significativamente uma parte do problema: entender o que o usuário está tentando alcançar.
Um usuário pode dizer: "Adicione leite à minha lista de compras.", "Você poderia colocar leite na lista?" ou "Eu esqueci o leite. Adicione por mim, ok."
Um modelo de linguagem pode frequentemente inferir que essas solicitações representam a mesma ação subjacente.
No entanto, entender a solicitação é apenas metade do problema.
O modelo ainda precisa ter uma maneira confiável de descobrir qual aplicativo pode executar essa ação, entender os parâmetros que ele requer, executá-lo e interpretar o resultado.
É aqui que as AppFunctions se tornam interessantes.
AppFunctions como camada de capacidade
Invezes de esperar que o agente entenda seus botões e layouts, seu aplicativo expõe capacidades estruturadas que o sistema pode descobrir e chamar.
No conceito, um aplicativo poderia exibir funções como:
getHeadlines()
addItemToShoppingList(item)
playMatch(matchId)
createNote(content)
transferMoney(account, amount)
A parte importante não são os nomes de função exatos.
A parte importante é que o aplicativo está expondo capacidades em vez de telas.
A IU continua valiosa para humanos. As AppFunctions fornecem uma interface adicional para software agindo em nome do usuário.
O fluxo agente: Recuperar, Combinar, Executar
Primeiro, o agente recupera os metadados de AppFunctions disponíveis.
A seguir, um modelo interpreta a solicitação do usuário e a combina com as funções disponíveis e seus esquemas.
No final, Android invoca a função selecionada e o aplicativo executa sua lógica empresarial normal.
Mantenha HTML no corpo se existir.
User:
"Crie uma nota que diz comprar leite."
↓
Agente:
entende o pedido
↓
Descoberta de AppFunction:
encontra createNote(content)
↓
Android:
executa createNote("comprar leite")
↓
Seu aplicativo:
valida → armazena → retorna resultado
O ponto arquitetônico interessante é que a IA não precisa implementar a lógica de negócios do seu aplicativo. Seu aplicativo ainda possui essa lógica.
O agente decide qual capacidade solicitar. Seu código permanece responsável por executá-la corretamente.
Como as partes estão conectadas
Um aplicativo de agente pode recuperar metadados de função, usar um modelo de chamada de função para selecionar a função apropriada e então pedir ao Android que execute-a.
Sua aplicação participa expondo capacidades claramente definidas. Essa separação é importante.
- O agente lida com interpretação.
- Android lida com descoberta e invocação.
- Seu aplicativo lida com a lógica de negócios, permissões, dados e persistência.
Isto é uma fronteira muito mais limpa do que dar ao modelo AI controle sobre uma sequência de botões e esperar que ele chegue ao resultado correto.
Prepare seu aplicativo para AppFunctions
Como sempre, você precisa importar as dependências corretas.
KSP no topo do seu arquivo gradle:
alias(libs.plugins.ksp)
Dependência de AppFunctions:
implementation(libs.androidx.appfunctions)
implementation(libs.androidx.appfunctions.service)
ksp(libs.androidx.appfunctions.compiler)
KSP na parte inferior do seu arquivo gradle:
// Configure AppFunctions KSP
ksp {
arg("appfunctions:aggregateAppFunctions", "true")
arg("appfunctions:generateMetadataFromSchema", "false")
}
Arquivo toml:
Criando o contrato estruturado
Você não precisa reescrever sua aplicação em torno da IA. Em vez disso, você expõe partes selecionadas de sua lógica empresarial existente por meio de anotações como @AppFunction e tipos estruturados usando @AppFunctionSerializable.
/**
* Uma nota com conteúdo e data.
*
* @param content O conteúdo da nota.
* @param date A data da nota.
*/
@AppFunctionSerializable(isDescribedByKDoc = true)
data class Note(
val content: String,
val date: Long
)
class MyNoteAppFunction(
val repository: Dependency
) {
/**
* Cria uma nova nota.
*
* @param appFunctionContext O contexto no qual a AppFunction é executada.
* @param content O conteúdo da nota.
* @return A nota criada.
*/
@AppFunction(isDescribedByKDoc = true)
fun createNote(
appFunctionContext: AppFunctionContext,
content: String
): Note {
return Note(
content,
System.currentTimeMillis()
)
}
}Esta é uma parte importante da design. Sua capacidade agora tem:
entrada estruturada → lógica de aplicativo → saída estruturada
Um agente não precisa mais descobrir qual campo de texto deve conter a nota ou qual botão salva. Ele chama a capacidade.
Documentação se torna parte da interface
Uma das consequências mais interessantes dos AppFunctions é que a documentação se torna mais importante.
Em código de aplicativo normal, um desenvolvedor às vezes pode se dar ao luxo de comentários vagos porque outro desenvolvedor pode inspecionar a implementação. Um agente IA não pode fazer as mesmas suposições.
A descrição de uma capacidade ajuda a explicar o que a função faz, quando deve ser selecionada, o que seus parâmetros significam e o que retorna.
Trate a documentação da função como parte do seu contrato público:
/**
* Cria uma nova nota contendo o texto fornecido.
*
* @param content Texto que deve ser armazenado na nova nota.
* @return A nota após ter sido persistida.
*/
fun createNote(content: String): NoteIsso dá tanto aos desenvolvedores quanto às máquinas uma descrição muito mais clara da capacidade.
Em uma arquitetura agêntica, a documentação não é mais apenas documentação. Ela se torna metadados usados para entender seu software.
Registrando suas AppFunctions
Você precisa registrar suas AppFunctions dentro da classe Application conforme abaixo
class MyApplication : Application(), KoinComponent, AppFunctionConfiguration.Provider {
val myNoteAppFunction: MyNoteAppFunction by inject()
override val appFunctionConfiguration: AppFunctionConfiguration
get() = AppFunctionConfiguration
.Builder()
.addEnclosingClassFactory(MyNoteAppFunction::class.java) {
myNoteAppFunction
}
.build()
// ...
}Suas AppFunctions geralmente devem chamar os mesmos repositórios, serviços e casos de uso que sua interface já usa. Evite criar uma segunda implementação da lógica do seu negócio especificamente para IA.
Uma boa arquitetura é:
UI ───────────┐
├── Caso de uso / lógica de negócios ── Repositório
AppFunctions ─┘Ambas as interfaces devem convergir na mesma camada de domínio.
Isso reduz duplicações e torna o comportamento mais consistente.
Conclusão
Neste primeiro artigo, vimos como as AppFunctions interagem com o sistema operacional Android e com sua aplicação. Compreendemos que é uma maneira mais determinística e otimizada de controlar apps. As AppFunctions dão aos desenvolvedores do Android a granularidade para escolher quais funções eles querem expor ao Sistema Agêntico. No próximo artigo, veremos como as AppFunctions podem ser disruptivas para o modelo de negócios dos aplicativos Android e como se preparar e adaptar.

