<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://runixo.malditainternet.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://runixo.malditainternet.com/" rel="alternate" type="text/html" /><updated>2025-06-21T14:27:34+00:00</updated><id>https://runixo.malditainternet.com/feed.xml</id><title type="html">runixo - el blog</title><subtitle>Blog personal, post ida de twitter, buscando un espacio donde escribir mis cosas del mundo computadoras.</subtitle><entry><title type="html">ADK Hackathon</title><link href="https://runixo.malditainternet.com/2025/06/20/adk-hackathon.html" rel="alternate" type="text/html" title="ADK Hackathon" /><published>2025-06-20T00:00:00+00:00</published><updated>2025-06-20T00:00:00+00:00</updated><id>https://runixo.malditainternet.com/2025/06/20/adk-hackathon</id><content type="html" xml:base="https://runixo.malditainternet.com/2025/06/20/adk-hackathon.html"><![CDATA[<h1 id="el-hackathon-de-agent-development-kit">El Hackathon de Agent Development Kit</h1>

<p>Como escribí antes, todavía no quiero hacer una empresa de IA, por eso el <a href="https://googlecloudmultiagents.devpost.com/?utm_source=gamma&amp;utm_medium=email&amp;utm_campaign=FY25-Q2-NORTHAM-GOO34096-onlineevent-su-ADKHackathon&amp;utm_content=innovators-newsletter&amp;utm_term=-">hackathon de ADK</a> me vino bien: vamos a jugar con esto, vamos a hacer algo que “parezca en serio” #adkhackathon</p>

<h2 id="agent-development-kit">Agent Development Kit</h2>
<p><a href="https://google.github.io/adk-docs/">ADK es una lib open source de google</a> para ‘hacer agentes’. Está bueno que muchos casos están contemplados entonces rápidamente se pueden hacer cosas:</p>
<ul>
  <li>agentes que tienen <a href="https://google.github.io/adk-docs/agents/multi-agents/">sub-agentes</a>; que pueden ser llamados ‘cuando hagan falta’ <a href="https://google.github.io/adk-docs/agents/workflow-agents/">o secuencialmente o en paralelo.</a></li>
  <li><a href="https://google.github.io/adk-docs/tools/">herramientas de diversas</a> fuentes: podés definir herramientas con funciones en código ó importar las herramientas que ofrecen servers MCP ó usar herramientas de LangChain ó usar herramientas built in (<code class="language-plaintext highlighter-rouge">google_search</code>, la mejor de todas)</li>
  <li><a href="https://google.github.io/adk-docs/callbacks/">callbacks donde meter código</a> (para poder decir: “esta parte la hace la LLM, pero después, el resultado, lo vamos a filtrar a traves de este pedazo de código viejo y confiable”)</li>
  <li>artifacts: archivos binarios que generan los agentes y que le van a interesar al usuario, etc.</li>
  <li><a href="https://google.github.io/adk-docs/deploy/">deployment en GCP</a>: yo me siento cómodo en GCP, así que tener una manera sencillita de deployear esto me puso contento</li>
</ul>

<h2 id="qué-hice">Qué hice</h2>
<p>Como quería probar la parte ‘desconocida’, decidí atacar un problema que ya conocía, que sé que APIs hay disponibles, que conozco como usan, etc.</p>

<p>Hice un “real estate AI agent” que hace una tarea que los agentes inmobiliarios aprecian mucho: busca comparables.</p>

<p>Para tasar una propiedad es interesante encontrar propiedades ‘similares’ que esten actualmente publicadas o que hayan estado en el pasado cercano.</p>

<p>En ‘similares’ está el secreto: muchas veces no hay algo <em>idéntico</em> entonces hay que buscar cosas que sean parecidas; y ahí está el arte: si dos casas tienen la misma cantidad de dormitorios, baños y superficie similar, pero están a kilómetros de distancia; son comparables o no? Si dos casas están pegadas PERO son muy distintas, son comparables o no?</p>

<h2 id="cómo-lo-hice">Cómo lo hice</h2>
<p>Hay una orden que es bastante secuencial y donde no hay mucho espacio para la ‘creatividad’:</p>
<ol>
  <li>En base a una dirección, hay que georeferenciarla y normalizarla (usando el MCP de Google Maps)</li>
  <li>Buscar datos de la propiedad en Google (usando una herramienta built in llamada <code class="language-plaintext highlighter-rouge">google_search</code>)</li>
  <li>Buscar los comparables (usando unas herramientas definidas con código que llaman a un API de búsqueda de propiedades)</li>
  <li>Generar un reporte.</li>
</ol>

<p>Para esto, hay un coso muy piola llamado SequentialAgent que permite llamarlos en orden:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">root_agent</span> <span class="o">=</span> <span class="n">SequentialAgent</span><span class="p">(</span>
  <span class="n">name</span><span class="o">=</span><span class="s">"real_estate_agent_comparables"</span><span class="p">,</span>
  <span class="n">description</span><span class="o">=</span><span class="s">"A real estate agent who can find comparables for a base property"</span><span class="p">,</span>
  <span class="n">sub_agents</span><span class="o">=</span><span class="p">[</span><span class="n">gmaps_agent</span><span class="p">,</span> <span class="n">google_search_agent</span><span class="p">,</span> <span class="n">api_search_agent</span><span class="p">,</span> <span class="n">report_writer_agent</span><span class="p">],</span>
<span class="p">)</span>
</code></pre></div></div>

<p>El agente <code class="language-plaintext highlighter-rouge">gmaps_agent</code> importa las herramientas de un server <a href="https://github.com/modelcontextprotocol/servers/tree/2025.4.24/src/google-maps">MCP de Google Maps</a> y le agrega algunas <a href="https://google.github.io/adk-docs/agents/llm-agents/#guiding-the-agent-instructions-instruction">instrucciones</a> tipo <code class="language-plaintext highlighter-rouge">instruction='Georeference and normalize addresses',</code></p>

<p>El <code class="language-plaintext highlighter-rouge">google_search_agent</code> es lo que me parece que le da un valor <em>enorme</em> a ADK: hace búsquedas en google y extrae datos de los documentos resultantes.  Lo uso especialmente para buscar datos importantes sobre las propiedades que en general no están tabulados. Es lo que hace un humano: ni bien le das una dirección, la googlea y mira “a ver que onda”</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span>  <span class="nn">google.adk.tools</span>  <span class="kn">import</span>  <span class="n">google_search</span>

<span class="n">root_agent</span> <span class="o">=</span> <span class="n">Agent</span><span class="p">(</span>
<span class="n">name</span><span class="o">=</span><span class="s">"basic_search_agent"</span><span class="p">,</span>
<span class="n">model</span><span class="o">=</span><span class="s">"gemini-2.0-flash"</span><span class="p">,</span>
<span class="n">description</span><span class="o">=</span><span class="s">"Agent to find property information using Google Search."</span><span class="p">,</span>
<span class="n">instruction</span><span class="o">=</span><span class="s">"""Search websites for information about the base property.
For the property sited EXACTLY in the address; ignore similar addresses.
For each property datum, please cite the source.
Find last sold date and price; property features (like pool, garden, shed; renovations done or needed, etc).
Other information that could be useful: robberies, murders, fires,etc.
Don't assume anything, only return facts"""</span><span class="p">,</span>
<span class="n">output_key</span><span class="o">=</span><span class="s">"website_data"</span><span class="p">,</span>
<span class="n">tools</span><span class="o">=</span><span class="p">[</span><span class="n">google_search</span><span class="p">]</span>
<span class="p">)</span>
</code></pre></div></div>

<p>El <code class="language-plaintext highlighter-rouge">api_search_agent</code> está armado de funciones que van a pegarle al API; algunas cosas que encontré:</p>
<ul>
  <li>El API que uso soporta OData Filters (yo no sabía que era esto, aparentemente es un standard para hacer queries a una DB, como un WHERE de SQL). Se me ocurrió que por ahí la LLM (Gemini en este caso) iba a saber construir el query, así que se lo dejé a disposición: decidió no usarlo. En la <a href="https://cloud.google.com/vertex-ai/generative-ai/docs/multimodal/function-calling#write_clear_and_detailed_function_names_parameter_descriptions_and_instructions">documentación de Vertex recomiendan usar parámetros sencillos y concretos.</a></li>
  <li>Así que terminé creando muchos parámetros de <code class="language-plaintext highlighter-rouge">bathrooms_min</code> y <code class="language-plaintext highlighter-rouge">bathrooms_max</code>; que terminan escribiendo el query de OData que usa luego el API para filtrar.</li>
</ul>

<h2 id="el-deploy">El Deploy</h2>
<p>Para deployearlo, lo hice a Cloud Run; que en principio parecía muy práctico; pero me di cuenta que el Dockerfile que escribía no permitía incorporar dependencias del OS (ej, yo necesitaba Node para poder correr el MCP de Google Maps). <a href="https://github.com/google/adk-python/pull/1524">Hice un PR para esto</a>.</p>

<h2 id="lo-que-todavía-no-usé">Lo que (todavía) no usé</h2>
<ul>
  <li>Hay toda una parte de APIs en real-time; entiendo que para audio y video que dejé sin usar</li>
  <li>Hay un servicio de GCP llamado AgentEngine que se usa para deployear agentes (yo hice deploy en Google Cloud Run)</li>
</ul>

<h2 id="las-preguntas-que-me-quedan">Las preguntas que me quedan</h2>

<p>Por qué cuando pensamos en “agentes” la UI que nos aparece es la de “un chat”? Es esta la mejor UI o es que todavía no se nos ocurrió algo mejor?</p>

<p>No sería interesante tener “una AI que haga UIs” para que arme la mejor UI posible para:</p>
<ul>
  <li>la interacción a desarrollar</li>
  <li>el tipo de usuario</li>
  <li>el dispositivo del usuario</li>
</ul>

<p>Por ejemplo, cuando una AI te pregunta si querés hacer “A” o “B”, yo me siento medio tonto escribiendo “B”. Preferiría que ahí me muestre un botón; aunque es verdad que uno podría contestarle: “Quiero que hagas B pero que tomes esta idea de A que me parece útil”</p>]]></content><author><name></name></author><summary type="html"><![CDATA[El Hackathon de Agent Development Kit]]></summary></entry><entry><title type="html">La IA</title><link href="https://runixo.malditainternet.com/ia/2025/06/13/la-ia.html" rel="alternate" type="text/html" title="La IA" /><published>2025-06-13T16:13:25+00:00</published><updated>2025-06-13T16:13:25+00:00</updated><id>https://runixo.malditainternet.com/ia/2025/06/13/la-ia</id><content type="html" xml:base="https://runixo.malditainternet.com/ia/2025/06/13/la-ia.html"><![CDATA[<h2 id="mi-relación-con-la-ai">Mi relación con la AI</h2>

<p>Yo ‘trabajo con computadoras’ hace 25 años: vi aparecer y consolidarse Linux como OS de servers indiscutido, trabajé en la ‘burbuja .com’ del 2000, vi nacer y crecer bittorrent; los sistemas descentralizados y distribuidos de en serio, viví como la virtualización de hardware pasó a ser algo realmente usable y el comienzo los servicios de cloud en 2006; luego las aparición de computadoras baratas (raspi, netbooks) en 2012 y después, por muchos años no pasó nada.</p>

<p>Bueno, en realidad, no pasó nada que <em>me emocione</em>, porque crypto nunca me enganchó. Mis reacciones más bien eran: “oh, que curiosidad”, “mirá que piola, una db distribuida”, “¿para qué lo podríamos usar?”
(algunas preguntas se contestaron: 
	- para que lo podríamos usar? 
	- transferir plata
	- re piola, muy útil, copado! 
)</p>

<p>Entonces, <em>para mí</em>, en las últimas décadas de las computadoras, no pasó nada disruptivo; hasta que llegó la AI. Y esto sí me parece poderoso, que cambia  el juego y que esta al alcance de todos. 
Con un montón de incertidumbres, con montón de riesgos y aún así, fascinante.</p>

<p>Se mueve todo tan rápido que da miedo y siento que no es todavía el momento de hacer <em>una empresa con AI</em>; sino que es el momento de skillear, de aprender como se usa, para que sirve, cuales son los límites, por donde viene la mano. 
Un acercamiento más lúdico, exploratorio, sin compromisos.</p>]]></content><author><name></name></author><category term="ia" /><summary type="html"><![CDATA[Mi relación con la AI]]></summary></entry><entry><title type="html">Bienvenidxs a este blog</title><link href="https://runixo.malditainternet.com/2025/06/10/bienvenidxs.html" rel="alternate" type="text/html" title="Bienvenidxs a este blog" /><published>2025-06-10T17:28:55+00:00</published><updated>2025-06-10T17:28:55+00:00</updated><id>https://runixo.malditainternet.com/2025/06/10/bienvenidxs</id><content type="html" xml:base="https://runixo.malditainternet.com/2025/06/10/bienvenidxs.html"><![CDATA[<h1 id="quién-soy-yo-que-hago-acá">quién soy yo, que hago acá</h1>

<p>yo: Hola, soy Martín (aka @runixo) y pasé 17 años en twitter. hace unos meses que dejé
grupo: Hola Martin</p>

<p>Desde hace un tiempo que siento que me falta un lugar donde decir las cosas que pienso del mundo computadoras.
Antes, Twitter era ese espacio para mí; ahora me fuí: ahí mismo aprendimos que un bar nazi no es el lugar donde uno quiere estar.</p>

<p>Entonces, voy a intentar esto; un espacio donde nadie espere nada de mí y cuando yo tenga ganas/tiempo/necesidad venga y escriba.</p>

<p>Todo esto estará hecho por gusto, ganas de compartir, sin presión. Empieza en este formato más bien rudimentario, quizás se convierta en algo mejor.</p>

<p>Veremos</p>]]></content><author><name></name></author><summary type="html"><![CDATA[quién soy yo, que hago acá]]></summary></entry></feed>