Chamadas de ferramentas do LangChain usando o Granite-3.0-8B-Instruct no Python com o watsonx.ai

Autor

Anna Gutowska

AI Engineer, Developer Advocate

IBM

Neste tutorial, usaremos ferramentas do LangChain criadas previamente para um agente ReAct demonstrar sua capacidade de diferenciar os casos de uso apropriados para cada ferramenta. Usaremos principalmente o pacote LangChain Python de código aberto.

Qual é a chamada da ferramenta?

A chamada de ferramentas, também conhecida como chamada de função, é a interface que permite que agentes de inteligência artificial (IA) trabalhem em tarefas específicas que exigem informações atualizadas, que de outra forma não estariam disponíveis para os grandes modelos de linguagem (LLMs) treinados. LLMs, como os modelos IBM® Granite ou os modelos GPT (generative pre-trained transformer) da OpenAI, têm acesso apenas às informações usadas no treinamento. Há muitas ferramentas padrão acessíveis por meio do LangChain, incluindo uma ferramenta para trabalhar com consultas de SQL database, acessar informações na Wikipedia e muito mais. Incentivamos você a ler a documentação do LangChain para obter uma lista abrangente de ferramentas criadas previamente.

As ferramentas personalizadas podem ser definidas usando vários métodos, incluindo o uso do decorador @tool ou Runnables do LangChain, que abordaremos neste tutorial. Ferramentas assíncronas podem ser criadas usando as classes StructuredTool ou BaseTool. Para ver as diferenças entre cada abordagem, incentivamos você a consultar a documentação oficial do LangChain. Consulte o tutorial de chamadas de função da IBM para obter exemplos de ferramentas personalizadas.

Incentivamos você a verificar nossa explicação de agentes de IA para obter uma visão geral detalhada dos vários tipos de agentes de IA e como eles diferem dos chatbots de LLMs tradicionais.

Pré-requisitos

Você precisa de uma conta do IBM® Cloud.

Etapas

Etapa 1. Configure seu ambiente

Embora você possa escolher entre várias ferramentas, este tutorial explica como configurar uma conta da IBM para usar um Jupyter Notebook.

  1. Faça login no watsonx.ai usando sua conta do IBM Cloud.

  2. Criar um projeto do watsonx.ai.

    Você pode obter a ID do projeto a partir de seu projeto. Clique na guia Gerenciar. Em seguida, copie a ID do projeto da seção Detalhes da página Geral. Você precisa dessa ID para este tutorial.

  3. Crie um Jupyter Notebook.

    Essa etapa abrirá um ambiente do Notebook onde você poderá copiar o código deste tutorial. Ou então, você pode baixar esse Notebook em seu sistema local e carregá-lo como um ativo em seu projeto do watsonx.ai. Para ver mais tutoriais do Granite, consulte a Comunidade IBM Granite. Este tutorial também está disponível no Github.

Etapa 2. Configure uma instância do watsonx.ai Runtime e uma chave de API

  1. Crie uma instância do serviço do watsonx.ai Runtime (selecione a região apropriada e escolha o plano Lite, que é uma instância gratuita).

  2. Gere uma chave de API.

  3. Associe a instância do serviço do watsonx.ai Runtime ao projeto que você criou no watsonx.ai.

Etapa 3. Instale e importe bibliotecas relevantes e configure suas credenciais

Precisamos de algumas bibliotecas e módulos para este tutorial. Certifique-se de importar os seguintes e, se eles não estiverem instalados, você pode resolver isso com uma instalação rápida cpm pip. LangChain e LangGraph serão os frameworks e toolkits de desenvolvedor utilizados.

Nota: Este tutorial foi criado no Python 3.11.9 e também é compatível com o Google Colab, que utiliza o Python 3.10.12. Para verificar sua versão do Python, você pode executar o comando !python --version  em uma célula de código.

#installations
!pip install -q langchain \
    "langchain_community<0.3.0" \
    langgraph \
    youtube_search \
    pyowm \
    ionic-langchain \
    python-dotenv

!pip install -qU langchain-ibm
#imports
import os

from langchain_ibm import ChatWatsonx
from langgraph.prebuilt import create_react_agent
from langchain_core.tools import Tool
from langchain_core.messages import HumanMessage
from langchain_community.tools import YouTubeSearchTool
from langchain_community.utilities import OpenWeatherMapAPIWrapper
from ionic_langchain.tool import IonicTool
from dotenv import load_dotenv

load_dotenv(os.getcwd()+"/.env", override=True)

Para definir nossas credenciais, precisamos do WATSONX_APIKEY e do WATSONX_PROJECT_ID que você gerou na etapa 1. Você pode armazená-los em um arquivo .env  no seu diretório ou substituir o texto do espaço reservado. Também definiremos a URL como o endpoint da API.

WATSONX_APIKEY = os.getenv('WATSONX_APIKEY', "<WATSONX_APIKEY_HERE>")
WATSONX_PROJECT_ID = os.getenv('WATSONX_PROJECT_ID', "<WATSONX_PROJECT_ID_HERE>")
URL = "https://us-south.ml.cloud.ibm.com"

A ferramenta de clima usada neste tutorial exige uma chave de API do OpenWeather. Para gerar uma, crie uma conta do OpenWeather. Ao criar uma conta, selecione a guia "Chaves de API" para exibir sua chave gratuita.

OPENWEATHERMAP_API_KEY = os.getenv('OPENWEATHERMAP_API_KEY', "<OPEN_WEATHERMAP_API_KEY_HERE>")

Etapa 4. Inicialize o LLM

Para este tutorial, utilizaremos o wrapper ChatWatsonx para definir nosso modelo de chat. Esse wrapper simplifica a integração da chamada e do encadeamento de ferramentas. Usaremos o modelo granite-3-8b-instruct . Incentivamos você a usar as referências de API na documentação do ChatWatsonx  para obter mais informações.

Para inicializar o LLM, precisamos definir os parâmetros do modelo. É importante configurar a temperatura do modelo aqui para limitar as alucinações do agente.

llm = ChatWatsonx(
    model_id="ibm/granite-3-8b-instruct",
    url = URL,
    apikey = WATSONX_APIKEY,
    project_id = WATSONX_PROJECT_ID,
    params = {
        "decoding_method": "greedy",
        "temperature": 0,
        "min_new_tokens": 5,
        "max_new_tokens": 2000
    }
)

Etapa 5. Estabeleça as ferramentas integradas

Podemos usar a classe Tool para tornar nossas ferramentas chamáveis. Também é importante uma descrição clara e simples da ferramenta. Além disso, o atributo booleano return_direct  determina se a resposta da ferramenta deve ser retornada diretamente ao usuário. Por último, o atributo opcional args_schema  do tipo pydantic.BaseModel  é usado para fornecer informações adicionais ou validação para o modelo.

Vamos imaginar que você está planejando suas próximas férias na Grécia e está ansioso para saber mais sobre o país e se preparar para a viagem. Primeiro, vamos configurar a ferramenta meteorológica integrada do LangChain. A ferramenta usa o OpenWeatherMapAPIWrapper,  que usa a OPENWEAtherMAP_API_KEY  que geramos anteriormente.

weather = OpenWeatherMapAPIWrapper(openweathermap_api_key=OPENWEATHERMAP_API_KEY)

weather_search = Tool(
    name="weather_search",
    description="Get weather for a city and country code, e.g. Athens, GR",
    func=weather.run,
)

Em seguida, vamos configurar a ferramenta criada previamente do YouTube usando o pacote YouTube Search disponível no LangChain. Essa etapa será útil para encontrar vídeos sobre seu destino de viagem.

youtube = YouTubeSearchTool()

youtube_search = Tool(
    name="youtube_search",
    description="Search YouTube for video links.",
    func=youtube.run,
)

Por último, vamos configurar uma ferramenta de compras online usando o Ionic. Essa ferramenta retorna itens relevantes para a consulta do usuário que estão à venda no mercado de comércio eletrônico.

ionic_search = IonicTool().tool()

Vamos definir nossa lista de várias ferramentas que fornecemos ao LLM. Também podemos imprimir a lista para ver como ela foi carregada. Para ver uma lista extensa de ferramentas do LangChain disponíveis, consulte a documentação do LangChain.

tools = [weather_search, youtube_search, ionic_search]
tools

Output:

[Tool(name='weather_search', description='Get weather for a city and country code, e.g. Athens, GR', func=<bound method OpenWeatherMapAPIWrapper.run of OpenWeatherMapAPIWrapper(owm=<pyowm.owm.OWM - API key=************************611450cc, subscription type=free, PyOWM version=(3, 3, 0)>, openweathermap_api_key='******************')>),

Tool(name='youtube_search', description='Search YouTube for video links.', func=<bound method BaseTool.run of YouTubeSearchTool()>),

Tool(name='ionic_commerce_shopping_tool', description='\nIonic is an e-commerce shopping tool...[abbreviated]', verbose=True, func=<bound method Ionic.query of <ionic_langchain.tool.Ionic object at 0x17f6e5510>>)] 

Etapa 6. Chamadas de ferramenta

A chamada da ferramenta normalmente se refere a um LLM que retorna o nome da ferramenta a ser chamada e seus argumentos. Podemos usar as informações extraídas para outros fins ou podemos chamar a ferramenta com esses argumentos. Para obter mais exemplos disso, consulte nosso tutorial de chamada de função .

Na verdade, executar a ferramenta e recuperar sua saída nem sempre está implícito. Neste tutorial, vamos explorar ambas as abordagens.

Retorne a ferramenta e os argumentos relevantes

Para realizar a chamada de ferramentas tradicional, podemos simplesmente fornecer uma consulta de usuário e usar o método bind_tools  criado previamente para transmitir a lista de ferramentas para o LLM em cada iteração.

llm_with_tools = llm.bind_tools(tools)
response = llm_with_tools.invoke([("human", "What are some youtube videos about greece")])
response

Output:

AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'chatcmpl-tool-7a15abba7d3c4419970d807ac0c8d353', 'type': 'function', 'function': {'name': 'youtube_search', 'arguments': '{"query": "greece"}'}}]}, response_metadata={'token_usage': {'completion_tokens': 21, 'prompt_tokens': 578, 'total_tokens': 599}, 'model_name': 'ibm/granite-3-8b-instruct', 'system_fingerprint': '', 'finish_reason': 'tool_calls'}, id='chat-5fe7a26b8f954c179c4995e873bff91e', tool_calls=[{'name': 'youtube_search', 'args': {'query': 'greece'}, 'id': 'chatcmpl-tool-7a15abba7d3c4419970d807ac0c8d353', 'type': 'tool_call'}], usage_metadata={'input_tokens': 578, 'output_tokens': 21, 'total_tokens': 599})

response.additional_kwargs

Output:

{'tool_calls': [{'id': 'chatcmpl-tool-7a15abba7d3c4419970d807ac0c8d353',
'type': 'function',
'function': {'name': 'youtube_search',
'arguments': '{"query": "greece"}'}}]}

Conforme visto na saída de tool_calls, o LLM identifica corretamente a chamada de ferramenta e os argumentos apropriados. O LLM não executa a ferramenta em si. Faremos isso na próxima etapa.

Execute a chamada da ferramenta e recupere sua saída

Para executar as chamadas de ferramentas, primeiro precisamos criar um agente ReAct usando o método auxiliar criado previamente create_react_agent  do LangGraph. Essa função cria um gráfico que serve como ponte entre o modelo de bate-papo e as ferramentas disponíveis, permitindo assim a chamada de ferramentas de agente. Esse gráfico é representado no diagrama a seguir.

Gráfico do agente ReAct
agent_executor = create_react_agent(llm, tools)

Agora podemos fazer perguntas ao agente que exigem uma chamada de ferramenta. Primeiro, podemos pedir ao modelo para retornar URLs para vídeos do YouTube sobre a Grécia. Podemos usar a classe HumanMessage  para transmitir a consulta do usuário para o LLM.

user_query = "What are some YouTube videos about Greece"
response = agent_executor.invoke({"messages": user_query})
response["messages"]

Output:

[HumanMessage(content='What are some YouTube videos about Greece', additional_kwargs={}, response_metadata={}, id='1adba6c0-32e6-4bbd-92a6-7d21b0177439'),
AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'chatcmpl-tool-b4b5bf452404424ba4d6d9c26e53c6ce', 'type': 'function', 'function': {'name': 'youtube_search', 'arguments': '{"query": "Greece"}'}}]}, response_metadata={'token_usage': {'completion_tokens': 22, 'prompt_tokens': 578, 'total_tokens': 600}, 'model_name': 'ibm/granite-3-8b-instruct', 'system_fingerprint': '', 'finish_reason': 'tool_calls'}, id='chat-5f41aee6736842749285aa7fbff50f65', tool_calls=[{'name': 'youtube_search', 'args': {'query': 'Greece'}, 'id': 'chatcmpl-tool-b4b5bf452404424ba4d6d9c26e53c6ce', 'type': 'tool_call'}], usage_metadata={'input_tokens': 578, 'output_tokens': 22, 'total_tokens': 600}),
ToolMessage(content="['https://www.youtube.com/watch?v=waQY2Ucpbd0&pp=ygUGR3JlZWNl', 'https://www.youtube.com/watch?v=NMlBB2pK5qo&pp=ygUGR3JlZWNl']", name='youtube_search', id='1ccf3137-2c10-495e-86ad-a548a3434243', tool_call_id='chatcmpl-tool-b4b5bf452404424ba4d6d9c26e53c6ce'),
AIMessage(content='Here are some YouTube videos about Greece:\n\n1. [Greece Travel Guide | Top 10 Tourist Attractions](https://www.youtube.com/watch?v=waQY2Ucpbd0&pp=ygUGR3JlZWNl)\n2. [Greece Travel Guide | Top 10 Tourist Attractions](https://www.youtube.com/watch?v=NMlBB2pK5qo&pp=ygUGR3JlZWNl)', additional_kwargs={}, response_metadata={'token_usage': {'completion_tokens': 117, 'prompt_tokens': 677, 'total_tokens': 794}, 'model_name': 'ibm/granite-3-8b-instruct', 'system_fingerprint': '', 'finish_reason': 'stop'}, id='chat-801e3b596a174ac88246b507c93e5869', usage_metadata={'input_tokens': 677, 'output_tokens': 117, 'total_tokens': 794})]

Ótimo! Conforme visto no AIMessage, o modelo identificou corretamente a chamada de ferramenta apropriada. No ToolMessage, vemos que o modelo retornou com sucesso a saída esperada usando a ferramenta integrada LangChain YouTube. Finalmente, o AIMessage  mostra que o LLM sintetizou a resposta da ferramenta.

Em seguida, vamos perguntar ao modelo sobre o clima na Grécia para determinar se ele chama a ferramenta weather_search  conforme o esperado.

user_query = "What is the weather in Athens, GR"
response = agent_executor.invoke({"messages": user_query})
response["messages"]

Output:

[HumanMessage(content='What is the weather in Athens, GR', additional_kwargs={}, response_metadata={}, id='a0c4b69c-988a-4f7d-9b8a-4780305f8e2a'),
AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'chatcmpl-tool-9a0c07a3b35f4c69a351c5540ab663f8', 'type': 'function', 'function': {'name': 'weather_search', 'arguments': '{"__arg1": "Athens, GR"}'}}]}, response_metadata={'token_usage': {'completion_tokens': 26, 'prompt_tokens': 579, 'total_tokens': 605}, 'model_name': 'ibm/granite-3-8b-instruct', 'system_fingerprint': '', 'finish_reason': 'tool_calls'}, id='chat-eeed087050e049f0ad715f3615c7fdda', tool_calls=[{'name': 'weather_search', 'args': {'__arg1': 'Athens, GR'}, 'id': 'chatcmpl-tool-9a0c07a3b35f4c69a351c5540ab663f8', 'type': 'tool_call'}], usage_metadata={'input_tokens': 579, 'output_tokens': 26, 'total_tokens': 605}),
ToolMessage(content='In Athens, GR, the current weather is as follows:\nDetailed status: few clouds\nWind speed: 4.47 m/s, direction: 23°\nHumidity: 58%\nTemperature: \n - Current: 15.15°C\n - High: 15.74°C\n - Low: 14.1°C\n - Feels like: 14.24°C\nRain: {}\nHeat index: None\nCloud cover: 20%', name='weather_search', id='587b0230-b667-41de-97b9-3779554d2559', tool_call_id='chatcmpl-tool-9a0c07a3b35f4c69a351c5540ab663f8'),
AIMessage(content='The current weather in Athens, GR is:\n- Detailed status: few clouds\n- Wind speed: 4.47 m/s, direction: 23°\n- Humidity: 58%\n- Temperature:\n - Current: 15.15°C\n - High: 15.74°C\n - Low: 14.1°C\n - Feels like: 14.24°C\n- Rain: None\n- Heat index: None\n- Cloud cover: 20%', additional_kwargs={}, response_metadata={'token_usage': {'completion_tokens': 125, 'prompt_tokens': 733, 'total_tokens': 858}, 'model_name': 'ibm/granite-3-8b-instruct', 'system_fingerprint': '', 'finish_reason': 'stop'}, id='chat-6719a5ca266a439bb10ed410db25c5ef', usage_metadata={'input_tokens': 733, 'output_tokens': 125, 'total_tokens': 858})]

O modelo foi capaz de discernir a ferramenta apropriada para chamar, executar a ferramenta com os argumentos extraídos, bem como sintetizar a produção da ferramenta. Agora, vamos pedir ao LLM algumas malas abaixo de US$ 100 para sua próxima viagem. Observe que a ferramenta foi projetada para pesquisar preços em centavos. Por isso, pedimos malas abaixo de 10.000 centavos nesse cenário, o equivalente a US$ 100.

user_query = "Find some suitcases for less than 10000"
response = agent_executor.invoke({"messages": user_query})
response["messages"]

Output:

[HumanMessage(content='Find some suitcases for less than 10000', additional_kwargs={}, response_metadata={}, id='8b207035-150a-4390-aff3-8b09ef85a592'),
AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'chatcmpl-tool-b011e718b18e41dcbcae2f7786af263d', 'type': 'function', 'function': {'name': 'ionic_commerce_shopping_tool', 'arguments': '{"__arg1": "suitcases, 10, 0, 10000"}'}}]}, response_metadata={'token_usage': {'completion_tokens': 41, 'prompt_tokens': 582, 'total_tokens': 623}, 'model_name': 'ibm/granite-3-8b-instruct', 'system_fingerprint': '', 'finish_reason': 'tool_calls'}, id='chat-e38c8568d1754636a6a92082561180bd', tool_calls=[{'name': 'ionic_commerce_shopping_tool', 'args': {'__arg1': 'suitcases, 10, 0, 10000'}, 'id': 'chatcmpl-tool-b011e718b18e41dcbcae2f7786af263d', 'type': 'tool_call'}], usage_metadata={'input_tokens': 582, 'output_tokens': 41, 'total_tokens': 623}),
ToolMessage(content='[{"products": [{"links": [{"text": "Details", "type": "pdp", "url": "https://go.ionic.click/Ch4CKd"}], "merchant_name": "Walmart", "merchant_product_id": "811277349", "name": "Zimtown Hardside Lightweight Spinner Orange 3 Piece Luggage Set with TSA Lock", "price": "$69.99", "status": "available", "thumbnail": "https://i5.walmartimages.com/asr/b809a274-ccc7-4ca4-b4f1-e848b4412fe6.314144bcd13e5467a33cb99e8dd5237c.jpeg?odnHeight=100&odnWidth=100&odnBg=ffffff", "brand_name": "Zimtown", "upc": "273109526768"}, {"links": [{"text": "Details", "type": "pdp", "url": "https://www.amazon.com/dp/B071HHX6VF?tag=ioniccommer00-20&linkCode=osi&th=1&psc=1"}], "merchant_name": "Amazon", "merchant_product_id": "B071HHX6VF", "name": "Amazon Basics Expandable Hardside Luggage, Suitcase with Wheels, 30-Inch Spinner with Four Spinner Wheels and Scratch-Resistant Surface, Black", "price": "$74.49", "status": "available", "thumbnail": "https://m.media-amazon.com/images/I/41jJcuMYSdL._SL160_.jpg", "brand_name": "Amazon Basics", "upc": "841710177190"}, .....[abbreviated],
AIMessage(content='Here are some suitcases that are less than 10000:\n\n1. [Zimtown Hardside Lightweight Spinner Orange 3 Piece Luggage Set with TSA Lock](https://go.ionic.click/Ch4CKd) - $69.99\n2. [Amazon Basics Expandable Hardside Luggage, Suitcase with Wheels, 30-Inch Spinner](https://www.amazon.com/dp/B071HHX6VF) - $74.49\n3. [SwissGear Sion Softside Expandable Luggage, Blue, Carry-On 21-Inch](https://www.amazon.com/dp/B01MFBVKDF) - $80.73\n4. [Travelers Club Midtown Hardside Luggage Travel, Rose Gold, 4-Piece Set](https://www.amazon.com/dp/B07RS4PK3J) - $95.19\n5. [American Tourister Stratum 2.0 Expandable Hardside Luggage with Spinner Wheels, 28" SPINNER, Slate Blue](https://www.amazon.com/dp/B0B2X1BDFH) - $89.97\n6. [Wrangler Smart Luggage Set with Cup Holder and USB Port, Navy Blue, 20-Inch Carry-On](https://www.amazon.com/dp/B07SLG6WZ2) - $39.99\n7. [Wrangler Hardside Carry-On Spinner Luggage, Lilac, 20-Inch](https://www.amazon.com/dp/B0C7YWMBGP) - $40.00\n8. [Protege 20 inch Hard Side Carry-On Spinner Luggage, Black Matte Finish (Walmart.com Exclusive)](https://go.ionic.click/qJqBRA) - $29.87\n9. [Wrangler Wesley Rolling Duffel Bag, Tannin, Large 30-Inch](https://www.amazon.com/dp/B07XKWMLJ5) - $44.00\n10. [U.S. Traveler Boren Polycarbonate Hardside Rugged Travel Suitcase Luggage with 8 Spinner Wheels, Aluminum Handle, Lavender, Checked-Large 30-Inch](https://www.amazon.com/dp/B085B4D852) - $79.99', additional_kwargs={}, response_metadata={'token_usage': {'completion_tokens': 612, 'prompt_tokens': 2794, 'total_tokens': 3406}, 'model_name': 'ibm/granite-3-8b-instruct', 'system_fingerprint': '', 'finish_reason': 'stop'}, id='chat-d08201ff6ef84c428e7ae44372396926', usage_metadata={'input_tokens': 2794, 'output_tokens': 612, 'total_tokens': 3406})]

Conforme visto pela resposta do LLM, o modelo usou corretamente a ferramenta de compras para retornar várias malas para compra online abaixo de US$ 100.

Resumo

Neste tutorial, você usou ferramentas do LangChain criadas previamente para criar um agente ReAct no Python com o watsonx usando o modelo granite-3-8b-instruct  . Você usou as ferramentas youtube_search , weather_search  e ionic_search  . O tutorial mostrou como implementar a chamada de ferramenta tradicional, bem como uma abordagem que executa as ferramentas. A saída de amostra é importante, pois mostra as etapas que o agente seguiu na criação de seu próprio fluxo de trabalho usando as funções disponíveis. As ferramentas concedidas ao agente eram vitais para responder às consultas dos usuários.

Soluções relacionadas
Agentes de IA para empresas

Crie, implemente e gerencie assistentes e agentes de IA potentes que automatizam fluxos de trabalho e processos com a IA generativa.

    Explore o watsonx Orchestrate
    Soluções de agentes de IA da IBM

    Construa o futuro do seu negócio com soluções de IA em que você pode confiar.

    Explore soluções de agentes de IA
    Serviços de IA do IBM® Consulting

    Os serviços de IA da IBM Consulting ajudam a reinventar a forma como as empresas trabalham com IA para gerar transformação.

    Explore os serviços de inteligência artificial
    Dê o próximo passo

    Se você optar por personalizar aplicativos e habilidades criados previamente ou criar e implementar serviços agênticos personalizados usando um estúdio de IA, a plataforma IBM watsonx tem aquilo de que você precisa.

    Explore o watsonx Orchestrate Explore o watsonx.ai