newsmode
search
Меню
arrow_back Назад

Llama-3 Func Calling – Hamel’s Blog - Hamel Husain

auto_awesomeКраткое саммари

Hamel Husain показывает, как использовать вызов функций (function calling) с моделью Llama-3 70B Instruct через инференс-API Replicate. В заметке приводится вспомогательный код для парсинга ответа с тегами <function-call> и <answer>, а также утилита для превращения Python-функций в JSON-схему (заимствованная из fastai/llm-hackers). Демонстрируются два инструмента: get_exchange_rate и create_contact. На нескольких сценариях показано поведение модели: когда инструмент не нужен (с предоставленными tools и без них), когда инструмент требуется и есть все параметры, и когда модели не хватает данных и она запрашивает их у пользователя. Полный код инференса с промптом доступен в репозитории replicate-examples автора.

Setup

Настройка

import replicate from pydantic import create_model import inspect, json, re from inspect import Parameter from fastcore.foundation import L from functools import partial from pprint import pprint

import replicate from pydantic import create_model import inspect, json, re from inspect import Parameter from fastcore.foundation import L from functools import partial from pprint import pprint

The following collapsible element contains helper functions for the Replicate inference API and parsing the response:

Следующий сворачиваемый блок содержит вспомогательные функции для инференс-API Replicate и парсинга ответа:

def parse(text): """Use regular expressions to find content within the tags.""" function_call_search = re.search(r"<function-call>\s*(.*?)\s*</function-call>", text, re.DOTALL) answer_search = re.search(r"<answer>\s*(.*?)\s*</answer>", text, re.DOTALL) function_call = function_call_search.group(1).strip() if function_call_search else None answer = answer_search.group(1).strip() if answer_search else None if function_call and function_call != "None": return {"type": "function-call", "content": function_call} elif answer: return {"type": "text", "content": answer} else: return {"type": "text", "content": text} def run(prompt:str, tools:str=None): inp = {"prompt": f"{prompt}", "temperature": 0} if tools: inp['tools'] = tools output = replicate.run( "hamelsmu/llama-3-70b-instruct-awq-with-tools:b6042c085a7927a3d87e065a9f51fb7238ef6870c7a2ab7b03caa3c0e9413e19", input=inp ) txt = ''.join(output) return parse(txt)

def parse(text): """Используем регулярные выражения, чтобы найти содержимое внутри тегов.""" function_call_search = re.search(r"\s*(.*?)\s*", text, re.DOTALL) answer_search = re.search(r"\s*(.*?)\s*", text, re.DOTALL) function_call = function_call_search.group(1).strip() if function_call_search else None answer = answer_search.group(1).strip() if answer_search else None if function_call and function_call != "None": return {"type": "function-call", "content": function_call} elif answer: return {"type": "text", "content": answer} else: return {"type": "text", "content": text} def run(prompt:str, tools:str=None): inp = {"prompt": f"{prompt}", "temperature": 0} if tools: inp['tools'] = tools output = replicate.run( "hamelsmu/llama-3-70b-instruct-awq-with-tools:b6042c085a7927a3d87e065a9f51fb7238ef6870c7a2ab7b03caa3c0e9413e19", input=inp ) txt = ''.join(output) return parse(txt)

A helper to help turn functions into a schema from fastai/llm-hackers

Вспомогательная функция, превращающая функции в схему — из fastai/llm-hackers

def schema(f): kw = {n:(o.annotation, ... if o.default==Parameter.empty else o.default) for n,o in inspect.signature(f).parameters.items()} s = create_model(f'Input for `{f.__name__}`', **kw).schema() return dict(name=f.__name__, description=f.__doc__, parameters=s)

def schema(f): kw = {n:(o.annotation, ... if o.default==Parameter.empty else o.default) for n,o in inspect.signature(f).parameters.items()} s = create_model(f'Input for `{f.__name__}`', **kw).schema() return dict(name=f.__name__, description=f.__doc__, parameters=s)

Lets define two tools:

Определим два инструмента:

def get_exchange_rate(base_currency:str, target_currency:str): """ Get the exchange rate between two currencies. Parameters: - base_currency (str): The currency to convert from. - target_currency (str): The currency to convert to. Returns: float: The exchange rate from base_currency to target_currency. """ ... def create_contact(name:str, email:str): """ Create a new contact. Parameters: - name (str): The name of the contact. - email (str): The email address of the contact. Returns: dict: Confirmation of the created contact. """ ... tools = json.dumps(list(L([get_exchange_rate, create_contact]).map(schema)))

def get_exchange_rate(base_currency:str, target_currency:str): """ Получить обменный курс между двумя валютами. Параметры: - base_currency (str): Валюта, из которой производится конвертация. - target_currency (str): Валюта, в которую производится конвертация. Возвращает: float: Обменный курс из base_currency в target_currency. """ ... def create_contact(name:str, email:str): """ Создать новый контакт. Параметры: - name (str): Имя контакта. - email (str): Адрес электронной почты контакта. Возвращает: dict: Подтверждение создания контакта. """ ... tools = json.dumps(list(L([get_exchange_rate, create_contact]).map(schema)))

The Demo

Демонстрация

Scenario 1A: No tool required to answer question

Сценарий 1A: Для ответа на вопрос инструмент не нужен

even though tool is provided

даже если инструмент предоставлен

o1a = run(prompt="Write a very short sentence about SEO.", tools=tools) pprint(o1a)

o1a = run(prompt="Write a very short sentence about SEO.", tools=tools) pprint(o1a)

{'content': 'Search Engine Optimization (SEO) is crucial for online ' 'visibility.', 'type': 'text'}

{'content': 'Search Engine Optimization (SEO) is crucial for online ' 'visibility.', 'type': 'text'}

Scenario 1B: No tool required to answer question

Сценарий 1B: Для ответа на вопрос инструмент не нужен

no tools are provided

инструменты не предоставлены

o1b = run(prompt="Write a very short sentence about SEO.", tools=None) pprint(o1b)

o1b = run(prompt="Write a very short sentence about SEO.", tools=None) pprint(o1b)

{'content': 'Here is a very short sentence about SEO:\n' '\n' '"Optimizing website content with relevant keywords improves ' 'search engine rankings."', 'type': 'text'}

{'content': 'Here is a very short sentence about SEO:\n' '\n' '"Optimizing website content with relevant keywords improves ' 'search engine rankings."', 'type': 'text'}

Scenario 2: Tool is reqiured to answer question

Сценарий 2: Для ответа на вопрос требуется инструмент

o2 = run(prompt="How many Japenese Yen are there in 1000 USD?", tools=tools) pprint(o2)

o2 = run(prompt="How many Japenese Yen are there in 1000 USD?", tools=tools) pprint(o2)

{'content': 'get_exchange_rate(base_currency="USD", target_currency="JPY")', 'type': 'function-call'}

{'content': 'get_exchange_rate(base_currency="USD", target_currency="JPY")', 'type': 'function-call'}

Scenario 3A: Tool reqiured but not enough info in the prompt for the params

Сценарий 3A: Инструмент нужен, но в промпте недостаточно информации для параметров

o3a = run(prompt="Can you help me add a Hamel Husain to my address book?", tools=tools) pprint(o3a)

o3a = run(prompt="Can you help me add a Hamel Husain to my address book?", tools=tools) pprint(o3a)

{'content': "I'd be happy to help you add Hamel Husain to your address book! " 'However, I need more information from you. Could you please ' "provide Hamel's email address? Once I have that, I can assist you " 'in adding the contact.', 'type': 'text'}

{'content': "I'd be happy to help you add Hamel Husain to your address book! " 'However, I need more information from you. Could you please ' "provide Hamel's email address? Once I have that, I can assist you " 'in adding the contact.', 'type': 'text'}

Scenario 3B: Tool required, there is enough info in the prompt

Сценарий 3B: Инструмент нужен, и в промпте достаточно информации

o3b = run(prompt="Can you help me add a Hamel Husain to my address book?\ His email address is h@fmail.com", tools=tools) pprint(o3b)

o3b = run(prompt="Can you help me add a Hamel Husain to my address book?\ His email address is h@fmail.com", tools=tools) pprint(o3b)

{'content': 'create_contact(name="Hamel Husain", email="h@fmail.com")', 'type': 'function-call'}

{'content': 'create_contact(name="Hamel Husain", email="h@fmail.com")', 'type': 'function-call'}