Files
assist/src/analytics/__pycache__/ai_success_monitor.cpython-311.pyc

131 lines
25 KiB
Plaintext
Raw Normal View History

<EFBFBD>
<00>3<EFBFBD>h:Z<00><00><><00>dZddlZddlZddlmZmZmZmZmZddl m Z m
Z
ddl m Z ddl mZddlZddlmZdd lmZdd
lmZdd lmZeje<19><00>Ze Gd <0C>d <0A><00><00><00>ZGd<0E>d<0F><00>ZdS)uM
AI调用成功率监控模块
监控AI API调用的成功率和性能指标
<EFBFBD>N)<05>Dict<63>List<73>Optional<61>Any<6E>Tuple)<02>datetime<6D> timedelta)<01> dataclass)<01> defaultdict<63>)<01>
db_manager)<01>Alert)<01> redis_manager)<01>Configc<00><><00>eZdZUdZeed<eed<eeed<eed<eed<e ed<e
ed<eeed <eeed
<eed <eed <d S)<0E>APICalluAPI调用记录<E8AEB0> timestamp<6D>user_id<69> work_order_id<69>
model_name<EFBFBD>endpoint<6E>success<73> response_time<6D> status_code<64> error_message<67> input_length<74> output_lengthN) <0B>__name__<5F>
__module__<EFBFBD> __qualname__<5F>__doc__r<00>__annotations__<5F>strr<00>int<6E>bool<6F>float<61><00><00>9d:\code\tsp-assistant\src\analytics\ai_success_monitor.pyrrs<><00><00><00><00><00><00><00><19><19><17><17><17><17> <10>L<EFBFBD>L<EFBFBD>L<EFBFBD><1B>C<EFBFBD>=<3D> <20> <20> <20><13>O<EFBFBD>O<EFBFBD>O<EFBFBD><11>M<EFBFBD>M<EFBFBD>M<EFBFBD> <11>M<EFBFBD>M<EFBFBD>M<EFBFBD><18><18><18><18><19>#<23><1D><1E><1E><1E><1B>C<EFBFBD>=<3D> <20> <20> <20><15><15><15><15><16><16><16><16><16>r(rc<00><><00>eZdZdZd<02>Zd<03>Z d+dedeeded ed
e d e
d eed eededede fd<11>Z de fd<13>Z de fd<14>Zdedefd<15>Zdedefd<17>Zd,dedede
fd<1A>Zd,dedede
fd<1B>Zdededefd<1F>Zd-dededeeeffd!<21>Zd"e
d#e
defd$<24>Zd-dedeeeffd%<25>Zd.d'edeeeeffd(<28>Zd/d'edefd*<2A>ZdS)0<>AISuccessMonitoruAI调用成功率监控器c<00>P<00>dddddd<06>|_ddd <09>dd
d <09>d d d <09>d dd <09>d<0F>|_dS)Ngffffff<66>?g$@g<><67><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<3F><00>
)<05>success_rate_min<69>avg_response_time_max<61>error_rate_max<61>consecutive_failures_max<61>hourly_failures_maxg\<5C><><EFBFBD>(\<5C>?g@)<02> success_raterg@g<><67><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?g @g333333<33>?g(@)<04> excellent<6E>good<6F>fair<69>poor)<02>
thresholds<EFBFBD>performance_levels<6C><01>selfs r)<00>__init__zAISuccessMonitor.__init__(sd<00><00>!%<25>%)<29>"<22>()<29>#%<25> 
<EFBFBD>
<EFBFBD><04><0F>+/<2F><13>E<>E<>%)<29>C<EFBFBD>@<40>@<40>%)<29>C<EFBFBD>@<40>@<40>%)<29>D<EFBFBD>A<>A<> #
<EFBFBD>#
<EFBFBD><04><1F><1F>r(c<00>(<00>tj<00><00>S)u获取Redis客户端)r<00>get_connectionr;s r)<00>_get_redis_clientz"AISuccessMonitor._get_redis_client:s<00><00><1C>+<2B>-<2D>-<2D>-r(Nrrrrrrrrrrr<00>returnc <00>d<00> ttj<00><00>||||||||| |
<EFBFBD><01> <00> } |<00>| <0B><00>|<00>| <0B><00>t
<00>d|<03>d|rdnd<05><00><04><00>| S#t$r(} t
<00>d| <0C><00><02><00>Yd} ~ dSd} ~ wwxYw)u记录API调用) rrrrrrrrrrruAPI调用记录: z - u成功u失败u记录API调用失败: N) rr<00>now<6F>_save_to_redis<69>_check_thresholds<64>logger<65>info<66> Exception<6F>error) r<rrrrrrrrrr<00>api_call<6C>es r)<00>record_api_callz AISuccessMonitor.record_api_call>s<><00><00> <18><1E>"<22>,<2C>.<2E>.<2E><1F>+<2B>%<25>!<21><1F>+<2B>'<27>+<2B>)<29>+<2B> <0E> <0E> <0E>H<EFBFBD> <11> <1F> <1F><08> )<29> )<29> )<29> <11> "<22> "<22>8<EFBFBD> ,<2C> ,<2C> ,<2C> <12>K<EFBFBD>K<EFBFBD>^<5E>J<EFBFBD>^<5E>^<5E>w<EFBFBD>;\<5C>8<EFBFBD>8<EFBFBD>T\<5C>^<5E>^<5E> _<> _<> _<><1B>O<EFBFBD><4F><18> <18> <18> <18> <12>L<EFBFBD>L<EFBFBD>6<>1<EFBFBD>6<>6<> 7<> 7<> 7<><17>4<EFBFBD>4<EFBFBD>4<EFBFBD>4<EFBFBD>4<EFBFBD><34><EFBFBD><EFBFBD><EFBFBD> <18><><EFBFBD>s<00>A:A=<00>=
B/<03>B*<03>*B/rJc <00><><00>|<00><00><00>}|sdS |j<00><00><00>}|j|j|j|j|j|j|j|j |j
|j d<02>
}|<02> dtj|d<04><05><00>|i<01><00>|<02> d|j<00><00>tj|d<04><05><00>|i<01><00>|<02> d|j<00><00>tj|d<04><05><00>|i<01><00>|<02>dd<08><00>dS#t $r(}t"<00>d |<05><00><02><00>Yd}~dSd}~wwxYw)
u保存到RedisN)
rrrrrrrrrr<00>api_calls:dailyF)<01> ensure_ascii<69>api_calls:model:zapi_calls:user:i<00>'u保存API调用到Redis失败: )r@rrrrrrrrrrr<00>zadd<64>json<6F>dumps<70>expirerHrFrI)r<rJ<00> redis_clientr<00> call_datarKs r)rDzAISuccessMonitor._save_to_redishs<><00><00><1B>-<2D>-<2D>/<2F>/<2F> <0C><1B> <13> <12>F<EFBFBD># @<01> <20>*<2A>4<>4<>6<>6<>I<EFBFBD>#<23>+<2B>!)<29>!7<>&<26>1<>$<24>-<2D>#<23>+<2B>!)<29>!7<>'<27>3<>!)<29>!7<> (<28> 5<>!)<29>!7<> <0E> <0E>I<EFBFBD> <19> <1D> <1D>!<21><15><1A>I<EFBFBD>E<EFBFBD>:<3A>:<3A>:<3A>I<EFBFBD>F<> <0E> <0E> <0E>
<19> <1D> <1D>8<>8<EFBFBD>#6<>8<>8<><15><1A>I<EFBFBD>E<EFBFBD>:<3A>:<3A>:<3A>I<EFBFBD>F<> <0E> <0E> <0E>
<19> <1D> <1D>4<>(<28>"2<>4<>4<><15><1A>I<EFBFBD>E<EFBFBD>:<3A>:<3A>:<3A>I<EFBFBD>F<> <0E> <0E> <0E> <19> <1F> <1F> 1<>><3E> B<> B<> B<> B<> B<><42><18> @<01> @<01> @<01> <12>L<EFBFBD>L<EFBFBD>><3E>1<EFBFBD>><3E>><3E> ?<3F> ?<3F> ?<3F> ?<3F> ?<3F> ?<3F> ?<3F> ?<3F> ?<3F><><EFBFBD><EFBFBD><EFBFBD> @<01><><EFBFBD>s<00>DD<00>
E<03>(E <03> Ec<00><><00> |<00>|j<00><00>}||jdkr#|<00>dd|j<00>d|<02>d<05>d<06><00>|<00>|j<00><00>}||jdkr|<00>dd |<03><00>d
<EFBFBD><00>|<00>|jd <0B> <0C><00>}||jd kr#|<00>dd|j<00>d|d<10><04>d
<EFBFBD><00>|<00>|jd <0B> <0C><00>}||jdkr&|<00>dd|j<00>d|d<14>d<15>d
<EFBFBD><00>dSdS#t$r(}t<00>
d|<06><00><02><00>Yd}~dSd}~wwxYw)u检查阈值并触发预警r2<00>consecutive_failuresu模型 u 连续失败 u<>criticalr3<00>high_hourly_failuresu每小时失败次数过多: <20>warning<6E><00><01>hoursr/<00>low_success_rateu 成功率过低: z.2%r0<00> slow_responseu 响应时间过长: z.2fu秒u检查阈值失败: N) <0B>_get_consecutive_failuresrr9<00>_trigger_alert<72>_get_hourly_failuresr<00>_get_recent_success_rate<74>_get_avg_response_timerHrFrI)r<rJrX<00>hourly_failuresr4<00>avg_response_timerKs r)rEz"AISuccessMonitor._check_thresholds<64>s<><00><00>& 5<>#'<27>#A<>#A<>(<28>BU<42>#V<>#V<> <20>#<23>t<EFBFBD><EFBFBD>7Q<37>'R<>R<>R<><14>#<23>#<23>*<2A>[<5B>h<EFBFBD>1<>[<5B>[<5B>AU<41>[<5B>[<5B>[<5B><1E><12><12><12>#<23>7<>7<><08>8J<38>K<>K<>O<EFBFBD><1E>$<24>/<2F>2G<32>"H<>H<>H<><14>#<23>#<23>*<2A>E<>O<EFBFBD>E<>E<><1D><12><12><12> <20>8<>8<><18>9L<39>TU<54>8<>V<>V<>L<EFBFBD><1B>d<EFBFBD>o<EFBFBD>.@<40>A<>A<>A<><14>#<23>#<23>&<26>W<>h<EFBFBD>1<>W<>W<>\<5C>W<>W<>W<><1D><12><12><12>!%<25> ;<3B> ;<3B>H<EFBFBD><O<>WX<57> ;<3B> Y<> Y<> <1D> <20>4<EFBFBD>?<3F>3J<33>#K<>K<>K<><14>#<23>#<23>#<23>b<>h<EFBFBD>1<>b<>b<>HY<48>b<>b<>b<>b<><1D><12><12><12><12><12>L<01>K<><4B><19> 5<> 5<> 5<> <12>L<EFBFBD>L<EFBFBD>3<><01>3<>3<> 4<> 4<> 4<> 4<> 4<> 4<> 4<> 4<> 4<><34><EFBFBD><EFBFBD><EFBFBD> 5<><35><EFBFBD>s<00>D4D:<00>:
E,<03>E'<03>'E,c<00>~<00> |<00><00><00>}|sdS|<02>d|<01><00>ddd<04><05><00>}d}|D]M\}} tj|<05><00>}|<07>dd<04><00>s|dz }nn<16>9#tj$rY<00>JwxYw|S#t $r(}t<00>d|<08><00><02><00>Yd }~dSd }~wwxYw)
u获取连续失败次数rrP<00> T<><01>
withscoresrr\u 获取连续失败次数失败: N) r@<00> zrevrangerR<00>loads<64>get<65>JSONDecodeErrorrHrFrI) r<rrU<00> recent_callsrXrV<00>_<>callrKs r)raz*AISuccessMonitor._get_consecutive_failures<65>s&<00><00> <15><1F>1<>1<>3<>3<>L<EFBFBD><1F> <19><18>q<EFBFBD>(<28>1<>1<>/<2F>:<3A>/<2F>/<2F><11><11><1F> 2<><0E><0E>L<EFBFBD>$%<25> <20> ,<2C> <1D> <1D> <0C> <09>1<EFBFBD><1D><1F>:<3A>i<EFBFBD>0<>0<>D<EFBFBD><1F>8<EFBFBD>8<EFBFBD>I<EFBFBD>t<EFBFBD>4<>4<><1E>,<2C><01>1<>,<2C>,<2C><1D><05>-<2D><><1C>+<2B><1D><1D><1D><1C>H<EFBFBD><1D><><EFBFBD><EFBFBD>(<28> '<27><><18> <15> <15> <15> <12>L<EFBFBD>L<EFBFBD>?<3F>A<EFBFBD>?<3F>?<3F> @<40> @<40> @<40><14>1<EFBFBD>1<EFBFBD>1<EFBFBD>1<EFBFBD>1<EFBFBD><31><EFBFBD><EFBFBD><EFBFBD> <15><><EFBFBD>s@<00>B
<00>%B
<00>0A3<02>0B
<00>3B<05>B
<00>B<05>B
<00>
B<<03>B7<03>7B<rc<00><00> |<00><00><00>}|sdS|<01>ddd<01><02><00>}|td<03><04><00>z}|<03><00><00>}|<04><00><00>}|<02>d||d<06><07><00>}d}|D]J\} }
t j| <09><00>} | <0B>dd<06><00>s|dz }<08>6#t
j$rY<00>GwxYw|S#t$r(} t<00> d | <0C><00><02><00>Yd
} ~ dSd
} ~ wwxYw) u获取每小时失败次数r)<03>minute<74>second<6E> microsecondr\r]rNTrjru#获取每小时失败次数失败: N) r@<00>replacer r<00> zrangebyscorerRrmrnrorHrFrI) r<rrU<00>
hour_start<EFBFBD>hour_end<6E>
start_time<EFBFBD>end_time<6D>calls<6C>failuresrVrqrrrKs r)rcz%AISuccessMonitor._get_hourly_failures<65>s[<00><00> <15><1F>1<>1<>3<>3<>L<EFBFBD><1F> <19><18>q<EFBFBD>"<22>*<2A>*<2A>!<21>A<EFBFBD>1<EFBFBD>*<2A>M<>M<>J<EFBFBD>!<21>I<EFBFBD>A<EFBFBD>$6<>$6<>$6<>6<>H<EFBFBD>#<23>-<2D>-<2D>/<2F>/<2F>J<EFBFBD><1F>)<29>)<29>+<2B>+<2B>H<EFBFBD> <20>.<2E>.<2E>!<21><1A><18><1F> /<2F><0E><0E>E<EFBFBD><19>H<EFBFBD> %<25> <1D> <1D> <0C> <09>1<EFBFBD><1D><1F>:<3A>i<EFBFBD>0<>0<>D<EFBFBD><1F>8<EFBFBD>8<EFBFBD>I<EFBFBD>t<EFBFBD>4<>4<>&<26> <20>A<EFBFBD> <0A><08><><EFBFBD><1B>+<2B><1D><1D><1D><1C>H<EFBFBD><1D><><EFBFBD><EFBFBD><1C>O<EFBFBD><4F><18> <15> <15> <15> <12>L<EFBFBD>L<EFBFBD>B<>q<EFBFBD>B<>B<> C<> C<> C<><14>1<EFBFBD>1<EFBFBD>1<EFBFBD>1<EFBFBD>1<EFBFBD><31><EFBFBD><EFBFBD><EFBFBD> <15><><EFBFBD>sA<00>C<00>A5C<00>/C<02>?C<00>C<05>C<00>C<05>C<00>
D <03>!D<03>D r\r^c<00>j<00> |<00><00><00>}|sdStj<00><00><00><00><00>}tj<00><00>t |<02><02><00>z
<00><00><00>}|<03>d|<01><00>||d<04><05><00>}|sdSd}t |<06><00>}|D]J\} }
tj| <09><00>} | <0B> dd<04><00>r|d z }<07>6#tj
$rY<00>GwxYw|dkr||z ndS#t$r(} t<00> d
| <0C><00><02><00>Yd } ~ dSd } ~ wwxYw) u获取最近成功率<E58A9F>r]rPTrjg<00>?rrr\u获取成功率失败: N)r@rrCrr rx<00>lenrRrmrnrorHrFrI) r<rr^rUr|r{r}<00>successful_calls<6C> total_callsrVrqrrrKs r)rdz)AISuccessMonitor._get_recent_success_rates<><00><00>! <17><1F>1<>1<>3<>3<>L<EFBFBD><1F> <1B><1A>s<EFBFBD><1F>|<7C>~<7E>~<7E>/<2F>/<2F>1<>1<>H<EFBFBD>"<22>,<2C>.<2E>.<2E>9<EFBFBD>5<EFBFBD>+A<>+A<>+A<>A<>L<>L<>N<>N<>J<EFBFBD> <20>.<2E>.<2E>/<2F>:<3A>/<2F>/<2F><1A><18><1F> /<2F><0E><0E>E<EFBFBD><19> <1B><1A>s<EFBFBD> <20> <1C><1D>e<EFBFBD>*<2A>*<2A>K<EFBFBD> %<25> <1D> <1D> <0C> <09>1<EFBFBD><1D><1F>:<3A>i<EFBFBD>0<>0<>D<EFBFBD><1B>x<EFBFBD>x<EFBFBD> <09>4<EFBFBD>0<>0<>.<2E>(<28>A<EFBFBD>-<2D>(<28><><EFBFBD><1B>+<2B><1D><1D><1D><1C>H<EFBFBD><1D><><EFBFBD><EFBFBD>6A<01>1<EFBFBD>_<EFBFBD>_<EFBFBD>#<23>k<EFBFBD>1<>1<>#<23> M<><4D><18> <17> <17> <17> <12>L<EFBFBD>L<EFBFBD>6<>1<EFBFBD>6<>6<> 7<> 7<> 7<><16>3<EFBFBD>3<EFBFBD>3<EFBFBD>3<EFBFBD>3<EFBFBD><33><EFBFBD><EFBFBD><EFBFBD> <17><><EFBFBD>sG<00>D<00>A9D<00>D<00>./C<02>D<00>C0<05>-D<00>/C0<05>0D<00>
D2<03>
D-<03>-D2c<00>f<00> |<00><00><00>}|sdStj<00><00><00><00><00>}tj<00><00>t |<02><02><00>z
<00><00><00>}|<03>d|<01><00>||d<04><05><00>}|sdSd}d}|D]U\} }
t j| <09><00>} | <0B>dd<06><00>} | dkr
|| z }|dz }<08>A#t j $rY<00>RwxYw|dkr||z ndS#t$r(} t<00> d | <0A><00><02><00>Yd
} ~ dSd
} ~ wwxYw) u获取平均响应时间r<E997B4>r]rPTrjrrr\u 获取平均响应时间失败: N) r@rrCrr rxrRrmrnrorHrFrI)r<rr^rUr|r{r}<00>
total_time<EFBFBD>countrVrqrrrrKs r)rez'AISuccessMonitor._get_avg_response_time%s<><00><00># <17><1F>1<>1<>3<>3<>L<EFBFBD><1F> <1B><1A>s<EFBFBD><1F>|<7C>~<7E>~<7E>/<2F>/<2F>1<>1<>H<EFBFBD>"<22>,<2C>.<2E>.<2E>9<EFBFBD>5<EFBFBD>+A<>+A<>+A<>A<>L<>L<>N<>N<>J<EFBFBD> <20>.<2E>.<2E>/<2F>:<3A>/<2F>/<2F><1A><18><1F> /<2F><0E><0E>E<EFBFBD><19> <1B><1A>s<EFBFBD><1C>J<EFBFBD><15>E<EFBFBD> %<25> <1D> <1D> <0C> <09>1<EFBFBD><1D><1F>:<3A>i<EFBFBD>0<>0<>D<EFBFBD>$(<28>H<EFBFBD>H<EFBFBD>_<EFBFBD>a<EFBFBD>$@<40>$@<40>M<EFBFBD>$<24>q<EFBFBD>(<28>(<28>"<22>m<EFBFBD>3<>
<EFBFBD><1D><11>
<EFBFBD><05><><EFBFBD><1B>+<2B><1D><1D><1D><1C>H<EFBFBD><1D><><EFBFBD><EFBFBD>*/<2F><11><19><19>:<3A><05>%<25>%<25><03> ;<3B><><18> <17> <17> <17> <12>L<EFBFBD>L<EFBFBD>?<3F>A<EFBFBD>?<3F>?<3F> @<40> @<40> @<40><16>3<EFBFBD>3<EFBFBD>3<EFBFBD>3<EFBFBD>3<EFBFBD><33><EFBFBD><EFBFBD><EFBFBD> <17><><EFBFBD>sG<00>C><00>A9C><00> C><00>!:C<02>C><00>C.<05>+C><00>-C.<05>.C><00>>
D0<03>D+<03>+D0<03>
alert_type<EFBFBD>message<67>severityc
<00><><00> td|<01><00>||||dtj<00><00><00><03><00>}tj<00><00>5}|<05>|<04><00>|<05><00><00>ddd<04><00>n #1swxYwYt<00>d|<02><00><02><00>dS#t$r(}t<00>
d|<06><00><02><00>Yd}~dSd}~wwxYw)u 触发预警uAI成功率监控_T)<07> rule_namer<65><00>levelr<6C>r<><00> is_active<76>
created_atNuAI成功率监控预警: u%触发AI成功率监控预警失败: ) rrrCr <00> get_session<6F>add<64>commitrFr[rHrI)r<r<>r<>r<><00>alert<72>sessionrKs r)rbzAISuccessMonitor._trigger_alertLs7<00><00> F<01><19>;<3B>z<EFBFBD>;<3B>;<3B>%<25><1E>!<21><1F><1E>#<23><<3C>><3E>><3E><0E><0E><0E>E<EFBFBD><1C>'<27>)<29>)<29> !<21>W<EFBFBD><17> <0B> <0B>E<EFBFBD>"<22>"<22>"<22><17><0E><0E> <20> <20> <20> !<21> !<21> !<21> !<21> !<21> !<21> !<21> !<21> !<21> !<21> !<21><><EFBFBD><EFBFBD> !<21> !<21> !<21> !<21> <13>N<EFBFBD>N<EFBFBD>@<40>w<EFBFBD>@<40>@<40> A<> A<> A<> A<> A<><41><18> F<01> F<01> F<01> <12>L<EFBFBD>L<EFBFBD>D<><11>D<>D<> E<> E<> E<> E<> E<> E<> E<> E<> E<><45><EFBFBD><EFBFBD><EFBFBD> F<01><><EFBFBD>s:<00>=B<00>*A5<03>) B<00>5A9<07>9B<00><A9<07>= B<00>
C<03>)C <03> C<03>c<00><><00> |<00><00><00>}|siStj<00><00><00><00><00>}tj<00><00>t |<02><01><00>z
<00><00><00>}|<03>d|<01><00>||d<03><04><00>}|s |dddddd<08>St |<06><00>dddgtt<00><00>d <09>}|D]<5D>\}} tj
|<08><00>}
|
<EFBFBD> d
d<03><00>r|d xxd z cc<n<|d xxd z cc<|
<EFBFBD> dd<07><00>} |d| xxd z cc<|
<EFBFBD> dd<05><00>} | dkr+|dxx| z cc<|d<00> | <0C><00><00><>#tj $rY<00><>wxYw|ddkr|d |dz nd} |dr|dt |d<00><00>z nd}|ddkr|d |dz nd}|<00>| |<0E><00>}||d|d |d t| d<14><00>t|d<15><00>t|d<14><00>|t!t#|d<00><00><00><00><00>dd<17><00><00>d<18> S#t&$r)}t(<00>d|<11><00><02><00>icYd}~Sd}~wwxYw)u获取模型性能指标r]rPTrjrr<><00>unknown)rr<>r4rg<00>
error_rate<EFBFBD>performance_level)r<>r<><00> failed_calls<6C>total_response_time<6D>response_times<65>errorsrr<>r\r<>rr<>rr<>r<>r<><00>r Nr-) rr<>r<>r<>r4rgr<>r<><00>
top_errorsu获取模型性能失败: )r@rrCrr rxr<>r r$rRrmrn<00>appendro<00>_determine_performance_level<65>round<6E>dict<63>list<73>itemsrHrFrI)r<rr^rUr|r{r}<00>statsrVrqrr<00> error_msgrr4rgr<>r<>rKs r)<00>get_model_performancez&AISuccessMonitor.get_model_performancebs<><00><00>K <16><1F>1<>1<>3<>3<>L<EFBFBD><1F> <1A><19> <09><1F>|<7C>~<7E>~<7E>/<2F>/<2F>1<>1<>H<EFBFBD>"<22>,<2C>.<2E>.<2E>9<EFBFBD>5<EFBFBD>+A<>+A<>+A<>A<>L<>L<>N<>N<>J<EFBFBD> <20>.<2E>.<2E>/<2F>:<3A>/<2F>/<2F><1A><18><1F> /<2F><0E><0E>E<EFBFBD><19> <12>",<2C>#$<24>$'<27>),<2C>"%<25>)2<> <12><12><12> #<23>5<EFBFBD>z<EFBFBD>z<EFBFBD>$%<25> !<21>'*<2A>"$<24>%<25>c<EFBFBD>*<2A>*<2A> <0E><0E>E<EFBFBD>!&<26> <1D> <1D> <0C> <09>1<EFBFBD><1D><1F>:<3A>i<EFBFBD>0<>0<>D<EFBFBD><1B>x<EFBFBD>x<EFBFBD> <09>4<EFBFBD>0<>0<>8<><1D>0<>1<>1<>1<>Q<EFBFBD>6<>1<>1<>1<>1<><1D>n<EFBFBD>-<2D>-<2D>-<2D><11>2<>-<2D>-<2D>-<2D>$(<28>H<EFBFBD>H<EFBFBD>_<EFBFBD>i<EFBFBD>$H<>$H<> <09><1D>h<EFBFBD><0F> <09>2<>2<>2<>a<EFBFBD>7<>2<>2<>2<>$(<28>H<EFBFBD>H<EFBFBD>_<EFBFBD>a<EFBFBD>$@<40>$@<40>M<EFBFBD>$<24>q<EFBFBD>(<28>(<28><1D>3<>4<>4<>4<> <0A>E<>4<>4<>4<><1D>.<2E>/<2F>6<>6<>}<7D>E<>E<>E<><45><EFBFBD><1B>+<2B><1D><1D><1D><1C>H<EFBFBD><1D><><EFBFBD><EFBFBD>PU<01>Ub<55>Oc<4F>fg<66>Og<4F>Og<4F>5<EFBFBD>!3<>4<>u<EFBFBD>]<5D>7K<37>K<>K<>mn<6D>L<EFBFBD>_d<5F>eu<65>_v<5F> }<7D><05>&;<3B> <<3C>s<EFBFBD>5<EFBFBD>IY<49>CZ<43>?[<5B>?[<5B> [<5B> [<5B>|}<7D> <1D>IN<49>}<7D>I]<5D>`a<>Ia<49>Ia<49><15>~<7E>.<2E><15>}<7D>1E<31>E<>E<>gh<67>J<EFBFBD>!%<25> A<> A<>,<2C>Pa<50> b<> b<> <1D>)<29>$<24>]<5D>3<>$)<29>*<<3C>$=<3D> %<25>n<EFBFBD> 5<> %<25>l<EFBFBD>A<EFBFBD> 6<> 6<>%*<2A>+<<3C>a<EFBFBD>%@<40>%@<40>#<23>J<EFBFBD><01>2<>2<>%6<>"<22>4<EFBFBD><05>h<EFBFBD><0F>(=<3D>(=<3D>(?<3F>(?<3F>#@<40>#@<40><12>!<21><12>#D<>E<>E<>
<0E>
<0E>
<0E><><19> <16> <16> <16> <12>L<EFBFBD>L<EFBFBD>9<>a<EFBFBD>9<>9<> :<3A> :<3A> :<3A><15>I<EFBFBD>I<EFBFBD>I<EFBFBD>I<EFBFBD>I<EFBFBD>I<EFBFBD><49><EFBFBD><EFBFBD><EFBFBD> <16><><EFBFBD>sO<00>J<00>BJ<00>/J<00> B>F <02>
J<00> F<05>J<00>F<05>DJ<00>
K<03>(K <03>K<03> Kr4rgc<00>|<00>|j<00><00><00>D]!\}}||dkr||dkr|cS<00>"dS)u确定性能等级r4rr8)r:r<>)r<r4rgr<>r9s r)r<>z-AISuccessMonitor._determine_performance_level<65>sV<00><00>!%<25>!8<>!><3E>!><3E>!@<40>!@<40> <1D> <1D> <1D>E<EFBFBD>:<3A><1B>z<EFBFBD>.<2E>9<>9<>9<>>O<>S]<5D>^m<>Sn<53>>n<>>n<><1C> <0C> <0C> <0C><><15>vr(c <00><><00> |<00><00><00>}|siStj<00><00><00><00><00>}tj<00><00>t |<01><01><00>z
<00><00><00>}|<02>d||d<03><04><00>}|sddddid<07>St |<05><00>dddt<00><00>tt<00><00>tt<00><00>d<08>}|D<00>]*\}} tj |<07><00>} | <09> d d<03><00>r|d
xxd z cc<n|d xxd z cc<| <09> d d<05><00>}
|
dkr|dxx|
z cc<|d<00> | <09> dd<11><00><00><00>|d| <09> dd<14><00>xxd z cc<tj|<08><00><00>d<15><00>} |d| xxd z cc<<00><01>#tj$rY<00><01>(wxYw|ddkr|d
|dz nd} |ddkr|d|dz nd} |d|d
|d t#| d<18><00>t#| d<19><00>t |d<00><00>t%|d<00><00>t%|d<00><00>d<1A>S#t&$r)}t(<00>d|<0E><00><02><00>icYd}~Sd}~wwxYw)u获取系统整体性能r]rNTrjrr<>)r<>r4rg<00> unique_users<72>model_distribution)r<>r<>r<>r<>r<>r<><00>hourly_distributionrr<>r\r<>rr<>r<>r<00>r<>rr<>z%H:00r<30>r<>r<>r )r<>r<>r<>r4rgr<>r<>r<>u获取系统性能失败: N)r@rrCrr rxr<><00>setr r$rRrmrnr<><00> fromtimestamp<6D>strftimeror<>r<>rHrFrI)r<r^rUr|r{r}r<>rVrrrr<00>hourr4rgrKs r)<00>get_system_performancez'AISuccessMonitor.get_system_performance<63>s<><00><00>J <16><1F>1<>1<>3<>3<>L<EFBFBD><1F> <1A><19> <09><1F>|<7C>~<7E>~<7E>/<2F>/<2F>1<>1<>H<EFBFBD>"<22>,<2C>.<2E>.<2E>9<EFBFBD>5<EFBFBD>+A<>+A<>+A<>A<>L<>L<>N<>N<>J<EFBFBD> <20>.<2E>.<2E>!<21><1A><18><1F> /<2F><0E><0E>E<EFBFBD><19> <12>#$<24>$'<27>),<2C>$%<25>*,<2C> <12><12><12> #<23>5<EFBFBD>z<EFBFBD>z<EFBFBD>$%<25> !<21>'*<2A> #<23><05><05>&1<>#<23>&6<>&6<>'2<>3<EFBFBD>'7<>'7<><0E><0E>E<EFBFBD>).<2E> <1D> <1D>$<24> <09>9<EFBFBD><1D><1F>:<3A>i<EFBFBD>0<>0<>D<EFBFBD><1B>x<EFBFBD>x<EFBFBD> <09>4<EFBFBD>0<>0<>3<><1D>0<>1<>1<>1<>Q<EFBFBD>6<>1<>1<>1<>1<><1D>n<EFBFBD>-<2D>-<2D>-<2D><11>2<>-<2D>-<2D>-<2D>$(<28>H<EFBFBD>H<EFBFBD>_<EFBFBD>a<EFBFBD>$@<40>$@<40>M<EFBFBD>$<24>q<EFBFBD>(<28>(<28><1D>3<>4<>4<>4<> <0A>E<>4<>4<>4<><19>.<2E>)<29>-<2D>-<2D>d<EFBFBD>h<EFBFBD>h<EFBFBD>y<EFBFBD>"<22>.E<>.E<>F<>F<>F<><19>.<2E>/<2F><04><08><08><1C>y<EFBFBD>0Q<30>0Q<30>R<>R<>R<>VW<56>W<>R<>R<>R<>$<24>1<>)<29><<3C><<3C>E<>E<>g<EFBFBD>N<>N<>D<EFBFBD><19>/<2F>0<><14>6<>6<>6<>!<21>;<3B>6<>6<>6<>6<><36><1B>+<2B><1D><1D><1D><1C>H<EFBFBD><1D><><EFBFBD><EFBFBD>PU<01>Ub<55>Oc<4F>fg<66>Og<4F>Og<4F>5<EFBFBD>!3<>4<>u<EFBFBD>]<5D>7K<37>K<>K<>mn<6D>L<EFBFBD>W\<5C>]j<>Wk<57>no<6E>Wo<57>Wo<57><05>&;<3B> <<3C>u<EFBFBD>]<5D>?S<> S<> S<>uv<75> <1D> %<25>]<5D>3<>$)<29>*<<3C>$=<3D> %<25>n<EFBFBD> 5<> %<25>l<EFBFBD>A<EFBFBD> 6<> 6<>%*<2A>+<<3C>a<EFBFBD>%@<40>%@<40> #<23>E<EFBFBD>.<2E>$9<> :<3A> :<3A>&*<2A>5<EFBFBD>1E<31>+F<>&G<>&G<>'+<2B>E<EFBFBD>2G<32>,H<>'I<>'I<> <0E> <0E> <0E><><19> <16> <16> <16> <12>L<EFBFBD>L<EFBFBD>9<>a<EFBFBD>9<>9<> :<3A> :<3A> :<3A><15>I<EFBFBD>I<EFBFBD>I<EFBFBD>I<EFBFBD>I<EFBFBD>I<EFBFBD><49><EFBFBD><EFBFBD><EFBFBD> <16><><EFBFBD>sP<00>J=<00>A=J=<00>AJ=<00>(D G7<02>5J=<00>7H
<05>J=<00> H
<05>
B2J=<00>=
K0<03>K+<03>%K0<03>+K0<03><00>daysc
<00>T<00> g}t|<01><00>D<00>]C}tj<00><00><00><00><00>t |<03><01><00>z
}tj|tj<00><00><00><00><00>}tj|tj<00><00><00><00><00>}|<05> <00><00>}|<06> <00><00>}|<00>
<00><00>} | s.|<02> |<04> <00><00>dddd<04><04><00><00><01>| <09> d||d<06><07><00>}
|
s.|<02> |<04> <00><00>dddd<04><04><00><00><01>Pd} d} |
D]k\} } tj| <0A><00>}|<0F>dd<06><00>r| d z } |<0F>d
d<02><00>}|dkr| |z } <0C>W#tj$rY<00>hwxYw|
r| t%|
<EFBFBD><00>z nd}|
r| t%|
<EFBFBD><00>z nd}|<02> |<04> <00><00>t%|
<EFBFBD><00>t'|d <0B><00>t'|d <0C><00>d<04><04><00><00><02>Et)t+|<02><00><00><00>S#t,$r)}t.<00>d |<13><00><02><00>gcYd}~Sd}~wwxYw)u获取性能趋势<E8B68B>r<>rr<>)<04>dater<65>r4rgrNTrjrr\rr<>r u获取性能趋势失败: N)<19>rangerrCr<>r <00>combine<6E>min<69>time<6D>maxrr@r<><00> isoformatrxrRrmrnror<>r<>r<><00>reversedrHrFrI)r<r<><00>
trend_data<EFBFBD>ir<69><00> day_start<72>day_endr{r|rUr}r<>r<>rVrqrrrr4rgrKs r)<00>get_performance_trendz&AISuccessMonitor.get_performance_trends<00><00>C <16><1B>J<EFBFBD><1A>4<EFBFBD>[<5B>[<5B>: <13>: <13><01><1F>|<7C>~<7E>~<7E>*<2A>*<2A>,<2C>,<2C>y<EFBFBD>a<EFBFBD>/@<40>/@<40>/@<40>@<40><04>$<24>,<2C>T<EFBFBD>8<EFBFBD><<3C>3D<33>3D<33>3F<33>3F<33>G<>G<> <09>"<22>*<2A>4<EFBFBD><18><1C>1B<31>1B<31>1D<31>1D<31>E<>E<><07>&<26>0<>0<>2<>2<>
<EFBFBD>"<22>,<2C>,<2C>.<2E>.<2E><08>#<23>5<>5<>7<>7<> <0C>#<23><1D><1E>%<25>%<25> $<24><0E><0E> 0<> 0<>'(<28>(+<2B>-0<> '<16>'<16><17><17><17> <1D>$<24>2<>2<>%<25><1E><1C>#<23> 3<><12><12><05><1D><1D><1E>%<25>%<25> $<24><0E><0E> 0<> 0<>'(<28>(+<2B>-0<> '<16>'<16><17><17><17> <1D>#$<24> <20>&)<29>#<23>$)<29> !<21> !<21>L<EFBFBD>I<EFBFBD>q<EFBFBD>
!<21>#<23>z<EFBFBD>)<29>4<>4<><04><1F>8<EFBFBD>8<EFBFBD>I<EFBFBD>t<EFBFBD>4<>4<>2<>,<2C><01>1<>,<2C>(,<2C><08><08><1F>!<21>(D<>(D<> <0A>(<28>1<EFBFBD>,<2C>,<2C>/<2F>=<3D>@<40>/<2F><><EFBFBD><1F>/<2F>!<21>!<21>!<21> <20><08>!<21><><EFBFBD><EFBFBD>AF<01>L<>/<2F>#<23>e<EFBFBD>*<2A>*<2A><<3C><<3C>1<EFBFBD> <0C>HM<48>$T<>$7<>#<23>e<EFBFBD>*<2A>*<2A>$D<>$D<>ST<53>!<21><1A>!<21>!<21> <20>N<EFBFBD>N<EFBFBD>,<2C>,<2C>#&<26>u<EFBFBD>:<3A>:<3A>$)<29>,<2C><01>$:<3A>$:<3A>).<2E>/@<40>!<21>)D<>)D<> #<12>#<12><13><13><13><13><18><08><1A>,<2C>,<2C>-<2D>-<2D> -<2D><><18> <16> <16> <16> <12>L<EFBFBD>L<EFBFBD>9<>a<EFBFBD>9<>9<> :<3A> :<3A> :<3A><15>I<EFBFBD>I<EFBFBD>I<EFBFBD>I<EFBFBD>I<EFBFBD>I<EFBFBD><49><EFBFBD><EFBFBD><EFBFBD> <16><><EFBFBD>sD<00>E,I4<00>/AG<04>?I4<00>G<07>I4<00>G<07>B!I4<00>4
J'<03>>J"<03>J'<03>"J'<03>c<00>:<00> |<00><00><00>}|sdStj<00><00>t|<01><02><00>z
<00><00><00>}|<02>dd|<03><00>}|<02>d<04><00>}|D]}|<02>|d|<03><00><00>|<02>d<05><00>}|D]}|<02>|d|<03><00><00>t<00>d|<04><00><02><00>|S#t$r(}t<00>
d|<08><00><02><00>Yd}~dSd}~wwxYw) u清理旧数据rr<>rNzapi_calls:model:*zapi_calls:user:*u,清理AI成功率监控数据成功: 数量=u%清理AI成功率监控数据失败: N) r@rrCr r<00>zremrangebyscore<72>keysrFrGrHrI) r<r<>rU<00> cutoff_time<6D> removed_count<6E>
model_keys<EFBFBD>key<65> user_keysrKs r)<00>cleanup_old_dataz!AISuccessMonitor.cleanup_old_dataMsX<00><00> <15><1F>1<>1<>3<>3<>L<EFBFBD><1F> <19><18>q<EFBFBD>#<23><<3C>><3E>><3E>I<EFBFBD>4<EFBFBD>,@<40>,@<40>,@<40>@<40>K<>K<>M<>M<>K<EFBFBD>)<29>9<>9<>!<21><11><1B><0E><0E>M<EFBFBD>&<26>*<2A>*<2A>+><3E>?<3F>?<3F>J<EFBFBD>!<21> C<01> C<01><03><1C>-<2D>-<2D>c<EFBFBD>1<EFBFBD>k<EFBFBD>B<>B<>B<>B<>%<25>)<29>)<29>*<<3C>=<3D>=<3D>I<EFBFBD> <20> C<01> C<01><03><1C>-<2D>-<2D>c<EFBFBD>1<EFBFBD>k<EFBFBD>B<>B<>B<>B<> <12>K<EFBFBD>K<EFBFBD>V<>}<7D>V<>V<> W<> W<> W<> <20> <20><><18> <15> <15> <15> <12>L<EFBFBD>L<EFBFBD>D<><11>D<>D<> E<> E<> E<><14>1<EFBFBD>1<EFBFBD>1<EFBFBD>1<EFBFBD>1<EFBFBD><31><EFBFBD><EFBFBD><EFBFBD> <15><><EFBFBD>s<00>C(<00>C C(<00>(
D<03>2D<03>D)NNrr)r\)r<>)r<>)r<>)rrr r!r=r@r#rr$r%r&rrLrDrErarrcrdrerbrrr<>r<>r<>rr<>r<>r'r(r)r+r+%s<><00><00><00><00><00><00>$<24>$<24>
<EFBFBD>
<EFBFBD>
<EFBFBD>$.<2E>.<2E>.<2E>&*<2A>'+<2B><1D><1E>(<18>(<18><14>(<18> <20><03>}<7D>(<18><18> (<18>
<16> (<18> <16> (<18><1D>(<18><1E>c<EFBFBD>]<5D>(<18> <20><03>}<7D>(<18><1A>(<18><1B>(<18>
<11>(<18>(<18>(<18>(<18>T)@<01>w<EFBFBD>)@<01>)@<01>)@<01>)@<01>V(5<>'<27>(5<>(5<>(5<>(5<>T<15>C<EFBFBD><15>C<EFBFBD><15><15><15><15>@!<15>h<EFBFBD>!<15>3<EFBFBD>!<15>!<15>!<15>!<15>F#<17>#<17>3<EFBFBD>#<17>s<EFBFBD>#<17>5<EFBFBD>#<17>#<17>#<17>#<17>J%<17>%<17><13>%<17>S<EFBFBD>%<17><15>%<17>%<17>%<17>%<17>NF<01><13>F<01>s<EFBFBD>F<01>c<EFBFBD>F<01>F<01>F<01>F<01>,M<16>M<16><03>M<16>C<EFBFBD>M<16><14>c<EFBFBD>SV<53>h<EFBFBD><1E>M<16>M<16>M<16>M<16>^<16><15><16>SX<53><16>]`<60><16><16><16><16>L<16>L<16>C<EFBFBD>L<16><14>c<EFBFBD>3<EFBFBD>h<EFBFBD><1E>L<16>L<16>L<16>L<16>\E<16>E<16>#<23>E<16>d<EFBFBD>4<EFBFBD><03>S<EFBFBD><08>><3E>6J<36>E<16>E<16>E<16>E<16>N<15><15>S<EFBFBD><15>#<23><15><15><15><15><15>r(r+)r!rR<00>logging<6E>typingrrrrrrr <00> dataclassesr
<00> collectionsr r<><00> core.databaser <00> core.modelsr<00>core.redis_managerr<00> config.configr<00> getLoggerrrFrr+r'r(r)<00><module>r<>sZ<00><01><04><04>
 <0C> <0B> <0B> <0B><0E><0E><0E><0E>3<>3<>3<>3<>3<>3<>3<>3<>3<>3<>3<>3<>3<>3<>(<28>(<28>(<28>(<28>(<28>(<28>(<28>(<28>!<21>!<21>!<21>!<21>!<21>!<21>#<23>#<23>#<23>#<23>#<23>#<23> <0B> <0B> <0B> <0B>&<26>&<26>&<26>&<26>&<26>&<26><1F><1F><1F><1F><1F><1F>.<2E>.<2E>.<2E>.<2E>.<2E>.<2E>"<22>"<22>"<22>"<22>"<22>"<22> <1A><17> <1A>8<EFBFBD> $<24> $<24><06>
<EFBFBD> <17> <17> <17> <17> <17> <17> <17> <0B><19> <17>G <15>G <15>G <15>G <15>G <15>G <15>G <15>G <15>G <15>G r(