Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: HuggingFaceLocalChatGenerator unified support for tools #8827

Merged
merged 10 commits into from
Feb 10, 2025
Merged

Conversation

vblagoje
Copy link
Member

@vblagoje vblagoje commented Feb 6, 2025

Why:

Adds universal tools support to HuggingFaceLocalChatGenerator

What:

  • Introduced support for tool calls, allowing the generation model to prepare and parse tool interactions.
  • Implemented a tool call parsing method that utilizes regex patterns or callables.

How can it be used:

The addition allows for parsing tool calls from generated text, identified by tool names and their arguments. This can be set up during initialization:

import torch

from haystack.dataclasses import ChatMessage
from haystack.tools import Tool
from haystack.components.generators.chat import HuggingFaceLocalChatGenerator
from haystack.utils import Secret

def weather(city: str):
    return f'The weather in {city} is sunny and 32°C'

# Define tool parameters
tool_parameters = {
    "type": "object",
    "properties": {"city": {"type": "string"}},
    "required": ["city"]
}

# Create weather tool
weather_tool = Tool(
    name="weather",
    description="useful to determine the weather in a given location",
    parameters=tool_parameters,
    function=weather
)
# Initialize generator with tool
client = HuggingFaceLocalChatGenerator(
    model="NousResearch/Hermes-2-Pro-Llama-3-8B",
    token=Secret.from_env_var("HF_TOKEN"),
    tools=[weather_tool],
    huggingface_pipeline_kwargs={"torch_dtype":torch.bfloat16, "device_map": "auto"}
)
client.warm_up()

# Run initial query
messages = [ChatMessage.from_user("What's the weather like in Paris?")]
results = client.run(messages=messages)

# Get tool call from response
tool_message = next(msg for msg in results["replies"] if msg.tool_call)
tool_call = tool_message.tool_call

# Execute tool and send result back
weather_result = weather(**tool_call.arguments)
new_messages = [
    messages[0],
    tool_message,
    ChatMessage.from_tool(tool_result=weather_result, origin=tool_call)
]

# Get final response
final_result = client.run(new_messages)
print(final_result["replies"][0].text)

>>> The weather in Paris is sunny and 32°C. Enjoy your day!

How did you test it:

  • Added unit tests that mock generator run with specified tool patterns and tool lists
  • Real test notebook

Notes for the reviewer:

  • See https://huggingface.co/blog/unified-tool-use for more details about HF and tools
  • Validate the regex pattern for tool call extraction.
  • Ensure comprehensive testing of different tool call scenarios to guarantee robustness.

@github-actions github-actions bot added the type:documentation Improvements on the docs label Feb 6, 2025
@coveralls
Copy link
Collaborator

coveralls commented Feb 6, 2025

Pull Request Test Coverage Report for Build 13236543453

Warning: This coverage report may be inaccurate.

This pull request's base commit is no longer the HEAD commit of its target branch. This means it includes changes from outside the original pull request, including, potentially, unrelated coverage changes.

Details

  • 0 of 0 changed or added relevant lines in 0 files are covered.
  • 24 unchanged lines in 2 files lost coverage.
  • Overall coverage decreased (-0.4%) to 92.228%

Files with Coverage Reduction New Missed Lines %
telemetry/_telemetry.py 1 84.15%
components/generators/chat/hugging_face_local.py 23 84.46%
Totals Coverage Status
Change from base Build 13183889468: -0.4%
Covered Lines: 9173
Relevant Lines: 9946

💛 - Coveralls

@vblagoje vblagoje marked this pull request as ready for review February 7, 2025 09:00
@vblagoje vblagoje requested review from a team as code owners February 7, 2025 09:00
@vblagoje vblagoje requested review from dfokina, davidsbatista and anakin87 and removed request for a team and davidsbatista February 7, 2025 09:00
@vblagoje
Copy link
Member Author

vblagoje commented Feb 7, 2025

@davidsbatista asking @anakin87 for review here as he knows this code intimately 🙏

Copy link
Member

@anakin87 anakin87 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work! I particularly appreciated the notebook...

I left some comments about points we can improve.

@vblagoje
Copy link
Member Author

vblagoje commented Feb 7, 2025

Have a look at the updated run of the notebook as well @anakin87 🙏

@vblagoje vblagoje requested a review from anakin87 February 7, 2025 13:05
Copy link
Member

@anakin87 anakin87 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left a small comment to address.

Plus, "feat!:" in the PR title indicates a breaking change, and this does not seem breaking.
If I am right, let's simply change this to "feat:"

Feel free to merge once these small aspects are fixed.

Good work!

generator = HuggingFaceLocalChatGenerator(
model="meta-llama/Llama-2-13b-chat-hf", tools=tools, tool_parsing_function=custom_tool_parser
)
generator.pipeline = Mock(return_value=[{"generated_text": "Let me check the weather for you"}])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this generated_text is confusing. Please use something like "mock response. We don't use it"

Uses DEFAULT_TOOL_PATTERN to extract tool calls.

:param text: The text to parse for tool calls.
:returns: A list containing a single ToolCall if a valid tool call is found, None otherwise.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we are only extracting a single tool call, but this is clearly explained.
We can improve this in future if there are requests from the community.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes exactly, that's why I left it as a list 💪

@vblagoje vblagoje changed the title feat!: HuggingFaceLocalChatGenerator unified support for tools feat: HuggingFaceLocalChatGenerator unified support for tools Feb 10, 2025
@vblagoje vblagoje merged commit 73bfc08 into main Feb 10, 2025
18 checks passed
@vblagoje vblagoje deleted the hf_tools branch February 10, 2025 08:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic:tests type:documentation Improvements on the docs
Projects
None yet
Development

Successfully merging this pull request may close these issues.

HuggingFaceLocal ChatGenerator - support for Tool
3 participants