67 lines
2.8 KiB
Python
67 lines
2.8 KiB
Python
# Copyright (c) ModelScope Contributors. All rights reserved.
|
|
import json
|
|
from typing import TYPE_CHECKING, List, Optional, Tuple, Union
|
|
|
|
from .hermes import HermesAgentTemplate
|
|
|
|
if TYPE_CHECKING:
|
|
from swift.template import Prompt
|
|
|
|
|
|
class YoutuAgentTemplate(HermesAgentTemplate):
|
|
"""Agent template for Youtu-LLM models.
|
|
|
|
Tool calling format:
|
|
- Tool call: <tool_call>{"name": "function-name", "arguments": {...}}</tool_call>
|
|
- Tool response: <tool_response>...</tool_response>
|
|
"""
|
|
|
|
def _get_tool_responses(self, tool_messages):
|
|
res_tool = []
|
|
for tool_message in tool_messages:
|
|
tool_content = tool_message['content']
|
|
res_tool.append(f'<tool_response>{tool_content}</tool_response>')
|
|
return '\n'.join(res_tool)
|
|
|
|
def _format_tool_responses(
|
|
self,
|
|
assistant_content: str,
|
|
tool_messages,
|
|
) -> Tuple[str, 'Prompt']:
|
|
with_action = self.keyword.action in assistant_content and self.keyword.action_input in assistant_content
|
|
if with_action:
|
|
return super()._format_tool_responses(assistant_content, tool_messages)
|
|
# For Youtu-LLM, tool responses are placed in user message
|
|
if hasattr(self, 'template_meta'):
|
|
prompt = self.template_meta.prompt
|
|
chat_sep = self.template_meta.chat_sep
|
|
else:
|
|
prompt = ['<|User|>{{QUERY}}<|Assistant|>']
|
|
chat_sep = ['<|end_of_text|>']
|
|
res = chat_sep.copy()
|
|
total_tool = self._get_tool_responses(tool_messages)
|
|
for context in prompt:
|
|
if isinstance(context, str):
|
|
context = context.replace('{{QUERY}}', total_tool)
|
|
res.append(context)
|
|
return assistant_content, res
|
|
|
|
def _format_tools(self, tools: List[Union[str, dict]], system: Optional[str] = None, user_message=None) -> str:
|
|
tool_descs = [json.dumps(self.wrap_tool(tool), ensure_ascii=False) for tool in tools]
|
|
system = system or ''
|
|
if system:
|
|
system = f'{system}\n\n'
|
|
return f"""{system}<|begin_of_tool_description|>Tool calling capabilities.
|
|
You may call one or more functions to assist with the user query. You have the following functions available:
|
|
""" + '\n'.join([f'```json\n{desc}\n```' for desc in tool_descs]) + """
|
|
For tool call returns, you MUST use the following format:
|
|
<tool_call>{"name": "function-name", "arguments": {"param1": "value1", "param2": "value2"}}</tool_call>
|
|
<|end_of_tool_description|>"""
|
|
|
|
def _format_tool_calls(self, tool_call_messages):
|
|
tool_calls = []
|
|
for message in tool_call_messages:
|
|
tool_call = self._parse_tool_call(message['content'])
|
|
tool_calls.append(f'<tool_call>{json.dumps(tool_call, ensure_ascii=False)}</tool_call>')
|
|
return ''.join(tool_calls)
|