优化提示词及没有工具调用闭合标签

This commit is contained in:
Vertex-AI-Step-Builder
2025-12-31 14:20:20 +00:00
parent 6bcdbc2560
commit cecfc74a96
2 changed files with 76 additions and 6 deletions

View File

@@ -125,6 +125,7 @@ class ResponseParser:
1. Responses with tool calls (wrapped in tags) 1. Responses with tool calls (wrapped in tags)
2. Regular text responses 2. Regular text responses
3. Multiple tool calls in a single response 3. Multiple tool calls in a single response
4. Incomplete tool calls (missing closing tag) - fallback parsing
Args: Args:
llm_response: The raw text response from the LLM llm_response: The raw text response from the LLM
@@ -152,6 +153,10 @@ class ResponseParser:
if matches: if matches:
return self._parse_tool_call_response(llm_response, matches) return self._parse_tool_call_response(llm_response, matches)
else: else:
# Check for incomplete tool call (opening tag without closing tag)
if self.tool_call_start_tag in llm_response:
logger.warning("Detected incomplete tool call (missing closing tag). Attempting fallback parsing.")
return self._parse_incomplete_tool_call(llm_response)
return self._parse_text_only_response(llm_response) return self._parse_text_only_response(llm_response)
except Exception as e: except Exception as e:
@@ -217,6 +222,55 @@ class ResponseParser:
tool_calls=tool_calls if tool_calls else None tool_calls=tool_calls if tool_calls else None
) )
def _parse_incomplete_tool_call(self, llm_response: str) -> ResponseMessage:
"""
Parse a response with an incomplete tool call (missing closing tag).
This is a fallback method when the LLM doesn't close the tag properly.
It attempts to extract the tool call JSON and complete it.
Args:
llm_response: The full LLM response with incomplete tool call
Returns:
ResponseMessage with content and optionally tool_calls
"""
try:
# Find the opening tag
start_idx = llm_response.find(self.tool_call_start_tag)
if start_idx == -1:
return self._parse_text_only_response(llm_response)
# Extract content before the opening tag
content_before = llm_response[:start_idx].strip() if start_idx > 0 else None
# Extract everything after the opening tag
after_tag = llm_response[start_idx + len(self.tool_call_start_tag):]
# Try to extract valid JSON
json_str = self._extract_valid_json(after_tag)
if json_str:
try:
tool_call_data = json.loads(json_str)
tool_call = self._create_tool_call(tool_call_data)
logger.info(f"Successfully parsed incomplete tool call: {tool_call.function.name}")
return ResponseMessage(
content=content_before,
tool_calls=[tool_call]
)
except json.JSONDecodeError as e:
logger.warning(f"Failed to parse JSON from incomplete tool call: {e}")
# If all else fails, return as text
logger.warning("Could not salvage incomplete tool call, returning as text")
return ResponseMessage(content=llm_response)
except Exception as e:
logger.warning(f"Error in _parse_incomplete_tool_call: {e}")
return ResponseMessage(content=llm_response)
def _parse_text_only_response(self, llm_response: str) -> ResponseMessage: def _parse_text_only_response(self, llm_response: str) -> ResponseMessage:
""" """
Parse a response with no tool calls. Parse a response with no tool calls.

View File

@@ -117,17 +117,33 @@ def inject_tools_into_prompt(messages: List[ChatMessage], tools: List[Tool]) ->
tool_prompt = f""" tool_prompt = f"""
You are a helpful assistant with access to a set of tools. You are a helpful assistant with access to a set of tools.
You can call them by emitting a JSON object inside tool call tags.
IMPORTANT: Use the following format for tool calls: ## TOOL CALL FORMAT (CRITICAL)
Format: {TOOL_CALL_START_TAG}{{"name": "tool_name", "arguments": {{...}}}}{TOOL_CALL_END_TAG}
Example: {full_example} When you need to use a tool, you MUST follow this EXACT format:
Here are the available tools: {TOOL_CALL_START_TAG}{{"name": "tool_name", "arguments": {{...}}}}{TOOL_CALL_END_TAG}
### IMPORTANT RULES:
1. ALWAYS include BOTH the opening tag ({TOOL_CALL_START_TAG}) AND closing tag ({TOOL_CALL_END_TAG})
2. The JSON must be valid and properly formatted
3. Keep arguments concise to avoid truncation
4. Do not include any text between the tags except the JSON
### Examples:
Simple call:
{full_example}
Multiple arguments:
{TOOL_CALL_START_TAG}{{"name": "search", "arguments": {{"query": "example", "limit": 5}}}}{TOOL_CALL_END_TAG}
## AVAILABLE TOOLS:
{tool_defs} {tool_defs}
Only use the tools if strictly necessary. ## REMEMBER:
- If you decide to call a tool, output ONLY the tool call tags (you may add brief text before or after)
- ALWAYS close your tags properly with {TOOL_CALL_END_TAG}
- Keep your arguments concise and essential
""" """
# Prepend the system prompt with tool definitions # Prepend the system prompt with tool definitions
return [ChatMessage(role="system", content=tool_prompt)] + messages return [ChatMessage(role="system", content=tool_prompt)] + messages