-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathagent-with-fusion.ts
More file actions
172 lines (141 loc) · 4.59 KB
/
Copy pathagent-with-fusion.ts
File metadata and controls
172 lines (141 loc) · 4.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
/**
* LangChain + Prompt Fusion Integration Example
*
* Demonstrates how to use Prompt Fusion with LangChain's createReactAgent
* using the messageModifier pattern for dynamic prompt composition.
*
* Based on official LangChain documentation and production patterns.
*/
import { createReactAgent } from "@langchain/langgraph/prebuilt";
import { ChatOpenAI } from "@langchain/openai";
import { tool } from "@langchain/core/tools";
import { z } from "zod";
import { SystemMessage } from "@langchain/core/messages";
import PromptFusionEngine from "../../core/promptFusionEngine.js";
// Initialize fusion engine
const fusionEngine = new PromptFusionEngine();
// Define your tools
const searchTool = tool(
async ({ query }) => {
// Implementation
return `Search results for: ${query}`;
},
{
name: "search_knowledge",
description: "Search the knowledge graph",
schema: z.object({
query: z.string().describe("Search query"),
}),
}
);
const tools = [searchTool];
// LAYER 1: Base Prompt (Tool definitions & safety rules)
const basePrompt = `You are an AI assistant with knowledge graph access.
AVAILABLE TOOLS:
- search_knowledge: Query the knowledge graph for entities and relationships
SAFETY RULES:
- Always validate search queries
- Never expose sensitive information
- Cite sources when using knowledge graph data`;
// LAYER 2: Brain Prompt (Workspace configuration)
const brainPrompt = `WORKSPACE: Customer Analytics
ENVIRONMENT: Production
CONFIGURATION:
- Maximum query depth: 5 levels
- Response format: Structured with citations
- Data access: Read-only
GUIDELINES:
- Focus on data-driven insights
- Provide quantitative analysis when possible
- Always include confidence levels`;
// LAYER 3: Persona Prompt (Role overlay - loaded dynamically)
async function getPersonaForChat(chatId: string): Promise<{id: string, content: string} | null> {
// In production: fetch from database/Redis
// Example personas:
const personas = {
'analyst': {
id: 'analyst',
content: `You are a DATA ANALYST role.
SPECIALIZATION:
- Statistical analysis and pattern recognition
- Data visualization recommendations
- Trend identification and forecasting
TOOL PERMISSIONS:
- search_knowledge: Full access
- Query limit: 1000 records per request
COMMUNICATION STYLE:
- Technical but accessible
- Always quantify findings
- Provide actionable insights`
},
'researcher': {
id: 'researcher',
content: `You are a RESEARCH SPECIALIST role.
SPECIALIZATION:
- Deep empirical investigation
- Source validation and citation
- Comprehensive literature review
TOOL PERMISSIONS:
- search_knowledge: Full access
- Query limit: Unlimited
COMMUNICATION STYLE:
- Academic rigor
- Detailed explanations
- Complete source attribution`
}
};
// For this example, return analyst persona
return personas['analyst'];
}
// Create messageModifier with Prompt Fusion
function createFusionModifier(
basePrompt: string,
brainPrompt: string,
getPersona: (chatId: string) => Promise<{id: string, content: string} | null>
) {
return async (messages: any[], config: any) => {
const chatId = config?.configurable?.thread_id || 'default';
// Fetch persona dynamically
const personaData = await getPersona(chatId);
const personaContent = personaData?.content || '';
const personaId = personaData?.id || 'default';
// Determine weights based on persona presence
const weights = personaId !== 'default' && personaContent
? { base: 0.2, brain: 0.3, persona: 0.5 } // Persona dominates
: { base: 0.4, brain: 0.6, persona: 0.0 }; // Brain dominates
// Fuse prompts with semantic weighting
const fusedContent = fusionEngine.semanticWeightedFusion(
basePrompt,
brainPrompt,
personaContent,
weights
);
// Create system message
const systemMessage = new SystemMessage(fusedContent);
// Prepend to messages
return [systemMessage, ...messages];
};
}
// Create the agent
const model = new ChatOpenAI({
model: "gpt-4o",
temperature: 0,
});
const agent = createReactAgent({
llm: model,
tools: tools,
messageModifier: createFusionModifier(basePrompt, brainPrompt, getPersonaForChat)
});
// Use the agent
async function main() {
const config = { configurable: { thread_id: "user-123-chat-456" } };
const result = await agent.invoke({
messages: [{ role: "user", content: "Analyze customer retention trends" }],
}, config);
console.log(result.messages[result.messages.length - 1].content);
}
// Run if executed directly
if (import.meta.url === `file://${process.argv[1]}`) {
main();
}
export { agent, createFusionModifier };