|
104 | 104 | "- Text-to-text generation\n",
|
105 | 105 | "- Text-to-audio generation\n",
|
106 | 106 | "- Text-to-audio conversation\n",
|
| 107 | + "- Function calling\n", |
| 108 | + "- Code execution\n", |
107 | 109 | "\n",
|
108 | 110 | "See the [Multimodal Live API](https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/multimodal-live) page for more details."
|
109 | 111 | ]
|
|
590 | 592 | "await main()"
|
591 | 593 | ]
|
592 | 594 | },
|
| 595 | + { |
| 596 | + "cell_type": "markdown", |
| 597 | + "metadata": { |
| 598 | + "id": "f214d0c3bee0" |
| 599 | + }, |
| 600 | + "source": [ |
| 601 | + "### **Example 4**: Function calling\n", |
| 602 | + "\n", |
| 603 | + "You can use function calling to create a description of a function, then pass that description to the model in a request. The response from the model includes the name of a function that matches the description and the arguments to call it with.\n", |
| 604 | + "\n", |
| 605 | + "**Notes**:\n", |
| 606 | + "\n", |
| 607 | + "- All functions must be declared at the start of the session by sending tool definitions as part of the `setup` message.\n", |
| 608 | + "- Currently only one tool is supported in the API." |
| 609 | + ] |
| 610 | + }, |
| 611 | + { |
| 612 | + "cell_type": "code", |
| 613 | + "execution_count": null, |
| 614 | + "metadata": { |
| 615 | + "id": "8a7595aee24a" |
| 616 | + }, |
| 617 | + "outputs": [], |
| 618 | + "source": [ |
| 619 | + "# Set model generation_config\n", |
| 620 | + "CONFIG = {\"response_modalities\": [\"TEXT\"]}\n", |
| 621 | + "\n", |
| 622 | + "# Define function declarations\n", |
| 623 | + "TOOLS = {\n", |
| 624 | + " \"function_declarations\": {\n", |
| 625 | + " \"name\": \"get_current_weather\",\n", |
| 626 | + " \"description\": \"Get the current weather in the given location\",\n", |
| 627 | + " \"parameters\": {\n", |
| 628 | + " \"type\": \"OBJECT\",\n", |
| 629 | + " \"properties\": {\"location\": {\"type\": \"STRING\"}},\n", |
| 630 | + " },\n", |
| 631 | + " }\n", |
| 632 | + "}\n", |
| 633 | + "\n", |
| 634 | + "headers = {\n", |
| 635 | + " \"Content-Type\": \"application/json\",\n", |
| 636 | + " \"Authorization\": f\"Bearer {bearer_token[0]}\",\n", |
| 637 | + "}\n", |
| 638 | + "\n", |
| 639 | + "# Connect to the server\n", |
| 640 | + "async with connect(SERVICE_URL, additional_headers=headers) as ws:\n", |
| 641 | + " # Setup the session\n", |
| 642 | + " await ws.send(\n", |
| 643 | + " json.dumps(\n", |
| 644 | + " {\n", |
| 645 | + " \"setup\": {\n", |
| 646 | + " \"model\": MODEL,\n", |
| 647 | + " \"generation_config\": CONFIG,\n", |
| 648 | + " \"tools\": TOOLS,\n", |
| 649 | + " }\n", |
| 650 | + " }\n", |
| 651 | + " )\n", |
| 652 | + " )\n", |
| 653 | + "\n", |
| 654 | + " # Receive setup response\n", |
| 655 | + " raw_response = await ws.recv(decode=False)\n", |
| 656 | + " setup_response = json.loads(raw_response.decode())\n", |
| 657 | + "\n", |
| 658 | + " # Send text message\n", |
| 659 | + " text_input = \"Get the current weather in Santa Clara, San Jose and Mountain View\"\n", |
| 660 | + " display(Markdown(f\"**Input:** {text_input}\"))\n", |
| 661 | + "\n", |
| 662 | + " msg = {\n", |
| 663 | + " \"client_content\": {\n", |
| 664 | + " \"turns\": [{\"role\": \"user\", \"parts\": [{\"text\": text_input}]}],\n", |
| 665 | + " \"turn_complete\": True,\n", |
| 666 | + " }\n", |
| 667 | + " }\n", |
| 668 | + "\n", |
| 669 | + " await ws.send(json.dumps(msg))\n", |
| 670 | + "\n", |
| 671 | + " responses = []\n", |
| 672 | + "\n", |
| 673 | + " # Receive chucks of server response\n", |
| 674 | + " async for raw_response in ws:\n", |
| 675 | + " response = json.loads(raw_response.decode(\"UTF-8\"))\n", |
| 676 | + "\n", |
| 677 | + " if (tool_call := response.get(\"toolCall\")) is not None:\n", |
| 678 | + " for function_call in tool_call[\"functionCalls\"]:\n", |
| 679 | + " responses.append(f\"FunctionCall: {str(function_call)}\\n\")\n", |
| 680 | + "\n", |
| 681 | + " if (server_content := response.get(\"serverContent\")) is not None:\n", |
| 682 | + " if server_content.get(\"turnComplete\", True):\n", |
| 683 | + " break\n", |
| 684 | + "\n", |
| 685 | + " # Print the server response\n", |
| 686 | + " display(Markdown(\"**Response >** {}\".format(\"\\n\".join(responses))))" |
| 687 | + ] |
| 688 | + }, |
| 689 | + { |
| 690 | + "cell_type": "markdown", |
| 691 | + "metadata": { |
| 692 | + "id": "ad6b585deadb" |
| 693 | + }, |
| 694 | + "source": [ |
| 695 | + "### **Example 5**: Code execution\n", |
| 696 | + "\n", |
| 697 | + "You can use code execution capability to generate and execute Python code directly within the API.\n", |
| 698 | + "\n", |
| 699 | + "In this example, you initialize the code execution tool by passing `code_execution` in the `Tools` configuration, and register this tool with the model at the start of the session by sending tool definitions as part of the `setup` message." |
| 700 | + ] |
| 701 | + }, |
| 702 | + { |
| 703 | + "cell_type": "code", |
| 704 | + "execution_count": null, |
| 705 | + "metadata": { |
| 706 | + "id": "acbbd8c0155e" |
| 707 | + }, |
| 708 | + "outputs": [], |
| 709 | + "source": [ |
| 710 | + "# Set model generation_config\n", |
| 711 | + "CONFIG = {\"response_modalities\": [\"TEXT\"]}\n", |
| 712 | + "\n", |
| 713 | + "# Set code execution\n", |
| 714 | + "TOOLS = {\"code_execution\": {}}\n", |
| 715 | + "\n", |
| 716 | + "headers = {\n", |
| 717 | + " \"Content-Type\": \"application/json\",\n", |
| 718 | + " \"Authorization\": f\"Bearer {bearer_token[0]}\",\n", |
| 719 | + "}\n", |
| 720 | + "\n", |
| 721 | + "# Connect to the server\n", |
| 722 | + "async with connect(SERVICE_URL, additional_headers=headers) as ws:\n", |
| 723 | + " # Setup the session\n", |
| 724 | + " await ws.send(\n", |
| 725 | + " json.dumps(\n", |
| 726 | + " {\n", |
| 727 | + " \"setup\": {\n", |
| 728 | + " \"model\": MODEL,\n", |
| 729 | + " \"generation_config\": CONFIG,\n", |
| 730 | + " \"tools\": TOOLS,\n", |
| 731 | + " }\n", |
| 732 | + " }\n", |
| 733 | + " )\n", |
| 734 | + " )\n", |
| 735 | + "\n", |
| 736 | + " # Receive setup response\n", |
| 737 | + " raw_response = await ws.recv(decode=False)\n", |
| 738 | + " setup_response = json.loads(raw_response.decode())\n", |
| 739 | + "\n", |
| 740 | + " # Send text message\n", |
| 741 | + " text_input = \"Write code to calculate the 15th fibonacci number then find the nearest palindrome to it\"\n", |
| 742 | + " display(Markdown(f\"**Input:** {text_input}\"))\n", |
| 743 | + "\n", |
| 744 | + " msg = {\n", |
| 745 | + " \"client_content\": {\n", |
| 746 | + " \"turns\": [{\"role\": \"user\", \"parts\": [{\"text\": text_input}]}],\n", |
| 747 | + " \"turn_complete\": True,\n", |
| 748 | + " }\n", |
| 749 | + " }\n", |
| 750 | + "\n", |
| 751 | + " await ws.send(json.dumps(msg))\n", |
| 752 | + "\n", |
| 753 | + " responses = []\n", |
| 754 | + "\n", |
| 755 | + " # Receive chucks of server response\n", |
| 756 | + " async for raw_response in ws:\n", |
| 757 | + " response = json.loads(raw_response.decode(\"UTF-8\"))\n", |
| 758 | + "\n", |
| 759 | + " if (server_content := response.get(\"serverContent\")) is not None:\n", |
| 760 | + " model_turn = server_content.get(\"modelTurn\")\n", |
| 761 | + " if (parts := model_turn.get(\"parts\")) is not None:\n", |
| 762 | + " if parts[0].get(\"text\"):\n", |
| 763 | + " responses.append(parts[0][\"text\"])\n", |
| 764 | + " for part in parts:\n", |
| 765 | + " if (executable_code := part.get(\"executableCode\")) is not None:\n", |
| 766 | + " display(\n", |
| 767 | + " Markdown(\n", |
| 768 | + " f\"\"\"**Executable code:**\n", |
| 769 | + "```py\n", |
| 770 | + "{executable_code.get(\"code\")}\n", |
| 771 | + "```\n", |
| 772 | + " \"\"\"\n", |
| 773 | + " )\n", |
| 774 | + " )\n", |
| 775 | + " if server_content.get(\"turnComplete\", False):\n", |
| 776 | + " break\n", |
| 777 | + "\n", |
| 778 | + " # Print the server response\n", |
| 779 | + " display(Markdown(f\"**Response >** {''.join(responses)}\"))" |
| 780 | + ] |
| 781 | + }, |
593 | 782 | {
|
594 | 783 | "cell_type": "markdown",
|
595 | 784 | "metadata": {
|
|
0 commit comments