用 openJiuwen 安全护栏框架打造财智助手:手把手教你构建金融级 AI 智能体

金融 AI 应用有个老大难问题:怎么在提供智能服务的同时保证安全合规?

传统的提示词约束方式存在明显缺陷------容易被绕过、难以维护、无法同时检测输入和输出。最近我用 openJiuwen Agent Core 框架全新推出的安全护栏框架(Guardrail Framework),从零构建了一个名为「财智助手」的金融投资咨询智能体。

这个系统通过事件驱动的回调机制,在 Agent 生命周期中嵌入了四道安全防线:

  1. 危险操作检测 ------ 拦截转账、密码等危险指令
  2. 合规用语过滤 ------ 防止承诺收益、保本保息等违规用语
  3. 投资建议拦截 ------ 避免具体买卖建议带来的法律风险
  4. 频率限制保护 ------ 防止恶意用户消耗系统资源

项目地址:https://atomgit.com/openJiuwen/agent-core?utm_source=csdn


一、为什么需要安全护栏

金融行业对 AI 应用的安全性和合规性要求极高,传统开发方式存在几个明显问题:

|--------|-------------------------|
| 问题类型 | 具体表现 |
| 危险操作风险 | 用户要求 AI 执行转账、查询密码等操作 |
| 合规用语风险 | AI 输出"保证收益"、"保本保息"等违规用语 |
| 投资建议风险 | AI 给出具体买卖建议,承担法律责任 |
| 滥用风险 | 恶意用户频繁请求消耗系统资源 |

这些问题用传统的提示词约束很难解决------容易被绕过、后处理无法覆盖所有场景、缺乏系统化的检测机制。

安全护栏框架是什么

安全护栏框架(Guardrail Framework) 是 openJiuwen 最新推出的生产级安全检测能力,基于回调框架实现了事件驱动的安全检测机制。

几个关键特性:

|-------|-----------------------------------------------|
| 特性 | 能做什么 |
| 事件驱动 | 与 AsyncCallbackFramework 深度集成,无缝嵌入 Agent 生命周期 |
| 模块化设计 | BaseGuardrail + GuardrailBackend 分离,即插即用 |
| 多级风险 | RiskLevel 枚举(SAFE/LOW/MEDIUM/HIGH/CRITICAL) |
| 链式配置 | 支持流畅的 API 链式调用 |
| 组合能力 | 多个护栏可协同工作 |

适合哪些场景

|-------------|-----------|
| 场景 | 能解决什么问题 |
| 💰 投资咨询 | 防止违规操作和用语 |
| 🏦 客服问答 | 防止承诺和误导 |
| 📊 数据分析 | 保护系统资源 |
| 🤖 通用 Agent | 根据场景灵活配置 |


二、安全护栏框架的架构设计

2.1 三层架构解读

安全护栏框架的核心是一个三层架构:

2.2 可以监听哪些事件

护栏框架可以监听 Agent 执行流程中的各种事件:

|------------------|------------|-------------|
| 事件 | 什么时候触发 | 适合用什么护栏 |
| user_input | 用户输入进入系统 | 危险操作检测、频率限制 |
| llm_input | 发送给 LLM 之前 | 提示词注入检测 |
| llm_output | LLM 返回之后 | 敏感信息过滤 |
| agent_response | Agent 最终响应 | 合规用语检测 |
| tool_input | 工具调用前 | 参数校验 |
| tool_output | 工具返回后 | 结果过滤 |

2.3 风险等级如何划分

框架使用五级风险等级系统,每个等级对应不同的处理策略:

复制代码
class RiskLevel(Enum):
    SAFE = "safe"          # 无风险,正常通过
    LOW = "low"            # 低风险,记录但放行
    MEDIUM = "medium"      # 中风险,需要关注
    HIGH = "high"          # 高风险,建议拦截
    CRITICAL = "critical"  # 严重风险,必须拦截

三、快速开始:搭建开发环境

3.1 环境要求

|------------|----------------|
| 组件 | 版本要求 |
| Python | 3.11+ |
| openJiuwen | Latest(包含安全护栏) |
| openai | Latest |

3.2 安装步骤

复制代码
git clone https://atomgit.com/openJiuwen/agent-core.git
cd agent-core
python -m venv venv
source venv/bin/activate  # Linux/Mac
uv pip install -e .
cd examples/financial_advisor

3.3 快速验证(无需 API Key)

运行护栏演示脚本,快速体验框架能力:

复制代码
python test_guardrails_simple.py

四、「财智助手」系统架构设计

4.1 整体架构图

金融咨询智能体采用四层安全防护架构:

4.2 项目目录结构

复制代码
examples/financial_advisor/
├── README.md
├── run.py                              # 主入口
├── test_guardrails_simple.py           # 护栏演示脚本
├── src/
│   ├── __init__.py
│   ├── financial_agent.py              # 智能体实现
│   ├── cli.py                          # CLI 交互界面
│   └── guardrails/                     # 安全护栏模块
│       ├── __init__.py
│       ├── backends.py                 # 检测后端实现
│       └── guards.py                   # 护栏实现 + 护栏组合

4.3 核心模块功能说明

|--------|--------------------------|---------------|
| 模块 | 对应文件 | 负责什么 |
| CLI 界面 | cli.py | 命令行交互、护栏测试模式 |
| 智能体 | financial_agent.py | Agent 封装、护栏集成 |
| 护栏后端 | guardrails/backends.py | 检测逻辑实现 |
| 护栏类 | guardrails/guards.py | 护栏封装和组合 |


五、安全护栏实现详解

5.1 护栏框架核心接口

BaseGuardrail 抽象基类

所有护栏都继承自 BaseGuardrail,实现了统一的注册和检测机制:

复制代码
from openjiuwen.core.security.guardrail.guardrail import BaseGuardrail
from openjiuwen.core.security.guardrail.models import GuardrailResult

class CustomGuardrail(BaseGuardrail):
    """自定义护栏示例"""

    DEFAULT_EVENTS = ["user_input"]

    async def detect(self, event_name: str, *args, **kwargs) -> GuardrailResult:
        text = kwargs.get("text", "")

        if "危险内容" in text:
            return GuardrailResult.block(
                risk_level=RiskLevel.HIGH,
                risk_type="dangerous_content",
                details={"matched_content": "危险内容"}
            )

        return GuardrailResult.pass_()
GuardrailBackend 后端接口

检测后端负责实现具体的检测算法,与护栏类分离:

复制代码
from openjiuwen.core.security.guardrail.backends import GuardrailBackend
from openjiuwen.core.security.guardrail.models import RiskAssessment

class CustomBackend(GuardrailBackend):
    """自定义检测后端"""

    async def analyze(self, data: dict) -> RiskAssessment:
        text = data.get("text", "")

        if "违规" in text:
            return RiskAssessment(
                has_risk=True,
                risk_level=RiskLevel.HIGH,
                risk_type="violation",
                confidence=0.9,
                details={"reason": "检测到违规内容"}
            )

        return RiskAssessment(
            has_risk=False,
            risk_level=RiskLevel.SAFE
        )

5.2 四层安全护栏实现

护栏一:危险操作检测

检测目标:转账、密码、账户操作等危险指令

复制代码
class DangerousOperationBackend(GuardrailBackend):
    """危险操作检测后端"""

    DANGEROUS_PATTERNS = {
        "transfer": [r"转账", r"汇款", r"支付", r"付款"],
        "password": [r"密码", r"验证码", r"OTP", r"口令"],
        "account": [r"登录.*账户", r"授权.*账户", r"绑定.*银行卡"],
    }

    async def analyze(self, data: dict) -> RiskAssessment:
        text = data.get("text", "")
        text_lower = text.lower()

        detected_risks = []
        for risk_type, patterns in self.DANGEROUS_PATTERNS.items():
            for pattern in patterns:
                if re.search(pattern, text, re.IGNORECASE):
                    detected_risks.append({
                        "type": risk_type,
                        "matched_pattern": pattern
                    })
                    break

        if detected_risks:
            return RiskAssessment(
                has_risk=True,
                risk_level=RiskLevel.HIGH,
                risk_type="dangerous_operation",
                confidence=0.9,
                details={
                    "detected_risks": detected_risks,
                    "message": "检测到危险操作指令,AI无法执行此类操作",
                    "suggestion": "如有需要,请联系银行官方客服或使用官方APP"
                }
            )

        return RiskAssessment(
            has_risk=False,
            risk_level=RiskLevel.SAFE
        )

护栏类封装

复制代码
class DangerousOperationGuardrail(BaseGuardrail):
    """危险操作护栏"""

    DEFAULT_EVENTS = ["user_input"]

    def __init__(self, backend=None, strict_mode=False):
        if backend is None:
            backend = DangerousOperationBackend(strict_mode=strict_mode)
        super().__init__(backend=backend)

    async def detect(self, event_name: str, *args, **kwargs) -> GuardrailResult:
        text = kwargs.get("text", "")
        if not text:
            return GuardrailResult.pass_(details={"empty_input": True})

        return await super().detect(event_name, *args, **kwargs)
护栏二:合规用语检测

检测目标:承诺收益、保本保息、内部消息等违规用语

复制代码
class ComplianceTermsBackend(GuardrailBackend):
    """合规用语检测后端"""

    VIOLATION_PATTERNS = {
        "guaranteed_return": [
            r"保证.*收益", r"承诺.*盈利", r"必定.*赚钱",
            r"保本.*保息", r"零.*风险", r"稳赚不赔",
        ],
        "insider_info": [
            r"内部.*消息", r"内幕.*信息", r"独家.*消息",
        ],
    }

    def __init__(self, allow_educational=True):
        self.allow_educational = allow_educational
        self.risk_disclaimer_patterns = [
            r"投资有风险", r"市场有风险", r"盈亏自负",
        ]

    async def analyze(self, data: dict) -> RiskAssessment:
        content = data.get("content") or data.get("text", "")

        has_disclaimer = any(
            re.search(p, content, re.IGNORECASE)
            for p in self.risk_disclaimer_patterns
        )

        detected_violations = []
        for v_type, patterns in self.VIOLATION_PATTERNS.items():
            for pattern in patterns:
                if re.search(pattern, content, re.IGNORECASE):
                    detected_violations.append({"type": v_type, "pattern": pattern})
                    break

        if detected_violations:
            risk_level = RiskLevel.LOW if has_disclaimer else RiskLevel.MEDIUM
            return RiskAssessment(
                has_risk=True,
                risk_level=risk_level,
                risk_type="compliance_violation",
                details={"violations": detected_violations}
            )

        return RiskAssessment(has_risk=False, risk_level=RiskLevel.SAFE)
护栏三:投资建议检测

检测目标:具体股票代码、买卖价格、仓位建议

复制代码
class InvestmentAdviceBackend(GuardrailBackend):
    """投资建议检测后端"""

    ADVICE_PATTERNS = {
        "specific_stock": [
            r"建议.*买入?\s*[\d]{6}",
            r".*\d{6}.*值得.*买入",
        ],
        "specific_price": [
            r"\d+(\.\d+)?元.*买入",
            r"在.*\d+(\.\d+)?.*入场",
        ],
        "specific_position": [
            r"\d+[%%].*仓位",
            r"满仓.*买入",
        ],
    }

    async def analyze(self, data: dict) -> RiskAssessment:
        content = data.get("content") or data.get("text", "")

        detected_advices = []
        for a_type, patterns in self.ADVICE_PATTERNS.items():
            for pattern in patterns:
                if re.search(pattern, content, re.IGNORECASE):
                    detected_advices.append({"type": a_type, "pattern": pattern})
                    break

        if detected_advices:
            return RiskAssessment(
                has_risk=True,
                risk_level=RiskLevel.HIGH,
                risk_type="specific_investment_advice",
                details={"advices": detected_advices}
            )

        return RiskAssessment(has_risk=False, risk_level=RiskLevel.SAFE)
护栏四:频率限制检测

检测目标:请求频率控制,防止滥用

复制代码
class RateLimitBackend(GuardrailBackend):
    """频率限制检测后端"""

    def __init__(self, max_requests=10, time_window=60, cooldown_period=5):
        self.max_requests = max_requests
        self.time_window = time_window
        self.cooldown_period = cooldown_period
        self.request_history = defaultdict(list)

    async def analyze(self, data: dict) -> RiskAssessment:
        identifier = data.get("user_id") or data.get("session_id") or "default"
        current_time = time.time()

        history = self.request_history[identifier]
        history[:] = [ts for ts in history if current_time - ts < self.time_window]

        if history and (current_time - history[-1]) < self.cooldown_period:
            remaining = self.cooldown_period - (current_time - history[-1])
            return RiskAssessment(
                has_risk=True,
                risk_level=RiskLevel.LOW,
                risk_type="rate_limit_cooldown",
                details={"remaining_wait": round(remaining, 1)}
            )

        if len(history) >= self.max_requests:
            return RiskAssessment(
                has_risk=True,
                risk_level=RiskLevel.MEDIUM,
                risk_type="rate_limit_exceeded",
                details={"request_count": len(history)}
            )

        history.append(current_time)

        return RiskAssessment(
            has_risk=False,
            risk_level=RiskLevel.SAFE,
            details={"request_count": len(history)}
        )

5.3 护栏组合使用

框架提供了 FinancialGuardrailGroup 便捷类,支持一键注册所有护栏:

复制代码
class FinancialGuardrailGroup:
    """金融护栏组合"""

    def __init__(self, strict_mode=False, max_requests=10, time_window=60):
        self.dangerous_operation_guardrail = DangerousOperationGuardrail(
            strict_mode=strict_mode
        )
        self.compliance_output_guardrail = ComplianceOutputGuardrail()
        self.investment_advice_guardrail = InvestmentAdviceGuardrail()
        self.rate_limit_guardrail = RateLimitGuardrail(
            max_requests=max_requests,
            time_window=time_window
        )

    async def register_all(self, framework, session_id=None):
        """注册所有护栏到回调框架"""
        await self.dangerous_operation_guardrail.register(framework)
        await self.compliance_output_guardrail.register(framework)
        await self.investment_advice_guardrail.register(framework)
        await self.rate_limit_guardrail.register(framework)

    async def unregister_all(self):
        """注销所有护栏"""
        await self.dangerous_operation_guardrail.unregister()
        await self.compliance_output_guardrail.unregister()
        await self.investment_advice_guardrail.unregister()
        await self.rate_limit_guardrail.unregister()

5.4 智能体集成护栏

在智能体中集成护栏框架的关键代码:

复制代码
class FinancialAdvisorAgent:
    """金融投资咨询智能体「财智助手」"""

    def __init__(self, api_key: str, enable_guardrails: bool = True):
        self.agent = ReActAgent(card=self.card)
        self.agent.configure(self.config)

        self.enable_guardrails = enable_guardrails
        if enable_guardrails:
            self.guardrail_framework = AsyncCallbackFramework()
            self.guardrail_group = FinancialGuardrailGroup(
                max_requests=10,
                time_window=60,
                cooldown_period=2
            )

    async def chat(self, message: str, session_id: str = None):
        """与智能体对话(带护栏检测)"""
        session = Session(session_id or "financial_session")

        if self.enable_guardrails:
            await self.guardrail_group.register_all(
                self.guardrail_framework,
                session_id
            )

            # 输入检测
            try:
                await self.guardrail_framework.trigger(
                    "user_input",
                    text=message,
                    session_id=session_id
                )
            except Exception as e:
                await self.guardrail_group.unregister_all()
                raise

        try:
            result = await self.agent.invoke(
                inputs={"query": message},
                session=session
            )

            # 输出检测
            if self.enable_guardrails:
                response_content = str(result)
                try:
                    await self.guardrail_framework.trigger(
                        "agent_response",
                        content=response_content,
                        session_id=session_id
                    )
                except Exception:
                    return {
                        "status": "blocked",
                        "suggestion": self._get_safe_fallback_response(message)
                    }

            return {"status": "success", "result": result}

        finally:
            if self.enable_guardrails:
                await self.guardrail_group.unregister_all()

六、效果展示

6.1 护栏测试演示

复制代码
python test_guardrails_simple.py

6.2 CLI 交互模式

复制代码
python run.py --test

6.3 测试结果展示

场景一:安全输入正常通过
场景二:危险操作被拦截
场景三:合规用语被拦截
场景四:投资建议被拦截
场景五:综合测试

七、扩展开发:自定义你的护栏

7.1 添加自定义护栏

复制代码
from openjiuwen.core.security.guardrail.guardrail import BaseGuardrail
from openjiuwen.core.security.guardrail.models import GuardrailResult
from openjiuwen.core.security.guardrail.enums import RiskLevel

class CustomGuardrail(BaseGuardrail):
    """自定义护栏"""

    DEFAULT_EVENTS = ["user_input", "agent_response"]

    async def detect(self, event_name: str, *args, **kwargs) -> GuardrailResult:
        data = kwargs.get("text") or kwargs.get("content", "")

        if "需要检测的内容" in data:
            return GuardrailResult.block(
                risk_level=RiskLevel.MEDIUM,
                risk_type="custom_violation",
                details={"reason": "自定义拦截原因"}
            )

        return GuardrailResult.pass_()

# 使用自定义护栏
custom_guardrail = CustomGuardrail()
await custom_guardrail.register(framework)

7.2 添加自定义后端

复制代码
from openjiuwen.core.security.guardrail.backends import GuardrailBackend
from openjiuwen.core.security.guardrail.models import RiskAssessment

class CustomBackend(GuardrailBackend):
    """自定义检测后端"""

    async def analyze(self, data: dict) -> RiskAssessment:
        text = data.get("text", "")

        # 可以调用外部 API、使用机器学习模型等
        # result = await external_moderation_api.check(text)

        return RiskAssessment(has_risk=False, risk_level=RiskLevel.SAFE)

# 使用自定义后端
guardrail = DangerousOperationGuardrail(backend=CustomBackend())

7.3 护栏最佳实践

|------|-------------------|
| 实践要点 | 具体说明 |
| 事件选择 | 根据检测目标选择合适的事件 |
| 风险等级 | 合理设置风险等级,避免过度拦截 |
| 详情信息 | 提供详细的检测信息,便于调试 |
| 性能优化 | 检测逻辑异步化,避免阻塞主流程 |
| 错误处理 | 检测失败时返回安全结果,避免误拦截 |

八、总结

财智助手项目展示了 openJiuwen 安全护栏框架的几个核心能力:

  • 事件驱动架构:基于 AsyncCallbackFramework,无缝嵌入 Agent 生命周期
  • 模块化设计:BaseGuardrail + GuardrailBackend 分离,易于扩展
  • 即插即用:内置护栏可直接使用,护栏组合简化配置
  • 细粒度控制:五级风险等级,支持灵活的安全策略
  • 生产级能力:完整的注册/注销机制,支持动态管理

项目实现了四层防护:危险操作检测、合规用语过滤、投资建议拦截、频率限制保护。用户输入和 Agent 输出都会经过检测,确保金融合规要求。


参考资源


免责声明:本文项目仅用于演示 openJiuwen 安全护栏框架的使用方法。本智能体提供的任何内容仅供参考,不构成任何投资建议。投资有风险,入市需谨慎。

相关推荐
七夜zippoe1 天前
智能会议新纪元:JiuwenClaw AI会议管理系统全方位实战
人工智能·技能·skills·openjiuwen·记忆系统·jiuwenclaw
七夜zippoe1 天前
交叉编码器重排:支持vLLM兼容API的StandardReranker实现
人工智能·vllm·重排·openjiuwen·交叉编码器
●VON2 个月前
0基础也能行!「Flutter 跨平台开发训练营」1月19日正式启动!
学习·flutter·von·openjiuwen
EterNity_TiMe_2 个月前
用 openJiuwen 构建一个历史介绍 AI Agent:从需求到可运行实操
人工智能·开源·实战测评·openjiuwen
国服第二切图仔2 个月前
实战:在华为云上快速搭建 openJiuwen Agent 平台,并开发一个“诗词雅集”知识库智能体
人工智能·华为云·智能体·openjiuwen
爱吃大芒果2 个月前
openJiuwen(Windows端)大模型添加及AI Agent创建教程
人工智能·ubuntu·openjiuwen
qq_463408422 个月前
vagrant虚拟环境的Ubuntu 22.04 LTS环境Docker如何快速部署openJiuwen平台
人工智能·ubuntu·vagrant·openjiuwen
●VON2 个月前
DeepSeek-V3.2 模型在 OpenJiuWen 中的部署实践
学习·华为·von·openjiuwen
哈哈你是真的厉害2 个月前
Windows系统通过wsl Ubuntu24.04本地安装OpenJiuwen Studio的完整安装教程
人工智能·华为·ai·大模型·agent·智能体·openjiuwen