La comunicación entre sistemas es uno de los problemas más importantes que se tratan en la ciencia de la computación. Durante la historia se han desarrollado diversos formalismos para representar las propiedades de la comunicación entre sistemas concurrentes. Quizás el problema caracterÃstico en la comunicación de sistemas concurrentes es la sincronización de múltiples procesos, que fue estudiado profundamente en los años 70s y 80s. Esencialmente, dos agentes necesitan sincronizarse si existe la posibilidad de que puedan interferir el uno con el otro en modo destructivo. El clásico ejempo de interferencia es la actualización de datos. Por ejemplo, tenemos dos agentes a1 y a2, y ambos tienen acceso a una variable v. Supongamos que la variable v almacena el saldo de una cuenta determinada. Imaginemos que el agente a1 compra un producto y necesita actualizar el valor de v. El proceso de actualización se puede dividir en tres subprocesos: lectura, tratamiento de datos y escritura. Por ejemplo, si el valor de v = 30 euros, y compramos un producto que cuesta 5 euros, leeremos el valor actual de v (30 euros), haremos el tratamiento de datos que consistirá en comparaciones, consultas, operaciones aritméticas…, en nuestro ejemplo se reducirá simplemente a una resta. Por lo tanto harÃamos la siguiente operación aritmética: 30 – 5 euros = 25 euros, y escribirÃamos el valor resultante (25 euros) en la variable . Si mientras el agente a1 está realizando la compra, el agente a2 necesita realizar una compra en el mismo instante cuando lea el valor de la variable v no será real, ya que al agente a1 no le habrá dado tiempo de modificar el valor real. La problema de pérdida de datos al actualizar es una cuestión bastante común a tratar en aplicaciones que se comunican a través de estructuras compartidas.
SI no tratamos la comunicación a bajo nivel, ¿entonces como tratan los agentes las comunicaciones? Supongamos que tenemos un sistema programado en Java que contiene dos objetos a y b, y que a tiene disponible un método público llamado x. El objeto b puede comunicarse con a invocando el método x. En Java, significarÃa que b ejecuta una instrucción algo como a.x(arg), donde arg es el argumento que b quiere comunicar al objeto a. La cuestión está en cual es el objeto que toma la decisión de ejecutar el método x. ¿El objeto a o el objeto b? En este ejemplo a no tiene control en la ejecución de x, la decisión es completamente del objeto b.
Ahora vamos a considerar un ejemplo similar, pero en usando agentes. Tenemos dos agentes llamados i< /em> y j, en el cual i tiene la capacidad de efectuar una acción α (una acción es análoga a un método). No hay un concepto formal que diga que el agente j invoque una método en i. Esto es porque i es un agente autónomo: tiene control sobre su estado y su comportamiento. No puede ser ordenado por otro agente a realizar una determinada acción. Es bastante diferente el proceso de ejecutar un método o una acción dependiendo de si estamos tratando con agentes o con aplicaciones orientadas a objetos.
En resumen, los agentes no pueden ser forzados por otros agentes para realizar una determinada acción, ni escribir datos en el estado interno de otros agentes. Sin embargo esto no significa que no puedan comunicarse. Ellos pueden efectuar acciones para intentar influenciar a otro agente. Por ejemplo, supongamos que digo “Está lloviendo en Cádiz”, siendo cierto. Bajo circustancias normales, una acción comunicativa intenta modificar las creencias de otro. Lógicamente pronunciando “Está lloviendo en Cádiz” no voy a convencer a todo el mundo de que es cierto. Tu tienes el control de tus propias creencias (deseos, intenciones, …). Puedes pensar que lo que estoy diciendo es verdad o es mentira, solo tu. Aún asÃ, cuando digo “Está lloviendo en Cádiz” estoy intentando cambiar tu estado interno. Además, desde el momento que pronuncio esa oración es una acción que estoy realizando, lo estoy haciendo para un propósito: intentar hacer que creas que realmente está lloviendo en Cádiz.