Volver al blog

DSPy + Scrapeless: Da vida a tu programa DSPy con herramientas web a través de MCP

Alex Johnson
Alex Johnson

Senior Web Scraping Engineer

22-Jul-2026

Resumen:

  • DSPy convierte las herramientas del Servidor MCP de Scrapeless en objetos dspy.Tool con dspy.Tool.from_mcp_tool, dotando a un programa DSPy de las 21 herramientas web, desde scrape_markdown hasta un conjunto completo de navegador.
  • Cada herramienta convertida está vinculada a una mcp.ClientSession activa, por lo que las herramientas solo funcionan mientras esa sesión esté abierta; mantén todo el flujo dentro de un bloque async with ClientSession(...).
  • Convertir las herramientas y llamar a una directamente con acall se ejecuta sin modelo de lenguaje configurado; solo la ejecución de dspy.ReAct necesita un LM.
  • dspy.Tool.from_mcp_tool(session, tool) toma la sesión y una herramienta MCP y devuelve una herramienta DSPy que puedes llamar o pasar a un módulo.
  • Una llamada directa a scrape_markdown devuelve la página en formato Markdown, lista para alimentar a una firma DSPy.
  • Comienza en el plan gratuito de Scrapeless y otorga a tu programa DSPy herramientas web reales.

DSPy se basa en una idea diferente a la de la mayoría de los marcos de agentes: declaras lo que deseas con una firma y dejas que DSPy maneje la solicitud. Las herramientas encajan bien en ese modelo, pero DSPy no incluye una forma de acceder a la web en vivo. El Protocolo de Contexto del Modelo lo proporciona. Convierte las herramientas de un servidor MCP en herramientas DSPy y un módulo dspy.ReAct puede llamarlas de la misma manera que llama a cualquier otra herramienta.

Esta guía conecta DSPy al Servidor MCP de Scrapeless, convierte sus 21 herramientas, llama a una por real y muestra dónde se necesita una clave de modelo de lenguaje. La conversión y la llamada directa se verifican contra el servidor en vivo; la ejecución del módulo se marca como el único requisito que necesita.

Por qué Scrapeless MCP

El Servidor MCP de Scrapeless expone herramientas de raspado web y de navegador que un agente puede llamar directamente, por lo que la capa de raspado no es algo que construyas u hospedes. Una conexión sirve 21 herramientas: scrape_markdown y scrape_html para contenido, google_search y google_trends para datos de búsqueda, scrape_screenshot para capturas, y un conjunto completo de browser_* que controla un navegador en la nube. DSPy hace puente a todas ellas a través de dspy.Tool.from_mcp_tool, que convierte cada herramienta MCP en una herramienta DSPy nativa.

Las herramientas browser_* controlan el navegador en la nube de Scrapeless, por lo que un programa puede navegar por una página interactiva y leer lo que se renderiza, todo en la infraestructura de Scrapeless. Para la vista del protocolo del mismo servidor, la guía de integración de MCP cubre cómo se conectan los clientes MCP en general.

Requisitos previos

  • Python 3.10 o posterior.
  • Una clave API de Scrapeless desde el panel de control, exportada como SCRAPELESS_API_KEY.
  • Una clave de modelo de lenguaje (como OPENAI_API_KEY) solo para la ejecución de dspy.ReAct. Convertir y llamar a las herramientas no necesita una.

Instalación

Instala DSPy y la biblioteca cliente MCP.

bash Copy
pip install dspy mcp

Establece tu clave Scrapeless en el shell. Usa la clave real en tiempo de ejecución y mantén el marcador de posición fuera de tu código fuente.

bash Copy
export SCRAPELESS_API_KEY="sk_tu_clave_aquí"

Abrir una Sesión y Convertir las Herramientas

El puente MCP de DSPy funciona en una sesión activa. Abre una conexión HTTP transmitible, envuélvela en un mcp.ClientSession, inicialízala, lista las herramientas del servidor y convierte cada una con dspy.Tool.from_mcp_tool. La clave Scrapeless va en el encabezado x-api-token.

python Copy
import asyncio
import os

import dspy
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client


async def main() -> None:
    async with streamablehttp_client(
        "https://api.scrapeless.com/mcp", headers={"x-api-token": os.environ["SCRAPELESS_API_KEY"]}
    ) as (read, write, _):
        async with ClientSession(read, write) as session:
            await session.initialize()
            mcp_tools = (await session.list_tools()).tools
            tools = [dspy.Tool.from_mcp_tool(session, t) for t in mcp_tools]
            names = sorted(t.name for t in tools)
            print("herramientas dspy:", len(tools))
            print("herramientas:", ", ".join(names))


asyncio.run(main())

El servidor en vivo produce 21 herramientas DSPy, convertidas sin un modelo de lenguaje configurado.

text Copy
herramientas dspy: 21
herramientas: browser_click, browser_close, browser_create, browser_get_html, browser_get_text, browser_go_back, browser_go_forward, browser_goto, browser_press_key, browser_screenshot, browser_scroll, browser_scroll_to, browser_snapshot, browser_type, browser_wait, browser_wait_for, google_search, google_trends, scrape_html, scrape_markdown, scrape_screenshot

Cada herramienta convertida contiene una referencia a session, que es la razón por la que la conversión y todo lo que usa las herramientas permanece dentro del bloque async with ClientSession(...). Cierra la sesión y las herramientas dejan de funcionar. La capa de transporte y la de mensajes siguen la especificación del Protocolo de Contexto del Modelo, que se basa en la especificación JSON-RPC 2.0.

Llamar a una herramienta

Una herramienta DSPy se puede invocar por sí sola, por lo que puedes ejecutar una antes de construir un módulo. acall invoca la herramienta con argumentos de palabra clave y devuelve su resultado.

python Copy
import asyncio
import os

import dspy
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client


async def main() -> None:
    async with streamablehttp_client(
        "https://api.scrapeless.com/mcp", headers={"x-api-token": os.environ["SCRAPELESS_API_KEY"]}
    ) as (read, write, _):
        async with ClientSession(read, write) as session:
            await session.initialize()
            mcp_tools = (await session.list_tools()).tools
            tools = [dspy.Tool.from_mcp_tool(session, t) for t in mcp_tools]
            scrape_markdown = next(t for t in tools if t.name == "scrape_markdown")
            result = await scrape_markdown.acall(url="https://quotes.toscrape.com/")
            text = result if isinstance(result, str) else str(result)
            print("caracteres en markdown:", len(text))
            print("contiene una cita:", "El mundo tal como lo hemos creado" in text)


asyncio.run(main())

La llamada devuelve la página como Markdown, y la verificación del contenido confirma que hay una cita real presente.

text Copy
caracteres en markdown: 4308
contiene una cita: True

Llamar a una herramienta directamente es la forma más rápida de confirmar la conexión e inspeccionar lo que devuelve una herramienta, y es el mismo objeto que llamará un módulo. La documentación de DSPy cubre herramientas, firmas y módulos en su totalidad.

Integrar las herramientas en un módulo

dspy.ReAct toma una firma y una lista de herramientas y ejecuta el bucle de razonar-actuar. Este es el paso que necesita un modelo de lenguaje: configura uno con dspy.configure, luego deja que el módulo decida cuándo llamar a scrape_markdown o cualquier otra herramienta. Debido a que las herramientas están vinculadas a la sesión, el módulo se ejecuta dentro del mismo bloque async with ClientSession(...) que las convirtió.

Nota: dspy.configure(lm=...) y la ejecución de dspy.ReAct necesitan una clave de modelo de lenguaje como OPENAI_API_KEY, que no está establecida aquí. Convertir las 21 herramientas y la llamada directa a scrape_markdown anterior se ejecutan sin ella. Este bloque se muestra con su forma exacta; solo el recorrido del modelo es una brecha de prerequisito.

python Copy
# dentro del bloque `async with ClientSession(...)`, después de convertir `tools`
dspy.configure(lm=dspy.LM("openai/gpt-4o"))
agent = dspy.ReAct("pregunta -> respuesta", tools=tools)
result = await agent.acall(
    pregunta="Fetch https://quotes.toscrape.com/ and list the first three quotes with their authors."
)
print(result.answer)

En tiempo de ejecución, el módulo lee la firma, llama a scrape_markdown para obtener la página, razona sobre el Markdown que la llamada directa ya demostró, y llena el campo answer. Las herramientas son los mismos objetos, ya sea que las llame el módulo o tú.

Conclusión

DSPy más el Servidor MCP de Scrapeless mantiene el estilo declarativo de DSPy mientras añade un alcance web real. dspy.Tool.from_mcp_tool convierte las 21 herramientas, acall prueba que una funciona, y dspy.ReAct las convierte en un programa en ejecución. La única regla a recordar es que las herramientas viven en la sesión, así que mantén el flujo dentro de un bloque de sesión y solo la ejecución del módulo necesita una clave de modelo. Comienza con los scripts anteriores, limita las herramientas a lo que necesita tu firma y deja que DSPy haga el prompting.

Crea una cuenta gratuita en Scrapeless para obtener una clave API, y revisa los precios de Scrapeless cuando planees un programa recurrente.

Preguntas Frecuentes

P: ¿Necesita DSPy un modelo de lenguaje para cargar herramientas MCP?

No. Abrir la sesión, listar las herramientas, convertirlas con dspy.Tool.from_mcp_tool, y llamar a una con acall se ejecutan solo con la clave API de Scrapeless. Una clave de modelo de lenguaje solo es necesaria para dspy.ReAct, cuando el módulo mismo decide qué herramientas llamar.

P: ¿Por qué debe permanecer el código dentro de un bloque ClientSession?

dspy.Tool.from_mcp_tool vincula cada herramienta a la mcp.ClientSession que le pasas, por lo que las herramientas emiten sus llamadas a través de esa sesión. Una vez que sale el bloque async with ClientSession(...), la sesión se cierra y las herramientas ya no pueden funcionar, por lo que convertir y usar las herramientas pertenece al mismo bloque.
Q: ¿En qué se diferencia la integración MCP de DSPy de los marcos de adaptadores?

DSPy convierte herramientas desde una mcp.ClientSession en bruto con dspy.Tool.from_mcp_tool, en lugar de a través de un adaptador de nivel superior que gestiona la conexión por ti. La compensación es el control explícito de la duración de la sesión a cambio de una dependencia menos, y mantiene las herramientas como objetos ordinarios de dspy.Tool.

Q: ¿Cómo puedo llamar a una herramienta sin construir un módulo?

Cada herramienta convertida es callable con acall y argumentos de palabra clave, por lo que await scrape_markdown.acall(url="...") devuelve el resultado de la herramienta directamente. Esto es útil para confirmar la conexión e inspeccionar la salida antes de envolver las herramientas en un módulo dspy.ReAct.

Q: ¿Cómo le doy a un módulo solo algunas de las herramientas?

from_mcp_tool se ejecuta por herramienta, así que construye la lista de tools solo con las herramientas MCP que deseas, o filtra la lista convertida antes de pasarla a dspy.ReAct. Entregar a un módulo solo scrape_markdown y google_search es más seguro que el conjunto completo de 21 herramientas cuando la tarea solo necesita contenido y búsqueda.

Q: ¿La extracción a través de las herramientas está sujeta a las normas del objetivo?

Sí. Las herramientas obtienen páginas públicas, y sigues siendo responsable de respetar los términos de cada objetivo y sus directrices del Protocolo de Exclusión de Robots. Mantén el volumen limitado y los datos públicos, y delimita el módulo a las herramientas que la tarea realmente necesita.

En Scrapeless, solo accedemos a datos disponibles públicamente y cumplimos estrictamente con las leyes, regulaciones y políticas de privacidad del sitio web aplicables. El contenido de este blog es sólo para fines de demostración y no implica ninguna actividad ilegal o infractora. No ofrecemos garantías y renunciamos a toda responsabilidad por el uso de la información de este blog o enlaces de terceros. Antes de realizar cualquier actividad de scraping, consulte a su asesor legal y revise los términos de servicio del sitio web de destino u obtenga los permisos necesarios.

Artículos más populares

Catalogar