问题所在
LangChain代理可能用意外输入调用工具、无限制消耗API积分或进行危险的系统调用。没有运行时治理,代理在生产中是不可预测的成本和安全风险。
Scavio 解决方案
用确定性策略层包装每个LangChain工具,在执行前拦截调用。执行路径中无LLM调用。策略包括速率限制、PII检测、输入验证和审计日志。
之前
执行策略前,生产代理在一个会话中循环搜索调用耗尽了SerpAPI积分。PII数据被发送到搜索提供商。无审计跟踪。
之后
添加ShadowAudit风格包装后,代理每会话限制10次搜索调用。PII在到达搜索API前被检测并屏蔽。完整审计日志。
适用人群
将代理部署到生产环境并需要对工具调用进行确定性运行时治理的LangChain开发者。
核心优势
- 确定性执行——治理路径中无LLM
- 在危险调用执行前拦截
- 按会话追踪工具使用量控制成本
- PII检测防止数据泄露给搜索提供商
- 可作为包装器用于任何LangChain工具
Python 示例
Python
import re
from typing import Callable
class ToolPolicy:
def __init__(self, max_calls: int = 10, block_pii: bool = True):
self.max_calls = max_calls
self.block_pii = block_pii
self.call_count = 0
self.pii_patterns = [
re.compile(r'[\w.-]+@[\w.-]+\.\w+'), # email
re.compile(r'\b\d{3}[-.]?\d{3}[-.]?\d{4}\b'), # phone
]
def enforce(self, query: str) -> str | None:
self.call_count += 1
if self.call_count > self.max_calls:
return f'Blocked: max {self.max_calls} calls exceeded'
if self.block_pii:
for pattern in self.pii_patterns:
if pattern.search(query):
return 'Blocked: PII detected in query'
return None
def wrap_tool(fn: Callable, policy: ToolPolicy) -> Callable:
def wrapped(query: str) -> str:
block = policy.enforce(query)
if block:
return block
return fn(query)
return wrapped
# Usage:
policy = ToolPolicy(max_calls=10, block_pii=True)
# search_tool = wrap_tool(original_search, policy)JavaScript 示例
JavaScript
class ToolPolicy {
constructor(maxCalls = 10) {
this.maxCalls = maxCalls;
this.callCount = 0;
this.piiPatterns = [/[\w.-]+@[\w.-]+\.\w+/, /\b\d{3}[-.]?\d{3}[-.]?\d{4}\b/];
}
enforce(query) {
this.callCount++;
if (this.callCount > this.maxCalls) return `Blocked: max ${this.maxCalls} calls exceeded`;
if (this.piiPatterns.some(p => p.test(query))) return 'Blocked: PII detected';
return null;
}
}
function wrapTool(fn, policy) {
return async (query) => {
const block = policy.enforce(query);
if (block) return block;
return fn(query);
};
}
const policy = new ToolPolicy(10);
// const safeTool = wrapTool(originalSearch, policy);使用的平台
包含知识图谱、PAA和AI概览的网页搜索