feat: Add configurable system prompt to Condition Agent (#4587)
* feat: Add configurable system prompt to Condition Agent * Update system prompt to HTML for UI readability * fix: Remove invalid default routing and sync hardcoded role-based examples * Update ConditionAgent.ts * Update ConditionAgent.ts --------- Co-authored-by: Henry Heng <henryheng@flowiseai.com>
This commit is contained in:
parent
21caedde72
commit
dfb401ad83
|
|
@ -27,7 +27,7 @@ class ConditionAgent_Agentflow implements INode {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.label = 'Condition Agent'
|
this.label = 'Condition Agent'
|
||||||
this.name = 'conditionAgentAgentflow'
|
this.name = 'conditionAgentAgentflow'
|
||||||
this.version = 1.0
|
this.version = 1.1
|
||||||
this.type = 'ConditionAgent'
|
this.type = 'ConditionAgent'
|
||||||
this.category = 'Agent Flows'
|
this.category = 'Agent Flows'
|
||||||
this.description = `Utilize an agent to split flows based on dynamic conditions`
|
this.description = `Utilize an agent to split flows based on dynamic conditions`
|
||||||
|
|
@ -80,6 +80,26 @@ class ConditionAgent_Agentflow implements INode {
|
||||||
scenario: ''
|
scenario: ''
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Override System Prompt',
|
||||||
|
name: 'conditionAgentOverrideSystemPrompt',
|
||||||
|
type: 'boolean',
|
||||||
|
description: 'Override initial system prompt for Condition Agent',
|
||||||
|
optional: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Node System Prompt',
|
||||||
|
name: 'conditionAgentSystemPrompt',
|
||||||
|
type: 'string',
|
||||||
|
rows: 4,
|
||||||
|
optional: true,
|
||||||
|
acceptVariable: true,
|
||||||
|
default: CONDITION_AGENT_SYSTEM_PROMPT,
|
||||||
|
description: 'Expert use only. Modifying this can significantly alter agent behavior. Leave default if unsure',
|
||||||
|
show: {
|
||||||
|
conditionAgentOverrideSystemPrompt: true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*{
|
/*{
|
||||||
label: 'Enable Memory',
|
label: 'Enable Memory',
|
||||||
|
|
@ -242,6 +262,12 @@ class ConditionAgent_Agentflow implements INode {
|
||||||
const conditionAgentInput = nodeData.inputs?.conditionAgentInput as string
|
const conditionAgentInput = nodeData.inputs?.conditionAgentInput as string
|
||||||
let input = conditionAgentInput || question
|
let input = conditionAgentInput || question
|
||||||
const conditionAgentInstructions = nodeData.inputs?.conditionAgentInstructions as string
|
const conditionAgentInstructions = nodeData.inputs?.conditionAgentInstructions as string
|
||||||
|
const conditionAgentSystemPrompt = nodeData.inputs?.conditionAgentSystemPrompt as string
|
||||||
|
const conditionAgentOverrideSystemPrompt = nodeData.inputs?.conditionAgentOverrideSystemPrompt as boolean
|
||||||
|
let systemPrompt = CONDITION_AGENT_SYSTEM_PROMPT
|
||||||
|
if (conditionAgentSystemPrompt && conditionAgentOverrideSystemPrompt) {
|
||||||
|
systemPrompt = conditionAgentSystemPrompt
|
||||||
|
}
|
||||||
|
|
||||||
// Extract memory and configuration options
|
// Extract memory and configuration options
|
||||||
const enableMemory = nodeData.inputs?.conditionAgentEnableMemory as boolean
|
const enableMemory = nodeData.inputs?.conditionAgentEnableMemory as boolean
|
||||||
|
|
@ -277,31 +303,15 @@ class ConditionAgent_Agentflow implements INode {
|
||||||
const messages: BaseMessageLike[] = [
|
const messages: BaseMessageLike[] = [
|
||||||
{
|
{
|
||||||
role: 'system',
|
role: 'system',
|
||||||
content: CONDITION_AGENT_SYSTEM_PROMPT
|
content: systemPrompt
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
role: 'user',
|
role: 'user',
|
||||||
content: `{"input": "Hello", "scenarios": ["user is asking about AI", "default"], "instruction": "Your task is to check and see if user is asking topic about AI"}`
|
content: `{"input": "Hello", "scenarios": ["user is asking about AI", "user is not asking about AI"], "instruction": "Your task is to check if the user is asking about AI."}`
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
role: 'assistant',
|
role: 'assistant',
|
||||||
content: `\`\`\`json\n{"output": "default"}\n\`\`\``
|
content: `\`\`\`json\n{"output": "user is not asking about AI"}\n\`\`\``
|
||||||
},
|
|
||||||
{
|
|
||||||
role: 'user',
|
|
||||||
content: `{"input": "What is AIGC?", "scenarios": ["user is asking about AI", "default"], "instruction": "Your task is to check and see if user is asking topic about AI"}`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
role: 'assistant',
|
|
||||||
content: `\`\`\`json\n{"output": "user is asking about AI"}\n\`\`\``
|
|
||||||
},
|
|
||||||
{
|
|
||||||
role: 'user',
|
|
||||||
content: `{"input": "Can you explain deep learning?", "scenarios": ["user is interested in AI topics", "default"], "instruction": "Determine if the user is interested in learning about AI"}`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
role: 'assistant',
|
|
||||||
content: `\`\`\`json\n{"output": "user is interested in AI topics"}\n\`\`\``
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
// Use to store messages with image file references as we do not want to store the base64 data into database
|
// Use to store messages with image file references as we do not want to store the base64 data into database
|
||||||
|
|
@ -374,15 +384,19 @@ class ConditionAgent_Agentflow implements INode {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
let calledOutputName = 'default'
|
let calledOutputName: string
|
||||||
try {
|
try {
|
||||||
const parsedResponse = this.parseJsonMarkdown(response.content as string)
|
const parsedResponse = this.parseJsonMarkdown(response.content as string)
|
||||||
if (!parsedResponse.output) {
|
if (!parsedResponse.output || typeof parsedResponse.output !== 'string') {
|
||||||
throw new Error('Missing "output" key in response')
|
throw new Error('LLM response is missing the "output" key or it is not a string.')
|
||||||
}
|
}
|
||||||
calledOutputName = parsedResponse.output
|
calledOutputName = parsedResponse.output
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn(`Failed to parse LLM response: ${error}. Using default output.`)
|
throw new Error(
|
||||||
|
`Failed to parse a valid scenario from the LLM's response. Please check if the model is capable of following JSON output instructions. Raw LLM Response: "${
|
||||||
|
response.content as string
|
||||||
|
}"`
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean up empty inputs
|
// Clean up empty inputs
|
||||||
|
|
|
||||||
|
|
@ -39,37 +39,45 @@ export const DEFAULT_HUMAN_INPUT_DESCRIPTION_HTML = `<p>Summarize the conversati
|
||||||
</ul>
|
</ul>
|
||||||
`
|
`
|
||||||
|
|
||||||
export const CONDITION_AGENT_SYSTEM_PROMPT = `You are part of a multi-agent system designed to make agent coordination and execution easy. Your task is to analyze the given input and select one matching scenario from a provided set of scenarios. If none of the scenarios match the input, you should return "default."
|
export const CONDITION_AGENT_SYSTEM_PROMPT = `
|
||||||
|
<p>You are part of a multi-agent system designed to make agent coordination and execution easy. Your task is to analyze the given input and select one matching scenario from a provided set of scenarios.</p>
|
||||||
|
|
||||||
- **Input**: A string representing the user's query or message.
|
<ul>
|
||||||
- **Scenarios**: A list of predefined scenarios that relate to the input.
|
<li><strong>Input</strong>: A string representing the user's query, message or data.</li>
|
||||||
- **Instruction**: Determine if the input fits any of the scenarios.
|
<li><strong>Scenarios</strong>: A list of predefined scenarios that relate to the input.</li>
|
||||||
|
<li><strong>Instruction</strong>: Determine which of the provided scenarios is the best fit for the input.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
## Steps
|
<h2>Steps</h2>
|
||||||
|
<ol>
|
||||||
|
<li><strong>Read the input string</strong> and the list of scenarios.</li>
|
||||||
|
<li><strong>Analyze the content of the input</strong> to identify its main topic or intention.</li>
|
||||||
|
<li><strong>Compare the input with each scenario</strong>: Evaluate how well the input's topic or intention aligns with each of the provided scenarios and select the one that is the best fit.</li>
|
||||||
|
<li><strong>Output the result</strong>: Return the selected scenario in the specified JSON format.</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
1. **Read the input string** and the list of scenarios.
|
<h2>Output Format</h2>
|
||||||
2. **Analyze the content of the input** to identify its main topic or intention.
|
<p>Output should be a JSON object that names the selected scenario, like this: <code>{"output": "<selected_scenario_name>"}</code>. No explanation is needed.</p>
|
||||||
3. **Compare the input with each scenario**:
|
|
||||||
- If a scenario matches the main topic of the input, select that scenario.
|
|
||||||
- If no scenarios match, prepare to output "\`\`\`json\n{"output": "default"}\`\`\`"
|
|
||||||
4. **Output the result**: If a match is found, return the corresponding scenario in JSON; otherwise, return "\`\`\`json\n{"output": "default"}\`\`\`"
|
|
||||||
|
|
||||||
## Output Format
|
<h2>Examples</h2>
|
||||||
|
<ol>
|
||||||
|
<li>
|
||||||
|
<p><strong>Input</strong>: <code>{"input": "Hello", "scenarios": ["user is asking about AI", "user is not asking about AI"], "instruction": "Your task is to check if the user is asking about AI."}</code></p>
|
||||||
|
<p><strong>Output</strong>: <code>{"output": "user is not asking about AI"}</code></p>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p><strong>Input</strong>: <code>{"input": "What is AIGC?", "scenarios": ["user is asking about AI", "user is asking about the weather"], "instruction": "Your task is to check and see if the user is asking a topic about AI."}</code></p>
|
||||||
|
<p><strong>Output</strong>: <code>{"output": "user is asking about AI"}</code></p>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p><strong>Input</strong>: <code>{"input": "Can you explain deep learning?", "scenarios": ["user is interested in AI topics", "user wants to order food"], "instruction": "Determine if the user is interested in learning about AI."}</code></p>
|
||||||
|
<p><strong>Output</strong>: <code>{"output": "user is interested in AI topics"}</code></p>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
Output should be a JSON object that either names the matching scenario or returns "\`\`\`json\n{"output": "default"}\`\`\`" if no scenarios match. No explanation is needed.
|
<h2>Note</h2>
|
||||||
|
<ul>
|
||||||
## Examples
|
<li>Ensure that the input scenarios align well with potential user queries for accurate matching.</li>
|
||||||
|
<li>DO NOT include anything other than the JSON in your response.</li>
|
||||||
1. **Input**: {"input": "Hello", "scenarios": ["user is asking about AI", "default"], "instruction": "Your task is to check and see if user is asking topic about AI"}
|
</ul>
|
||||||
**Output**: "\`\`\`json\n{"output": "default"}\`\`\`"
|
|
||||||
|
|
||||||
2. **Input**: {"input": "What is AIGC?", "scenarios": ["user is asking about AI", "default"], "instruction": "Your task is to check and see if user is asking topic about AI"}
|
|
||||||
**Output**: "\`\`\`json\n{"output": "user is asking about AI"}\`\`\`"
|
|
||||||
|
|
||||||
3. **Input**: {"input": "Can you explain deep learning?", "scenarios": ["user is interested in AI topics", "default"], "instruction": "Determine if the user is interested in learning about AI"}
|
|
||||||
**Output**: "\`\`\`json\n{"output": "user is interested in AI topics"}\`\`\`"
|
|
||||||
|
|
||||||
## Note
|
|
||||||
- Ensure that the input scenarios align well with potential user queries for accurate matching
|
|
||||||
- DO NOT include anything other than the JSON in your response.
|
|
||||||
`
|
`
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue