forked from microsoft/agent-governance-toolkit
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlangchain_demo.py
More file actions
283 lines (224 loc) · 9.33 KB
/
langchain_demo.py
File metadata and controls
283 lines (224 loc) · 9.33 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
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
"""
LangChain Integration Demo - Agent Control Plane
This example demonstrates how to use the Agent Control Plane with LangChain
to govern tool calls made by LangChain agents.
The LangChain adapter provides the same zero-friction governance as the OpenAI
adapter, but for LangChain's agent framework.
"""
import sys
import os
# Add the src directory to the path
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "src")))
from agent_control_plane import (
AgentControlPlane,
LangChainAdapter,
create_governed_langchain_client,
ActionType,
PermissionLevel,
)
def print_section(title):
"""Print a formatted section header"""
print("\n" + "=" * 80)
print(f" {title}")
print("=" * 80 + "\n")
def demo_basic_langchain_governance():
"""Demonstrate basic LangChain governance"""
print_section("Demo 1: Basic LangChain Governance")
# Create control plane
control_plane = AgentControlPlane()
# Create a mock LangChain client for demonstration
# In real usage, you would use: from langchain.chat_models import ChatOpenAI
class MockLangChainLLM:
"""Mock LangChain LLM for demonstration"""
def __init__(self):
self.model_name = "gpt-3.5-turbo"
def __call__(self, prompt):
return f"Response to: {prompt}"
def invoke(self, messages):
return {"content": "Mock response", "tool_calls": []}
llm = MockLangChainLLM()
# Define permissions - read-only access
permissions = {
ActionType.FILE_READ: PermissionLevel.READ_ONLY,
ActionType.DATABASE_QUERY: PermissionLevel.READ_ONLY,
ActionType.FILE_WRITE: PermissionLevel.NONE, # Blocked!
}
# Create governed LangChain client
governed_llm = create_governed_langchain_client(
control_plane=control_plane,
agent_id="langchain-demo-agent",
langchain_client=llm,
permissions=permissions
)
print("✓ Created governed LangChain client")
print(f"✓ Agent ID: langchain-demo-agent")
print(f"✓ Permissions: READ_ONLY for files and database")
print(f"✓ File writes: BLOCKED\n")
# The governed_llm can now be used in place of the original LLM
# All tool calls will be automatically checked against the control plane
print("✓ LangChain client is now governed!")
print("✓ Use it with LangChain agents and all tool calls will be governed")
def demo_custom_tool_mapping():
"""Demonstrate custom tool mapping"""
print_section("Demo 2: Custom Tool Mapping")
control_plane = AgentControlPlane()
class MockLLM:
def __call__(self, prompt):
return f"Response to: {prompt}"
llm = MockLLM()
# Create agent context
permissions = {
ActionType.FILE_READ: PermissionLevel.READ_ONLY,
ActionType.API_CALL: PermissionLevel.READ_WRITE,
}
agent_context = control_plane.create_agent("custom-tool-agent", permissions)
# Custom tool mappings for company-specific tools
custom_mapping = {
"company_database_tool": ActionType.DATABASE_QUERY,
"company_file_reader": ActionType.FILE_READ,
"company_api_caller": ActionType.API_CALL,
}
# Create adapter with custom mapping
governed_llm = LangChainAdapter(
control_plane=control_plane,
agent_context=agent_context,
langchain_client=llm,
tool_mapping=custom_mapping
)
print("✓ Created LangChain adapter with custom tool mappings:")
print(" - company_database_tool → DATABASE_QUERY")
print(" - company_file_reader → FILE_READ")
print(" - company_api_caller → API_CALL")
print("\n✓ Company-specific tools are now mapped to standard ActionTypes")
print("✓ Governance rules apply to your custom tools!")
def demo_blocked_action_callback():
"""Demonstrate callback for blocked actions"""
print_section("Demo 3: Blocked Action Callback")
control_plane = AgentControlPlane()
# Track blocked actions
blocked_actions = []
def on_action_blocked(tool_name, tool_args, result):
"""Callback when an action is blocked"""
blocked_actions.append({
"tool": tool_name,
"args": tool_args,
"reason": result.get("error", "Unknown"),
})
print(f"\n⚠️ ALERT: Action blocked!")
print(f" Tool: {tool_name}")
print(f" Reason: {result.get('error', 'Unknown')}")
class MockLLM:
def __call__(self, prompt):
return f"Response to: {prompt}"
llm = MockLLM()
# Restrictive permissions
permissions = {
ActionType.FILE_READ: PermissionLevel.READ_ONLY,
ActionType.FILE_WRITE: PermissionLevel.NONE, # All writes blocked
}
agent_context = control_plane.create_agent("monitored-agent", permissions)
# Create adapter with callback
governed_llm = LangChainAdapter(
control_plane=control_plane,
agent_context=agent_context,
langchain_client=llm,
on_block=on_action_blocked
)
print("✓ Created LangChain adapter with blocked action callback")
print("✓ Callback will be invoked whenever an action is blocked")
print("✓ Use this for alerting, logging, or security monitoring")
print("\nExample uses:")
print(" - Send alerts to PagerDuty")
print(" - Log to SIEM system")
print(" - Notify security team")
print(" - Track repeated violations")
def demo_integration_pattern():
"""Demonstrate real-world integration pattern"""
print_section("Demo 4: Real-World Integration Pattern")
print("Real-world LangChain integration pattern:\n")
print("1. Setup (one-time):")
print(" ```python")
print(" from langchain.chat_models import ChatOpenAI")
print(" from langchain.agents import initialize_agent, load_tools")
print(" from agent_control_plane import create_governed_langchain_client")
print(" ")
print(" # Create base LLM")
print(" llm = ChatOpenAI(temperature=0, model='gpt-4')")
print(" ")
print(" # Wrap with governance")
print(" governed_llm = create_governed_langchain_client(")
print(" control_plane, 'my-agent', llm, permissions)")
print(" ```\n")
print("2. Use in agents:")
print(" ```python")
print(" # Load LangChain tools")
print(" tools = load_tools(['python_repl', 'requests', 'wikipedia'])")
print(" ")
print(" # Create agent with governed LLM")
print(" agent = initialize_agent(")
print(" tools, governed_llm, agent='zero-shot-react-description')")
print(" ")
print(" # Run tasks - all tool calls are governed!")
print(" agent.run('Search Wikipedia and save results to file')")
print(" ```\n")
print("3. Benefits:")
print(" ✓ Zero code changes to existing LangChain agents")
print(" ✓ All tool calls automatically governed")
print(" ✓ Complete audit trail in control plane")
print(" ✓ Policy enforcement at kernel level")
print(" ✓ Works with all LangChain agent types")
def demo_statistics():
"""Demonstrate statistics and audit trail"""
print_section("Demo 5: Statistics and Audit Trail")
control_plane = AgentControlPlane()
class MockLLM:
def __call__(self, prompt):
return f"Response to: {prompt}"
llm = MockLLM()
permissions = {
ActionType.FILE_READ: PermissionLevel.READ_ONLY,
}
agent_context = control_plane.create_agent("audit-demo-agent", permissions)
governed_llm = LangChainAdapter(
control_plane=control_plane,
agent_context=agent_context,
langchain_client=llm
)
# Get statistics
stats = governed_llm.get_statistics()
print("✓ Access adapter statistics:")
print(f" - Agent ID: {stats['agent_id']}")
print(f" - Session ID: {stats['session_id']}")
print(f" - Audit log entries: {len(stats['control_plane_audit'])}")
print(f" - Execution history: {len(stats['execution_history'])}")
print("\n✓ Complete audit trail available")
print("✓ Track all actions, decisions, and violations")
print("✓ Essential for compliance and debugging")
def main():
"""Run all demos"""
print("\n" + "=" * 80)
print(" LangChain Integration Demo - Agent Control Plane")
print("=" * 80)
try:
demo_basic_langchain_governance()
demo_custom_tool_mapping()
demo_blocked_action_callback()
demo_integration_pattern()
demo_statistics()
print_section("Summary")
print("✓ LangChain adapter provides zero-friction governance")
print("✓ Works with all LangChain agent types and tools")
print("✓ Custom tool mappings for company-specific tools")
print("✓ Callbacks for monitoring and alerting")
print("✓ Complete audit trail and statistics")
print("\n✓ Same governance approach as OpenAI adapter")
print("✓ Use the right adapter for your framework!")
print("\n" + "=" * 80 + "\n")
except Exception as e:
print(f"\n❌ Error: {str(e)}")
import traceback
traceback.print_exc()
if __name__ == "__main__":
main()