今天我引入了Kafka消息队列将音频识别改造为异步处理架构实现了“秒回”接口的削峰填谷。import sys import os import json from confluent_kafka import Producer, Consumer sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))) producer Producer({bootstrap.servers: 127.0.0.1:9092}) def submit_audio_task(file_path, session_id): task {file_path: file_path, session_id: session_id} producer.produce(audio_recognize, keysession_id, valuejson.dumps(task)) producer.flush() print(f【Producer】已发送任务: {task}) return f任务已提交: {session_id} consumer Consumer({ bootstrap.servers: 127.0.0.1:9092, group.id: recognize-workers-final, auto.offset.reset: earliest }) consumer.subscribe([audio_recognize]) def process_audio_worker(): 消费者从队列取任务 执行指纹提取和匹配 from src.utils.fingerprint import fingerprint_file from src.db.database import get_db from src.db.matcher import match_song from src.utils.cache import save_session print(Worker 已启动 等待任务...) while True: msg consumer.poll(1.0) if msg is None: continue if msg.error(): print(f【Consumer 报错】: {msg.error()}) continue task json.loads(msg.value().decode(utf-8)) print(f\n【Kafka收到消息】: {task}) print(f正在处理任务: {task[session_id]}) try: hashes fingerprint_file(task[file_path]) db next(get_db()) result match_song(db, hashes) save_session(task[session_id], { status: completed, result: result }) print(f任务完成: {task[session_id]}) except Exception as e: print(f【Worker 真实报错】: {repr(e)}) save_session(task[session_id], { status: error, error: str(e) }) if __name__ __main__: process_audio_worker()接着 我改造server.py为异步接口from fastapi import FastAPI, UploadFile, File, HTTPException from fastapi.middleware.cors import CORSMiddleware import shutil, os, tempfile, uvicorn, hashlib from uuid import uuid4 from src.utils.fingerprint import fingerprint_file from src.db.database import init_db, get_db from src.db.matcher import store_fingerprints, match_song from src.utils.cache import get_cached_result, cache_song_result, redis_lock, increment_song_play, get_session from src.utils.kafka_processor import submit_audio_task app FastAPI(title听歌识曲, version1.0) app.add_middleware( CORSMiddleware, allow_origins[*], allow_methods[*], allow_headers[*], ) app.on_event(startup) def startup(): init_db() app.get(/) def root(): return {status: ok, message: 听歌识曲 Agent API} app.post(/fingerprint) async def add_song(file: UploadFile File(...), song_name: str unknown): 同步接口提取指纹并存入 MySQL tmp tempfile.NamedTemporaryFile(deleteFalse, suffix.mp3) shutil.copyfileobj(file.file, tmp) tmp.close() try: hashes fingerprint_file(tmp.name) db next(get_db()) song_id store_fingerprints(db, song_name, hashes, tmp.name) return {song_id: song_id, song_name: song_name, hashes_count: len(hashes)} except Exception as e: raise HTTPException(status_code500, detailstr(e)) finally: os.unlink(tmp.name) app.post(/recognize) async def recognize(file: UploadFile File(...)): 异步识别提交任务到Kafka 立即返回 session_id session_id str(uuid4()) file_path fdata/uploads/{session_id}.wav os.makedirs(data/uploads, exist_okTrue) with open(file_path, wb) as f: content await file.read() f.write(content) try: submit_audio_task(file_path, session_id) except Exception as e: raise HTTPException(status_code500, detailfKafka 提交失败: {str(e)}) return {session_id: session_id, status: processing} app.get(/result/{session_id}) def get_result(session_id: str): 前端轮询拿 session_id 来查结果 result get_session(session_id) return result or {status: processing} if __name__ __main__: uvicorn.run(app, host127.0.0.1, port8010, wsnone)运行结果为今天我为系统加上了四道防线死循环检测、工具调用熔断、幻觉防护、数据安全让它从“能跑”进化为“生产可用”。import time import json from collections import defaultdict class DeadLoopDetector: 检测 Agent 死循环 def __init__(self, max_steps25, max_repeats3): self.max_steps max_steps self.max_repeats max_repeats self.step_count 0 self.action_history [] def check(self, action): self.step_count 1 if self.step_count self.max_steps: raise Exception(f超过最大步数 {self.max_steps}疑似死循环) self.action_history.append(action) recent self.action_history[-self.max_repeats:] if len(recent) self.max_repeats and len(set(recent)) 1: raise Exception(f连续重复动作 {self.max_repeats} 次疑似死循环) print(f [死循环检测] 通过当前步数: {self.step_count}) class CircuitBreaker: 熔断器工具连续失败自动熔断 def __init__(self, threshold5, timeout10): self.failure_count defaultdict(int) self.threshold threshold self.timeout timeout self.circuit_open defaultdict(float) def call_with_retry(self, func, args, retries3): name func.__name__ if self.circuit_open[name] 0: if time.time() - self.circuit_open[name] self.timeout: raise Exception(f工具 {name} 已熔断请稍后再试) else: self.circuit_open[name] 0 self.failure_count[name] 0 for i in range(retries): try: result func(*args) self.failure_count[name] 0 return result except Exception as e: self.failure_count[name] 1 print(f [熔断器] 工具 {name} 第 {i1} 次失败: {e}) if self.failure_count[name] self.threshold: self.circuit_open[name] time.time() raise Exception(f工具 {name} 达到熔断阈值已熔断) time.sleep(0.5) raise Exception(f重试 {retries} 次后仍失败) def validate_output(output, expected_schema): 验证 LLM 输出是否符合预期的 JSON 格式 try: data json.loads(output) for key in expected_schema: if key not in data: return False, f缺少字段: {key} return True, 验证通过 except json.JSONDecodeError: return False, JSON 格式错误 class SafeOperations: 安全操作所有写操作需要确认 审计日志 audit_log [] classmethod def safe_delete(cls, db, model, item_id): 安全删除软删除 审计日志 item db.query(model).filter(model.id item_id).first() if not item: raise Exception(记录不存在) cls.audit_log.append({ action: delete, model: str(model), id: item_id, time: time.time() }) if hasattr(item, is_deleted): item.is_deleted True else: db.delete(item) db.commit() print(f [安全操作] 已安全删除记录 {item_id}审计日志已记录) if __name__ __main__: print( 测试 1死循环检测 ) detector DeadLoopDetector(max_steps5, max_repeats3) try: for i in range(6): detector.check(search_song) except Exception as e: print(f成功拦截死循环: {e}) print(\n 测试 2熔断器 ) breaker CircuitBreaker(threshold3, timeout5) def faulty_tool(): raise Exception(数据库连接超时) try: breaker.call_with_retry(faulty_tool, [], retries5) except Exception as e: print(f成功触发熔断: {e}) print(\n 测试 3输出验证防幻觉 ) # 测试正确的输出 is_valid, msg validate_output({song: 晴天, artist: 周杰伦}, [song, artist]) print(f正确输出验证: {is_valid}, {msg}) # 测试缺少字段的输出 is_valid, msg validate_output({song: 晴天}, [song, artist]) print(f缺失字段验证: {is_valid}, {msg})运行结果为测试通过。
企业数字化 ERP 产品动态
相关推荐
TCP协议栈管理、文件符表映射机制与TCP资源关闭流程介绍 文章目录
一、进程与内核
1.用户态的Java程序进程
2.内核态的操作系统内核
2.1操作系统
2.1.1内核
二、文件描述符与表引用
1.文件描述符
2.文件描述符表
3.引用比例
三、TCP资源管理与连接维护
1.TCP协议栈
1.1TCB
1.1.1端点
1.1.1.1TCP连接状态
四、Socket引用… · 2026/9/24 17:52:44
基于 Java Spring Boot 的幼儿早教微信小程序设计与实现 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片!
1. 引言
随着移动互联网的普及和微信生态的快速发展,微信小程序凭借其即用即走、无需下载安装、传播便捷等优势,已成为教育服务领域的重要载体。… · 2026/9/24 17:52:44
视频素材格式转换:多款视频转换工具能力客观记录 自媒体素材整理、课件转码、监控视频归档时,经常遇到视频格式不兼容、平台上传受限的问题。批量转格式、压缩体积、提取音频、转 GIF,不同工具支持的格式种类、批量上限、编码自定义范围差别较大。下文客观记录多款视频转换工具基础能力与使用边界&#… · 2026/9/24 17:52:38
OPNET混合组网仿真:AODV与LTE协同实践 简介:面向无线网络研究与工程仿真场景,这份OPNET仿真资源针对AODV路由协议在LTE Ad Hoc(D2D)网络中难以快速复现和评估的问题,适合网络协议研究者、通信方向学生及OPNET使用者参考。压缩包内含aodv_route_table、aodv_… · 2026/9/24 19:44:35
JavaWeb超市会员管理系统:JSP+Servlet+JDBC毕设实战解析 简介:这是一套基于Javaweb的超市会员管理系统毕业设计项目,面向计算机相关专业正在做毕设的学生,以及需要项目实战练习的Java学习者,也可作为课程设计或期末大作业使用。系统采用JSP、Servlet、JDBC配合MySQL数据库,开… · 2026/9/24 19:44:35
交互动效设计从入门到实践:参数、规范与性能优化指南 交互动效设计这个词,圈外人听着可能觉得就是“让界面动起来”,但在实际项目里,它远不止加个过渡动画那么简单。我做了几年UI和动效相关的工作,最大的感受是:动效做得好,用户会觉得很顺手、很自然࿰… · 2026/9/24 19:44:35
基于OPNET的LTE与Ad Hoc融合网络AODV路由仿真实践 简介:面向需要开展无线自组织网络协议仿真的研究人员与工程师,这是一套基于OPNET Modeler的AODV路由协议仿真工程,重点覆盖LTE与Ad Hoc融合场景下的按需路由发现与性能评估。包内完整包含OPNET工程源码、协议模块(AODV路由表与地理… · 2026/9/24 19:44:35
使用Qt和C++开发宝可梦回合制小游戏:从状态机到信号槽实践 简介:一份基于 Qt 框架的 C 2D 角色扮演游戏源码,面向初学 Qt 和游戏开发的人群,以《宝可梦》核心玩法为蓝本,完整实现了世界探索、宝可梦养成、回合制战斗与玩家管理四大系统。资源共 20 个文件,以 9 个 cpp 与 8 个 … · 2026/9/24 19:44:35
2026 H5生成工具实战指南:从跨端分发到生态适配 1. 这不是工具清单,而是一份H5生产流水线的实战地图 你搜“2026年10大H5生成工具推荐”,点开一堆图文并茂的榜单,结果发现全是三年前的老版本截图、参数模糊的“一键生成”宣传语、以及根本找不到下载入口的“官方链接”。更尴尬的是&#x… · 2026/9/24 19:44:28
基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程 简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为… · 2026/9/24 0:00:13
1D-CNN时间序列建模实战:从Conv1d原理到工业落地 简介:面向时间序列数据建模的一维卷积神经网络完整实现,适合深度学习入门者及需要快速验证时序模型的研究者,能够从音频、文本、传感器或股价等序列中挖掘局部特征与时间依赖。压缩包体积很小,只有3KB,内含3个Python脚… · 2026/9/24 0:00:26
柔软的L:汉语语流中被忽视的舌肌张力控制 1. 这个“L”不是字母表里的L,而是舌尖上的L最近在几个方言群和语音教学社群里,反复看到有人发一句:“也说字母L:柔软的长舌”。初看以为是英语发音课笔记,点开才发现全是方言爱好者、播音系学生、语言康复师甚至戏曲演… · 2026/9/24 0:00:44