we add research mode prompt

This commit is contained in:
duanfuxiang 2025-03-15 08:16:21 +08:00
parent 18f1d52494
commit 05b1302a6c
9 changed files with 182 additions and 20 deletions

View File

@ -1,19 +1,48 @@
export function getCapabilitiesSection(
const RegexSearchFilesInstructions = "\n- You can use regex_search_files to perform pattern-based searches across files using regular expressions. This tool is ideal for finding exact text matches, specific patterns (like tags, links, dates, URLs), or structural elements in notes. It excels at locating precise format patterns and is perfect for finding connections between notes, frontmatter elements, or specific Markdown formatting."
const SemanticSearchFilesInstructions = "\n- You can use semantic_search_files to find content based on meaning rather than exact text matches. Semantic search uses embedding vectors to understand concepts and ideas, finding relevant content even when keywords differ. This is especially powerful for discovering thematically related notes, answering conceptual questions about your knowledge base, or finding content when you don't know the exact wording used in the notes."
function getObsidianCapabilitiesSection(
cwd: string,
searchTool: string,
searchFilesTool: string,
): string {
const searchInstructions = searchTool === 'regex'
? "\n- You can use regex_search_files to perform pattern-based searches across files using regular expressions. This tool is ideal for finding exact text matches, specific patterns (like tags, links, dates, URLs), or structural elements in notes. It excels at locating precise format patterns and is perfect for finding connections between notes, frontmatter elements, or specific Markdown formatting."
: searchTool === 'semantic'
? "\n- You can use semantic_search_files to find content based on meaning rather than exact text matches. Semantic search uses embedding vectors to understand concepts and ideas, finding relevant content even when keywords differ. This is especially powerful for discovering thematically related notes, answering conceptual questions about your knowledge base, or finding content when you don't know the exact wording used in the notes."
: "";
const searchFilesInstructions = searchFilesTool === 'regex'
? RegexSearchFilesInstructions
: searchFilesTool === 'semantic'
? SemanticSearchFilesInstructions
: "";
return `====
CAPABILITIES
- You have access to tools that let you list files, search content, read and write files, and ask follow-up questions. These tools help you effectively accomplish a wide range of tasks, such as creating notes, making edits or improvements to existing notes, understanding the current state of an Obsidian vault, and much more.
- When the user initially gives you a task, environment_details will include a list of all files in the current Obsidian folder ('${cwd}'). This file list provides an overview of the vault structure, offering key insights into how knowledge is organized through directory and file names, as well as what file formats are being used. This information can guide your decision-making on which notes might be most relevant to explore further. If you need to explore directories outside the current folder, you can use the list_files tool. If you pass 'true' for the recursive parameter, it will list files recursively. Otherwise, it will list only files at the top level, which is better suited for generic directories where you don't necessarily need the nested structure.${searchInstructions}
- When the user initially gives you a task, environment_details will include a list of all files in the current Obsidian folder ('${cwd}'). This file list provides an overview of the vault structure, offering key insights into how knowledge is organized through directory and file names, as well as what file formats are being used. This information can guide your decision-making on which notes might be most relevant to explore further. If you need to explore directories outside the current folder, you can use the list_files tool. If you pass 'true' for the recursive parameter, it will list files recursively. Otherwise, it will list only files at the top level, which is better suited for generic directories where you don't necessarily need the nested structure.${searchFilesInstructions}
`
}
function getDeepResearchCapabilitiesSection(): string {
return `====
CAPABILITIES
- You have access to tools that let you search the web using internet search engines like Google to find relevant information on current events, facts, data, and other online content.
- Using search_web, you can simulate a human research process: first searching with relevant keywords to obtain initial results (containing URLs, titles, and content snippets).
- You should evaluate the relevance and reliability of each search result based on its title and content snippet, then select the most relevant URLs for deeper investigation.
- Use fetch_urls_content to retrieve complete webpage content from selected URLs to gain detailed information.
- You can conduct multiple rounds of searches and content retrieval (maximum 3 rounds), optimizing your search keywords in each round based on previously gathered information, just as a human would perform deep research.
- Synthesize all collected information to answer the user's questions comprehensively, accurately, and in a well-structured manner, citing information sources when appropriate.
`
}
export function getCapabilitiesSection(
mode: string,
cwd: string,
searchWebTool: string,
): string {
if (mode === 'research') {
return getDeepResearchCapabilitiesSection();
}
return getObsidianCapabilitiesSection(cwd, searchWebTool);
}

View File

@ -1,4 +1,19 @@
export function getObjectiveSection(): string {
function getDeepResearchObjectiveSection(): string {
return `====
OBJECTIVE
You accomplish a given task iteratively, breaking it down into clear steps and working through them methodically.
1. Analyze the user's task and set clear, achievable goals to accomplish it. Prioritize these goals in a logical order.
2. Work through these goals sequentially, utilizing available tools one at a time as necessary. Each goal should correspond to a distinct step in your problem-solving process. You will be informed on the work completed and what's remaining as you go.
3. Remember, you have extensive capabilities with access to a wide range of tools that can be used in powerful and clever ways as necessary to accomplish each goal. Before calling a tool, do some analysis within <thinking></thinking> tags. First, analyze the file structure provided in environment_details to gain context and insights for proceeding effectively. Then, think about which of the provided tools is the most relevant tool to accomplish the user's task. Next, go through each of the required parameters of the relevant tool and determine if the user has directly provided or given enough information to infer a value. When deciding if the parameter can be inferred, carefully consider all the context to see if it supports a specific value. If all of the required parameters are present or can be reasonably inferred, close the thinking tag and proceed with the tool use. BUT, if one of the values for a required parameter is missing, DO NOT invoke the tool (not even with fillers for the missing params) and instead, ask the user to provide the missing parameters using the ask_followup_question tool. DO NOT ask for more information on optional parameters if it is not provided.
4. The user may provide feedback, which you can use to make improvements and try again. But DO NOT continue in pointless back and forth conversations, i.e. don't end your responses with questions or offers for further assistance.
`
}
function getObsidianObjectiveSection(): string {
return `====
OBJECTIVE
@ -10,3 +25,10 @@ You accomplish a given task iteratively, breaking it down into clear steps and w
3. Remember, you have extensive capabilities with access to a wide range of tools that can be used in powerful and clever ways as necessary to accomplish each goal. Before calling a tool, do some analysis within <thinking></thinking> tags. First, analyze the file structure provided in environment_details to gain context and insights for proceeding effectively. Then, think about which of the provided tools is the most relevant tool to accomplish the user's task. Next, go through each of the required parameters of the relevant tool and determine if the user has directly provided or given enough information to infer a value. When deciding if the parameter can be inferred, carefully consider all the context to see if it supports a specific value. If all of the required parameters are present or can be reasonably inferred, close the thinking tag and proceed with the tool use. BUT, if one of the values for a required parameter is missing, DO NOT invoke the tool (not even with fillers for the missing params) and instead, ask the user to provide the missing parameters using the ask_followup_question tool. DO NOT ask for more information on optional parameters if it is not provided.
4. The user may provide feedback, which you can use to make improvements and try again. But DO NOT continue in pointless back and forth conversations, i.e. don't end your responses with questions or offers for further assistance.`
}
export function getObjectiveSection(mode: string): string {
if (mode === 'research') {
return getDeepResearchObjectiveSection();
}
return getObsidianObjectiveSection();
}

View File

@ -52,15 +52,31 @@ function getEditingInstructions(diffStrategy?: DiffStrategy, experiments?: Recor
}
function getSearchInstructions(searchTool: string): string {
if (searchTool === 'regex') {
if (searchTool === 'regex') {
return `- When using the regex_search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task, you may use it to find specific content, notes, headings, connections between notes, tags, or any text-based information across the Obsidian vault. The results include context, so analyze the surrounding text to better understand the matches. Leverage the regex_search_files tool in combination with other tools for comprehensive analysis. For example, use it to find specific phrases or patterns, then use read_file to examine the full context of interesting matches before using write_to_file to make informed changes.`
} else if (searchTool === 'semantic') {
} else if (searchTool === 'semantic') {
return `- When using the semantic_search_files tool, craft your natural language query to describe concepts and ideas rather than specific patterns. Based on the user's task, you may use it to find thematically related content, conceptually similar notes, or knowledge connections across the Obsidian vault, even when exact keywords aren't present. The results include context, so analyze the surrounding text to understand the conceptual relevance of each match. Leverage the semantic_search_files tool in combination with other tools for comprehensive analysis. For example, use it to find specific phrases or patterns, then use read_file to examine the full context of interesting matches before using write_to_file to make informed changes.`
}
return ""
}
return ""
}
export function getRulesSection(
function getDeepResearchRulesSection(): string {
return `====
RULES
- You provide deep, unexpected insights, identifying hidden patterns and connections, and creating "aha moments.".
- You break conventional thinking, establish unique cross-disciplinary connections, and bring new perspectives to the user.
- Do not ask for more information than necessary. Use the tools provided to accomplish the user's request efficiently and effectively. When you've completed your task, you must use the attempt_completion tool to present the result to the user. The user may provide feedback, which you can use to make improvements and try again.
- You are only allowed to ask the user questions using the ask_followup_question tool. Use this tool only when you need additional details to complete a task, and be sure to use a clear and concise question that will help you move forward with the task. However if you can use the available tools to avoid having to ask the user questions, you should do so.
- Your goal is to try to accomplish the user's task, NOT engage in a back and forth conversation.
- NEVER end attempt_completion result with a question or request to engage in further conversation! Formulate the end of your result in a way that is final and does not require further input from the user.
- You are STRICTLY FORBIDDEN from starting your messages with "Great", "Certainly", "Okay", "Sure". You should NOT be conversational in your responses, but rather direct and to the point. For example you should NOT say "Great, I've fetched the urls content" but instead something like "I've fetched the urls content". It is important you be clear and technical in your messages.
- When presented with images, utilize your vision capabilities to thoroughly examine them and extract meaningful information. Incorporate these insights into your thought process as you accomplish the user's task.
- It is critical you wait for the user's response after each tool use, in order to confirm the success of the tool use.
`
}
function getObsidianRulesSection(
cwd: string,
searchTool: string,
supportsComputerUse: boolean,
@ -88,3 +104,17 @@ ${getEditingInstructions(diffStrategy, experiments)}
- Pay special attention to the open tabs in environment_details, as they indicate which notes the user is currently working with and may be most relevant to their task. Similarly, the current file information shows which note is currently in focus and likely the primary subject of the user's request.
- It is critical you wait for the user's response after each tool use, in order to confirm the success of the tool use. For example, if asked to create a structured note, you would create a file, wait for the user's response it was created successfully, then create another file if needed, wait for the user's response it was created successfully, etc.`
}
export function getRulesSection(
mode: string,
cwd: string,
searchTool: string,
supportsComputerUse: boolean,
diffStrategy?: DiffStrategy,
experiments?: Record<string, boolean> | undefined,
): string {
if (mode === 'research') {
return getDeepResearchRulesSection();
}
return getObsidianRulesSection(cwd, searchTool, supportsComputerUse, diffStrategy, experiments);
}

View File

@ -76,13 +76,24 @@ ${getToolUseGuidelinesSection()}
${mcpServersSection}
${getCapabilitiesSection(cwd, searchTool)}
${getCapabilitiesSection(
mode,
cwd,
searchTool,
)}
${getRulesSection(cwd, searchTool, supportsComputerUse, effectiveDiffStrategy, experiments)}
${getRulesSection(
mode,
cwd,
searchTool,
supportsComputerUse,
effectiveDiffStrategy,
experiments,
)}
${getSystemInfoSection(cwd)}
${getObjectiveSection()}
${getObjectiveSection(mode)}
${await addCustomInstructions(promptComponent?.customInstructions || modeConfig.customInstructions || "", globalCustomInstructions || "", cwd, mode, { preferredLanguage })}`

View File

@ -0,0 +1,31 @@
import { ToolArgs } from "../tools/types"
export function getFetchUrlsContentDescription(_args: ToolArgs): string {
return `## fetch_urls_content
Description:
This tool allows you to fetch the content of multiple web pages. It retrieves the HTML content and returns it in a readable format. Use this tool when you need to analyze, extract information from, or understand the content of specific web pages.
Parameters:
- urls: (required) A JSON array of URLs to fetch content from. Each URL should be a complete URL including the protocol (http:// or https://).
- Maximum: 10 URLs per request
Usage:
<fetch_urls_content>
<urls>
[
"https://example.com/page1",
"https://example.com/page2"
]
</urls>
</fetch_urls_content>
Example:
<fetch_urls_content>
<urls>
[
"https://en.wikipedia.org/wiki/Artificial_intelligence",
"https://github.com/features/copilot"
]
</urls>
</fetch_urls_content>
`
}

View File

@ -7,13 +7,15 @@ import { getAskFollowupQuestionDescription } from "./ask-followup-question"
import { getAttemptCompletionDescription } from "./attempt-completion"
import { getBrowserActionDescription } from "./browser-action"
import { getExecuteCommandDescription } from "./execute-command"
import { getFetchUrlsContentDescription } from "./fetch-url-content"
import { getInsertContentDescription } from "./insert-content"
import { getListFilesDescription } from "./list-files"
import { getReadFileDescription } from "./read-file"
import { getSearchAndReplaceDescription } from "./search-and-replace"
import { getSearchFilesDescription } from "./search-files"
import { getSearchWebDescription } from "./search-web"
import { getSwitchModeDescription } from "./switch-mode"
import { ALWAYS_AVAILABLE_TOOLS, TOOL_GROUPS, ToolName } from "./tool-groups"
import { ALWAYS_AVAILABLE_TOOLS, TOOL_GROUPS } from "./tool-groups"
import { ToolArgs } from "./types"
import { getUseMcpToolDescription } from "./use-mcp-tool"
import { getWriteToFileDescription } from "./write-to-file"
@ -32,6 +34,8 @@ const toolDescriptionMap: Record<string, (args: ToolArgs) => string | undefined>
search_and_replace: (args) => getSearchAndReplaceDescription(args),
apply_diff: (args) =>
args.diffStrategy ? args.diffStrategy.getToolDescription({ cwd: args.cwd, toolOptions: args.toolOptions }) : "",
search_web: (args): string | undefined => getSearchWebDescription(args),
fetch_urls_content: (args): string | undefined => getFetchUrlsContentDescription(args),
}
export function getToolDescriptionsForMode(
@ -63,7 +67,7 @@ export function getToolDescriptionsForMode(
const toolGroup = TOOL_GROUPS[groupName]
if (toolGroup) {
toolGroup.tools.forEach((tool) => {
if (isToolAllowedForMode(tool as ToolName, mode, customModes ?? [], experiments ?? {})) {
if (isToolAllowedForMode(tool, mode, customModes ?? [], experiments ?? {})) {
tools.add(tool)
}
})
@ -93,6 +97,6 @@ export function getToolDescriptionsForMode(
export {
getAccessMcpResourceDescription, getAskFollowupQuestionDescription,
getAttemptCompletionDescription, getBrowserActionDescription, getExecuteCommandDescription, getInsertContentDescription,
getListFilesDescription, getReadFileDescription, getSearchFilesDescription, getSearchAndReplaceDescription, getSwitchModeDescription, getUseMcpToolDescription, getWriteToFileDescription
getListFilesDescription, getReadFileDescription, getSearchAndReplaceDescription, getSearchFilesDescription, getSwitchModeDescription, getUseMcpToolDescription, getWriteToFileDescription
}

View File

@ -25,6 +25,7 @@ Usage:
}
]</operations>
</search_and_replace>
Example: Replace "climate change" with "climate crisis" in lines 1-10 of an essay
<search_and_replace>
<path>essays/environmental-impact.md</path>

View File

@ -0,0 +1,31 @@
import { ToolArgs } from "./types"
export function getSearchWebDescription(args: ToolArgs): string {
return `## search_web
Description:
This tool allows you to search the web using internet search engines like Google to find relevant information on current events, facts, data, and other online content.
Parameters:
- query: (required) The search query to send to internet search engines. For best results, use concise, specific, and preferably English queries that would work well with search engines like Google.
Usage Tips:
- Use specific keywords rather than full sentences
- Include important context terms to narrow results
- Use quotes for exact phrases: "exact phrase"
Usage:
<search_web>
<query>Your search query here</query>
</search_web>
Examples:
<search_web>
<query>capital of France population statistics 2023</query>
</search_web>
<search_web>
<query>"renewable energy" growth statistics Europe</query>
</search_web>
<search_web>
<query>react vs angular vs vue.js comparison</query>
</search_web>`
}

View File

@ -30,6 +30,9 @@ export const TOOL_GROUPS: Record<string, ToolGroupConfig> = {
edit: {
tools: ["apply_diff", "write_to_file", "insert_content", "search_and_replace"],
},
research: {
tools: ["search_web", "fetch_urls_content"],
},
// browser: {
// tools: ["browser_action"],
// },