完整教程:基于Python的单一功能审批智能体实现及接入Spring Cloud Alibaba
完整教程:基于Python的单一功能审批智能体实现及接入Spring Cloud Alibaba
适用场景:本教程针对企业级工作流系统(如您的FlowMind项目)添加智能审批功能。智能体专攻审批决策(e.g., 基于规则自动批准/拒绝/建议人工),使用本地微调模型(Phi-3 Mini)确保数据隐私。Python部分使用LangChain构建代理,Spring Cloud Alibaba部分通过REST API集成,支持Nacos服务发现和Sentinel流量控制。
教程目标:
- Python:实现审批智能体(LangChain + Ollama + 微调Phi-3)。
- 集成:将Python服务作为微服务接入Spring Cloud Alibaba(Spring Boot 3.x + Nacos + Sentinel)。
- 总时长:~2-3小时(含测试)。
📋 先决条件
硬件/软件
- Python环境:Python 3.12+,RTX 3060(12GB VRAM)+ 16GB RAM(用于微调/推理)。
- Spring环境:JDK 17+,Maven 3.9+,您的FlowMind项目(基于Spring Cloud Alibaba 2023.x或更新)。
- 其他:
- Ollama(v0.3+,ollama.com下载)。
- NVIDIA CUDA 12.x(驱动535+)。
- 数据库:MySQL(存储规则)。
- 依赖安装(Python):
pip install langchain langchain-ollama langchain-community flask pydantic torch transformers peft datasets trl accelerate bitsandbytes。
注意:所有操作本地执行,确保隐私。微调需~1小时,推理<200ms。
🚀 步骤1:Python环境设置与模型微调
1.1 安装Ollama并加载基模型
- 下载并安装Ollama(Windows/Linux/Mac支持)。
- 运行命令加载Phi-3 Mini基模型(~7GB下载):
ollama pull microsoft/phi-3-mini-4k-instruct ollama serve # 启动本地服务器 (localhost:11434) - 测试模型:
ollama run microsoft/phi-3-mini-4k-instruct "Hello, approve this request?"
1.2 准备训练数据(从Easy Rules转换)
假设您的规则存MySQL approval_rules表(字段:id, enterpriseId, condition, action, example)。创建Python脚本prepare_data.py导出并转换(生成JSONL训练集)。
import json
import pandas as pd # 假设用pandas从DB查询
from sqlalchemy import create_engine # pip install sqlalchemy pymysql
# 连接MySQL(替换您的配置)
engine = create_engine('mysql+pymysql://root:password@localhost:3306/flowmind')
# 查询规则(示例1000+条历史数据)
df = pd.read_sql("SELECT enterpriseId, condition, action, example FROM approval_rules LIMIT 1000", engine)
train_samples = []
for _, row in df.iterrows():
prompt = f"企业{row['enterpriseId']},规则: {row['condition']}。申请: {row['example']}。判断: "
completion = f"{{{{\"decision\": \"{row['action']}\", \"reason\": \"符合规则\", \"confidence\": 0.95}}}"
train_samples.append({"prompt": prompt, "completion": completion})
# 保存JSONL
with open("rules_finetune.jsonl", "w", encoding="utf-8") as f:
for sample in train_samples:
f.write(json.dumps(sample) + "\n")
print(f"生成 {len(train_samples)} 条训练样本")运行:python prepare_data.py。目标:1000-3000条(合成变体提升泛化)。
1.3 微调Phi-3模型(QLoRA,RTX 3060友好)
创建finetune.py脚本(~30-60min训练)。
from datasets import load_dataset
from peft import LoraConfig, get_peft_model, TaskType
from transformers import AutoModelForCausalLM, AutoTokenizer, TrainingArguments, BitsAndBytesConfig
from trl import SFTTrainer
import torch
# 模型配置
model_name = "microsoft/phi-3-mini-4k-instruct"
quantization_config = BitsAndBytesConfig(load_in_4bit=True) # 4-bit量化,VRAM<4GB
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(
model_name, quantization_config=quantization_config, device_map="auto", torch_dtype=torch.bfloat16
)
# QLoRA配置(高效微调)
peft_config = LoraConfig(task_type=TaskType.CAUSAL_LM, r=8, lora_alpha=16, lora_dropout=0.1)
model = get_peft_model(model, peft_config)
# 加载数据
dataset = load_dataset("json", data_files="rules_finetune.jsonl", split="train")
# 训练参数(小batch适配3060)
args = TrainingArguments(
output_dir="./phi3-rules-tuned",
num_train_epochs=2,
per_device_train_batch_size=2,
gradient_accumulation_steps=4,
learning_rate=2e-4,
fp16=True,
save_steps=500
)
trainer = SFTTrainer(model=model, args=args, train_dataset=dataset, tokenizer=tokenizer)
trainer.train()
# 保存适配器
model.save_pretrained("phi3-rules-adapter")
tokenizer.save_pretrained("phi3-rules-adapter")
print("微调完成!")运行:python finetune.py。监控VRAM:nvidia-smi(峰值~4GB)。
1.4 部署微调模型到Ollama
合并模型到GGUF(用Hugging Face工具):
# 安装gguf工具: pip install gguf python -c " from transformers import AutoModelForCausalLM, AutoTokenizer model = AutoModelForCausalLM.from_pretrained('microsoft/phi-3-mini-4k-instruct') tokenizer = AutoTokenizer.from_pretrained('phi3-rules-adapter') # 简化:手动合并或用llama.cpp convert.py脚本 " # 实际用llama.cpp: git clone https://github.com/ggerganov/llama.cpp && cd llama.cpp && python convert.py phi3-rules-tuned(简化:用Ollama Modelfile创建。)
创建Modelfile(
Modelfile文件):FROM ./phi3-rules.gguf # 您的GGUF文件路径 TEMPLATE """{{ .Prompt }}""" PARAMETER num_ctx 4096导入并测试:
ollama create phi3-rules -f Modelfile ollama run phi3-rules "企业A,请假2天,判断:"预期输出:
{"decision": "approve", "reason": "天数<3", "confidence": 0.95}
🐍 步骤2:Python实现单一功能审批智能体(LangChain)
创建approval_agent.py(核心代理,只处理审批决策)。
from langchain_ollama import OllamaLLM
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import JsonOutputParser
from langchain_core.runnables import RunnablePassthrough
from pydantic import BaseModel, Field
from typing import Dict
import os
# 输出模型(结构化审批结果)
class ApprovalDecision(BaseModel):
decision: str = Field(..., description="approve/reject/manual")
reason: str = Field(..., description="决策理由")
confidence: float = Field(..., ge=0, le=1, description="置信度")
# 加载本地Ollama模型
llm = OllamaLLM(model="phi3-rules", base_url="http://localhost:11434")
# 提示模板(单一审批逻辑,嵌入规则)
prompt = ChatPromptTemplate.from_template(
"""你是一个专属审批智能体。只分析企业审批请求,无其他输出。
规则: {rules}
申请内容: {input}
严格输出JSON格式: {{"decision": "approve/reject/manual", "reason": "简要理由", "confidence": 0.95}}
"""
)
# 构建链:输入 → 提示 → LLM → JSON解析
chain = (
{"rules": RunnablePassthrough(), "input": RunnablePassthrough()}
| prompt
| llm
| JsonOutputParser(pydantic_object=ApprovalDecision)
)
def approve_request(rules: str, request: str) -> Dict:
"""单一入口:执行审批"""
try:
result = chain.invoke({"rules": rules, "input": request})
return result
except Exception as e:
return {"decision": "manual", "reason": f"代理错误: {str(e)}", "confidence": 0.0}
# 示例测试
if __name__ == "__main__":
rules = "企业A: 请假天数<3自动批准; 金额>5000需人工。"
req = "员工张三请假2天,报销100元。"
print(approve_request(rules, req))测试:python approval_agent.py。输出示例:
{'decision': 'approve', 'reason': '天数符合规则,无高额报销', 'confidence': 0.95}🌐 步骤3:部署Python服务(Flask微服务)
创建app.py(暴露REST API,支持Spring调用)。
from flask import Flask, request, jsonify
from approval_agent import approve_request # 导入代理
from flask_cors import CORS # 跨域支持
app = Flask(__name__)
CORS(app) # 允许Spring前端调用
@app.route('/approve', methods=['POST'])
def approve():
data = request.json
rules = data.get('rules', '')
request_content = data.get('request', '')
result = approve_request(rules, request_content)
return jsonify(result)
@app.route('/health', methods=['GET'])
def health():
return jsonify({"status": "healthy"})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=True)运行:python app.py(服务启动:http://localhost:5000)。测试API:
curl -X POST http://localhost:5000/approve \
-H "Content-Type: application/json" \
-d '{"rules": "天数<3: approve", "request": "请假1天"}'☁️ 步骤4:接入Spring Cloud Alibaba(FlowMind项目)
4.1 添加依赖(在flowmind-modules/flowmind-flowable/pom.xml)
<dependencies>
<!-- Spring AI (可选,用于备用) -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-http-spring-boot-starter</artifactId>
</dependency>
<!-- RestTemplate增强 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>4.2 配置Nacos服务发现(注册Python服务)
- 在
application.yml(flowmind-cloud模块)添加:spring: cloud: nacos: discovery: server-addr: localhost:8848 # 您的Nacos application: name: flowmind-flowable management: endpoints: web: exposure: include: health,info - Python服务注册:用Python Nacos客户端(pip install nacos-sdk-python),在
app.py启动时注册(可选,简化用固定URL)。
4.3 创建审批服务类(AiApprovalService.java)
在flowmind-flowable模块创建服务,调用Python API(用RestTemplate)。
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Map;
@Service
public class AiApprovalService {
private final RestTemplate restTemplate = new RestTemplate();
private final ObjectMapper objectMapper = new ObjectMapper();
@Value("${ai.python.service.url:http://localhost:5000}")
private String pythonUrl; // 从配置加载,支持Nacos动态
public Map<String, Object> processApproval(String enterpriseId, String requestContent) {
// 从DB加载规则(您的ApprovalRuleRepository)
String rules = loadRulesFromDb(enterpriseId); // 实现:查询MySQL
// 构建请求
Map<String, String> requestBody = Map.of("rules", rules, "request", requestContent);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<Map<String, String>> entity = new HttpEntity<>(requestBody, headers);
try {
ResponseEntity<String> response = restTemplate.postForEntity(
pythonUrl + "/approve", entity, String.class
);
return objectMapper.readValue(response.getBody(), Map.class);
} catch (Exception e) {
return Map.of("decision", "manual", "reason", "API调用失败: " + e.getMessage(), "confidence", 0.0);
}
}
private String loadRulesFromDb(String enterpriseId) {
// 示例:从JPA仓库查询
// return approvalRuleRepository.findByEnterpriseId(enterpriseId).stream()
// .map(r -> r.getCondition() + ": " + r.getAction())
// .collect(Collectors.joining("; "));
return "企业" + enterpriseId + ": 请假天数<3自动批准; 金额>5000需人工。"; // 占位
}
}4.4 配置Sentinel(流量控制)
在application.yml添加:
spring:
cloud:
sentinel:
enabled: true
transport:
dashboard: localhost:8718 # Sentinel Dashboard
datasource:
ds1:
nacos:
server-addr: localhost:8848
data-id: flowmind-flowable-rules # 规则文件
group-id: SENTINEL_GROUP
data-type: json
rule-type: flow # 限流规则:/approve QPS<104.5 集成到Flowable工作流
- 在BPMN设计器(您的流程设计)添加服务任务:
- 委托表达式:
${aiApprovalService.processApproval(execution.getVariable('enterpriseId'), execution.getVariable('requestContent'))}
- 委托表达式:
- 添加独占网关:
- 条件:
${aiApprovalServiceResult.decision == 'approve'}→ 结束节点 ${aiApprovalServiceResult.decision == 'reject'}→ 拒绝分支- 否则 → 人工审批任务
- 条件:
- 部署流程:用Flowable UI上传BPMN。
4.6 UI扩展(Vue3前端)
在审批中心组件(flowmind-ui)添加按钮:
<template>
<el-button @click="callAiApprove">AI决策</el-button>
<div v-if="aiResult">{{ aiResult.reason }} (置信: {{ aiResult.confidence }})</div>
</template>
<script>
import axios from 'axios';
export default {
data() { return { aiResult: {} }; },
methods: {
async callAiApprove() {
const res = await axios.post('/api/flowable/ai-approve', { /* params */ });
this.aiResult = res.data;
}
}
};
</script>后端Controller:转发到AiApprovalService。
🧪 步骤5:测试与监控
5.1 端到端测试
- 启动全栈:Nacos、MySQL、Ollama、Python Flask、Spring Boot。
- 发起流程:用FlowMind UI提交请假申请(天数=2)。
- 验证:检查日志/AI输出 → 自动批准。变体(天数=5)→ 人工。
- API测试:Postman调用Spring
/api/flowable/ai-approve。
5.2 监控
- Sentinel:Dashboard查看QPS/阻塞。
- Ollama日志:
tail -f ~/.ollama/logs监控推理。 - 性能:JMeter压测,目标<500ms/决策。
常见问题
- VRAM不足:降batch_size=1,或用Gemma-2B替换Phi-3。
- Nacos注册:Python用
nacos-sdk-python:client = NacosClient(...) ; client.add_naming_instance(...)。 - 更新规则:改DB → 增量微调 → 重载Ollama。
📚 结论与扩展
恭喜!您已实现本地隐私智能审批体,并无缝接入Spring Cloud Alibaba。总代码<200行,易维护。扩展想法:
- 多代理:用LangGraph添加历史查询工具。
- 容器化:Docker打包Python + Ollama,Kubernetes部署。
- 资源:参考LangChain Docs (langchain.com, 2025版) 和 Spring AI Guide。
如果代码报错或需调试,提供日志我帮忙优化。享受智能审批! 🚀