Trước khi bắt đầu với hướng dẫn nâng cao này, vui lòng đảm bảo rằng bạn đã hiểu cơ bản về quy trình tích hợp công cụ trong ChatX. Kiểm tra để có một cái nhìn nhanh chóng.
Giao diện Công cụ
Chúng tôi đã xác định một loạt các phương thức trợ giúp trong lớp Tool để giúp các nhà phát triển nhanh chóng xây dựng các công cụ phức tạp hơn.
Trả lại Tin Nhắn
ChatX hỗ trợ các loại tin nhắn khác nhau như văn bản, liên kết, hình ảnh và tệp BLOB. Bạn có thể trả lại các loại tin nhắn khác nhau cho LLM và người dùng thông qua các giao diện sau đây.
Vui lòng lưu ý, một số tham số trong các giao diện sau sẽ được giới thiệu trong các phần sau.
URL Hình Ảnh
Bạn chỉ cần chuyển URL của hình ảnh, và ChatX sẽ tự động tải xuống hình ảnh và trả lại cho người dùng.
def create_image_message(self, image: str, save_as: str = '') -> ToolInvokeMessage:
"""
create an image message
:param image: the url of the image
:return: the image message
"""
Liên kết
Nếu bạn cần trả lại một liên kết, bạn có thể sử dụng giao diện sau đây.
def create_link_message(self, link: str, save_as: str = '') -> ToolInvokeMessage:
"""
create a link message
:param link: the url of the link
:return: the link message
"""
Văn Bản
Nếu bạn cần trả lại một tin nhắn văn bản, bạn có thể sử dụng giao diện sau đây.
def create_text_message(self, text: str, save_as: str = '') -> ToolInvokeMessage:
"""
create a text message
:param text: the text of the message
:return: the text message
"""
Tệp BLOB
Nếu bạn cần trả lại dữ liệu thô của một tệp, như hình ảnh, âm thanh, video, PPT, Word, Excel, v.v., bạn có thể sử dụng giao diện sau đây.
blob Dữ liệu thô của tệp, kiểu bytes
meta Thông tin siêu dữ liệu của tệp, nếu bạn biết loại tệp, tốt nhất là chuyển một mime_type, nếu không, ChatX sẽ sử dụng octet/stream làm loại mặc định
def create_blob_message(self, blob: bytes, meta: dict = None, save_as: str = '') -> ToolInvokeMessage:
"""
create a blob message
:param blob: the blob
:return: the blob message
"""
Công Cụ Lối Tắt
Trong các ứng dụng mô hình lớn, chúng ta có hai nhu cầu phổ biến:
Đầu tiên, tóm tắt một đoạn văn bản dài trước, sau đó chuyển nội dung tóm tắt cho LLM để tránh văn bản gốc quá dài để xử lý bởi LLM
Nội dung thu được bởi công cụ là một liên kết, và thông tin trang web cần được lục trước khi có thể trả lại cho LLM
Để giúp các nhà phát triển nhanh chóng thực hiện hai nhu cầu này, chúng tôi cung cấp hai công cụ lối tắt sau đây.
Công Cụ Tóm Tắt Văn Bản
Công cụ này nhận vào một user_id và văn bản cần tóm tắt, và trả lại văn bản đã tóm tắt. ChatX sẽ sử dụng mô hình mặc định của không gian làm việc hiện tại để tóm tắt văn bản dài.
def summary(self, user_id: str, content: str) -> str:
"""
summary the content
:param user_id: the user id
:param content: the content
:return: the summary
"""
Công Cụ Lục Trang Web
Công cụ này nhận vào liên kết trang web cần lục và một user_agent (có thể để trống), và trả lại một chuỗi chứa thông tin của trang web. User_agent là một tham số tùy chọn có thể được sử dụng để xác định công cụ. Nếu không chuyển, ChatX sẽ sử dụng user_agent mặc định.
def get_url(self, url: str, user_agent: str = None) -> str:
"""
get url
""" the crawled result
Vùng Biến
Chúng tôi đã giới thiệu một bể biến trong Công cụ để lưu trữ các biến, tệp, v.v. được tạo ra trong quá trình hoạt động của công cụ. Các biến này có thể được sử dụng bởi các công cụ khác trong quá trình hoạt động của công cụ.
Tiếp theo, chúng ta sẽ sử dụng DallE3 và Vectorizer.AI làm ví dụ để giới thiệu cách sử dụng bể biến.
DallE3 là một công cụ tạo hình ảnh có thể tạo ra hình ảnh dựa trên văn bản. Ở đây, chúng tôi sẽ để DallE3 tạo ra một logo cho một quán cà phê.
Vectorizer.AI là một công cụ chuyển đổi hình ảnh vector có thể chuyển đổi hình ảnh thành hình ảnh vector, để hình ảnh có thể được phóng to vô hạn mà không bị méo mó. Ở đây, chúng tôi sẽ chuyển đổi biểu tượng PNG được tạo ra bởi DallE3 thành một hình ảnh vector, để nó có thể được sử dụng thực sự bởi các nhà thiết kế.
DallE3
Đầu tiên, chúng tôi sử dụng DallE3. Sau khi tạo hình ảnh, chúng tôi lưu hình ảnh vào bể biến. Mã như sau:
from typing import Any, Dict, List, Union
from core.tools.entities.tool_entities import ToolInvokeMessage
from core.tools.tool.builtin_tool import BuiltinTool
from base64 import b64decode
from openai import OpenAI
class DallE3Tool(BuiltinTool):
def _invoke(self,
user_id: str,
tool_paramters: Dict[str, Any],
) -> Union[ToolInvokeMessage, List[ToolInvokeMessage]]:
"""
invoke tools
"""
client = OpenAI(
api_key=self.runtime.credentials['openai_api_key'],
)
# prompt
prompt = tool_paramters.get('prompt', '')
if not prompt:
return self.create_text_message('Please input prompt')
# call openapi dalle3
response = client.images.generate(
prompt=prompt, model='dall-e-3',
size='1024x1024', n=1, style='vivid', quality='standard',
response_format='b64_json'
)
result = []
for image in response.data:
# Save all images to the variable pool through the save_as parameter. The variable name is self.VARIABLE_KEY.IMAGE.value. If new images are generated later, they will overwrite the previous images.
result.append(self.create_blob_message(blob=b64decode(image.b64_json),
meta={ 'mime_type': 'image/png' },
save_as=self.VARIABLE_KEY.IMAGE.value))
return result
Lưu ý rằng chúng tôi đã sử dụng self.VARIABLE_KEY.IMAGE.value như tên biến của hình ảnh. Để cho các công cụ của các nhà phát triển có thể hợp tác với nhau, chúng tôi đã định nghĩa KEY này. Bạn có thể sử dụng nó tự do, hoặc bạn có thể chọn không sử dụng KEY này. Việc chuyển một KEY tùy chỉnh cũng được chấp nhận.
Vectorizer.AI
Tiếp theo, chúng ta sử dụng Vectorizer.AI để chuyển đổi biểu tượng PNG được tạo ra bởi DallE3 thành một hình ảnh vector. Hãy đi qua các chức năng mà chúng tôi đã định nghĩa ở đây. Mã như sau:
from core.tools.tool.builtin_tool import BuiltinTool
from core.tools.entities.tool_entities import ToolInvokeMessage, ToolParamter
from core.tools.errors import ToolProviderCredentialValidationError
from typing import Any, Dict, List, Union
from httpx import post
from base64 import b64decode
class VectorizerTool(BuiltinTool):
def _invoke(self, user_id: str, tool_paramters: Dict[str, Any]) \
-> Union[ToolInvokeMessage, List[ToolInvokeMessage]]:
"""
Tool invocation, the image variable name needs to be passed in from here, so that we can get the image from the variable pool
"""
def get_runtime_parameters(self) -> List[ToolParamter]:
"""
Override the tool parameter list, we can dynamically generate the parameter list based on the actual situation in the current variable pool, so that the LLM can generate the form based on the parameter list
"""
def is_tool_avaliable(self) -> bool:
"""
Whether the current tool is available, if there is no image in the current variable pool, then we don't need to display this tool, just return False here
"""
Tiếp theo, hãy thực hiện ba chức năng này
from core.tools.tool.builtin_tool import BuiltinTool
from core.tools.entities.tool_entities import ToolInvokeMessage, ToolParamter
from core.tools.errors import ToolProviderCredentialValidationError
from typing import Any, Dict, List, Union
from httpx import post
from base64 import b64decode
class VectorizerTool(BuiltinTool):
def _invoke(self, user_id: str, tool_paramters: Dict[str, Any]) \
-> Union[ToolInvokeMessage, List[ToolInvokeMessage]]:
"""
invoke tools
"""
api_key_name = self.runtime.credentials.get('api_key_name', None)
api_key_value = self.runtime.credentials.get('api_key_value', None)
if not api_key_name or not api_key_value:
raise ToolProviderCredentialValidationError('Please input api key name and value')
# Get image_id, the definition of image_id can be found in get_runtime_parameters
image_id = tool_paramters.get('image_id', '')
if not image_id:
return self.create_text_message('Please input image id')
# Get the image generated by DallE from the variable pool
image_binary = self.get_variable_file(self.VARIABLE_KEY.IMAGE)
if not image_binary:
return self.create_text_message('Image not found, please request user to generate image firstly.')
# Generate vector image
response = post(
'https://vectorizer.ai/api/v1/vectorize',
files={ 'image': image_binary },
data={ 'mode': 'test' },
auth=(api_key_name, api_key_value),
timeout=30
)
if response.status_code != 200:
raise Exception(response.text)
return [
self.create_text_message('the vectorized svg is saved as an image.'),
self.create_blob_message(blob=response.content,
meta={'mime_type': 'image/svg+xml'})
]
def get_runtime_parameters(self) -> List[ToolParamter]:
"""
override the runtime parameters
"""
# Here, we override the tool parameter list, define the image_id, and set its option list to all images in the current variable pool. The configuration here is consistent with the configuration in yaml.
return [
ToolParamter.get_simple_instance(
name='image_id',
llm_description=f'the image id that you want to vectorize, \
and the image id should be specified in \
{[i.name for i in self.list_default_image_variables()]}',
type=ToolParamter.ToolParameterType.SELECT,
required=True,
options=[i.name for i in self.list_default_image_variables()]
)
]
def is_tool_avaliable(self) -> bool:
# Only when there are images in the variable pool, the LLM needs to use this tool
return len(self.list_default_image_variables()) > 0
Đáng chú ý rằng chúng tôi thực sự không sử dụng image_id ở đây. Chúng tôi giả định rằng phải có một hình ảnh trong bể biến mặc định khi gọi công cụ này, vì vậy chúng tôi trực tiếp sử dụng image_binary = self.get_variable_file(self.VARIABLE_KEY.IMAGE) để lấy hình ảnh. Trong các trường hợp mà khả năng của mô hình yếu, chúng tôi khuyến nghị các nhà phát triển làm điều tương tự, điều này có thể hiệu quả cải thiện khả năng chịu lỗi và tránh việc mô hình truyền các tham số không chính xác.