From d9f37d6816a1ad3921251365648f4a0701120dbb Mon Sep 17 00:00:00 2001 From: jinye_huang Date: Sun, 27 Apr 2025 15:57:59 +0800 Subject: [PATCH] =?UTF-8?q?=E9=80=89=E9=A2=98=E7=AE=A1=E7=90=86=E5=99=A8?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E5=A2=9E=E5=8A=A0=E4=BA=86=E6=A8=A1=E7=B3=8A?= =?UTF-8?q?=E5=8C=B9=E9=85=8D=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poster_gen_config.json | 4 +- resource/Object/美的鹭湖鹭栖台酒店.txt | 1 + .../prompt_manager.cpython-312.pyc | Bin 28187 -> 26480 bytes utils/prompt_manager.py | 537 +++++++++--------- 4 files changed, 267 insertions(+), 275 deletions(-) diff --git a/poster_gen_config.json b/poster_gen_config.json index 718cc5e..1dfde84 100644 --- a/poster_gen_config.json +++ b/poster_gen_config.json @@ -1,7 +1,7 @@ { "date": "4月29日,4月30日, 4月28日, 5月1日", - "num": 15, - "variants": 15, + "num": 1, + "variants": 2, "topic_temperature": 0.2, "topic_top_p": 0.3, "topic_presence_penalty": 1.5, diff --git a/resource/Object/美的鹭湖鹭栖台酒店.txt b/resource/Object/美的鹭湖鹭栖台酒店.txt index f070db5..186ee1a 100644 --- a/resource/Object/美的鹭湖鹭栖台酒店.txt +++ b/resource/Object/美的鹭湖鹭栖台酒店.txt @@ -1,3 +1,4 @@ +主体:美的鹭湖鹭栖台酒店 【佛山·盈香心动乐园X美的鹭湖鹭栖台酒店】周末不加收!浪漫四季花海,萌宠乐园惬意度假~50+机动游戏项目全体验!399元美的鹭栖台高级房+大阳台观景+2大2小两天无限次盈香生态园门票+童话牧场、森林剧场、无动力乐园、机动乐园畅玩,加100元还可升级全新网红项目芭比飞车、飞毯上山全包 【价格】:399 元r diff --git a/utils/__pycache__/prompt_manager.cpython-312.pyc b/utils/__pycache__/prompt_manager.cpython-312.pyc index 3cb2e163e425d3e71c612f458441ffc9638f0f82..51fed845adb35d3b9781d7e29d3d126482f05ed0 100644 GIT binary patch delta 10120 zcmeHNYgAj;mA+T+7f2w11QJN%CB)NUW6Z-i5Wv{R7_c2XegtE#4A>yZl?XPyik#MI zaK?#6ZxTc76qreB^0Jk>O_aEaNv6{>=`_8vNF-~RRc942>5qxyxNDkpty#0r)x%)B zkJb4xe@1Ju?>Xo0v-jC&pMB0g-{tHae)AJN_E#}65)6K8eize~);|)f!5c#lH>j}Jn7gt<*j`yAvFSxW#(Z@~Zg@m$H43rCh zUq8pkuroBi%TRz*_*v{F&g*!H4adY-C+6T$T#`$19X#t36o+)$BSPrkHYIQli|Hp+ z%9v;$@_?OB9}uVD9D3E7B++tS`sQkt_^#e^)Ejs&tkDa34nD=RCDQIzJw3io%*C-| zw4>Efz_Tku8FUE11|cP=#rCIRm_xKo znkdqr5FV+;FdKdWnJ+*U5CKAks2sj4@$%oPKhZo zAsT|N$(Td3tfwTxONfqSvr3cgDG?2X_yk5tYO&W*12Q|p3}efWj4d`Q0tUE&hg_E_ zp@b`4*Nr)(6c5JpDvU=)NF6bhjCM7v=;IY4sU!9-KN!L06uvYGG~Qv7--k&lmqms| ztYFV@C@49lKqip_Du$2^#em`%tDX|VAd;ahp(GL64^Xj>q3KQpMq!BYl#Yi%O&WH@ zD^v_6rDT;bpi{5I8!1_5PlpQoqohA*VGYTEV8Gspjk-FHiVKa(5f3FHGRF}^Ki;a> z%c*!+G72gNW+}ReaEywlVh(Y(V`$Np#6>KFmB;Pi;8+L8!5_rZF?&{6F_wXmX%3}5 z93U8WIGcVnLFtUAlq+ZdVT@2Zl#eTqaYN5Rd=NXzeHa_W&8mTM=q@pYe+w7iU3}rG z`O9xFxSmkJ1Q<(s3tpY<#nZ0&56&(OkIi3x7K8x9yywlOi z;R4HYugn`~f3o=OEA#JPx$)de0a0nK7W)8cy~`x~Kz|R|HG_7UhG zNCn=-kl@o7!G`(wo(;Pz?4q~LoF)?O=>tNtAbz-Zb@HGmSEf|iS!67$sIr{<~_&R=NDJ5G`)(MIYCarsvzEBLz)c+ zQUi}~#g&~FtL11vSv6GAOgj5|`|VrXt?iu_vfxm+m1v7DrnW-^Lqo^fdfV+CT?Lgr zeI4yRwyJ_??=v9GhIYRt?2pH>t9iR;il%mZ;y%l-_jLL5>zVv|Z{F^2Z0H#IZn6$% zeG;19(3FK{${C&Og(ok4@!W-_i_erB*xCL99lR^13t53S)~{ti&`c3H+9tMxp-t=z zlNC@k<3aqW4NY^{U{PgHd+$M_y=thunY`Ov=U=rq-1(;<(1wO|9GkA5ZvU|MI7Wgy zkUH)W%dr8p!!39I;;?Js>G3ar_C(0Qkj>?WKg0na3L zR@(gK%k%F)zi{fw1=s7*DT?eKZ->;fo6z#!OIMz{G4&4+B-8 zpuNA}VkLrnvfbKg33A(eddLDKbQS8x?QK6A$1qFF_% z5hKsq?(DS$#nB}fd@Pz(awLPh*gkl)`<+HFA*O!HtLN!Wrs)DXnGgTioAP>Pt_ zY#n{1#YV10viWQ!C}Cgp^bJ}_vJ|x|*oMJwdsp9pz0IOOY7a^dT5R^vItTu~0SE%b z6vQny6^#>W+PzWWO#bu1F_eApy1M_e>Vpy3UV(Ld9J{T-#ER3hlQKrV-a~jEViIa+ zMRhlM58`6&bxrc{rfYIlKxZ5gUyDmVM~*uO#|Fn8V~(kZXZ59X**O;_uS(oyzU=j% z>3SxLejfiz^@r+Trhb?@+uZ7J-sNrH+y1+afGM?L5;k z(lEMrD#NEL9IgwflZG1tnv`1@Hzvo$n^z{f>~z`aqxAZKN_S@4$hL{vPgUldLU?;y zh9zpxtsb?XEt`0BY`rhRj5_7J@IZ3v=%W*H6GfBC(Oj2s4rC0{l@moiWyTvy*gBZz zU9)++KQ-@WMLI#|#!ppwNM`Oj6^lZ0k({rcD{%63}Jd!jv(^ zE>S>}dWU>RBGOD9YH>8riztKGG}^fHgpn_lTpukohW_|j_` zg<&o|a~Vs6FMYkI-J9-wz@J|4O|SQ*HvrFdWjbRjy{as|u1Xqh9oaHc2g)<@Zeg4R z)2J|@O&ec7w*Ksfsl!*b>%fTTdGk?M(>=U5e2JU^ZowOA<&iP2pqC{ZP`RO%#pAxcJCvM2)z%Gwd*kMR*cV@=XytJQi>@oDS{8Y|iIc<<6$G#puP90p}ii1p8 zl}2&j;6}2_eIVGuUQS3A#V0r@LnY;ObEaCrV~-B{bAg)Y!byT|SLx{wl2r7#DN)Lc z^mhm%?J)w16Kxf;t-sAu(O*i%^gC)JT_}?ZC=qF(L`e7#GyN{r$3<@v4iRW>xl1!&j8Y2d zzFH}cOcKFivubIGHC~E1C>Wg`o8X^b$WJ0FrC5Swer6 z++Ff2PVR&rLH>68u^tQ5c0g?a9f*tPUR(O!`=P^&eHl6WOn;y^=4DHTg=}kKlR1uV z*JaAk$rI$kMs5QyjOcVuvJRw#POAnenPs8FLSjRj+E6MS442tmTH4Xx(Pasr7E(4_ zu@G$_k3=gsC=PW)XIr>ef4jYlM2SmK7U5EQkK* zl&&4Hji|MwYy8?guQt!GE%IuMeA?B%#5KdxK#I|yQt3^p^z51W4wF*pOWErcB@ato zJ3p5uj+RUmy;v4ds{P6guQFp|uUA>b$ckX=kSXYrQllnGJFXs6kL$*C6W#7)UsC1p zX3(XGr$5m*I2G}y2Tu;3cARvKK0GTo1+sGdS#{p5y6MBrJ`0mo=gT_eRiwLQqn2w* z{Y2eV^*?S3Z)N8zCoA1zPbKVKuEx34Jb!AHH?_(``BEEQ8?UKTudmxM%JXZ?UX6Jw z$Ezs`lvhXVd0tKFTyFlwQs=9s{@e<0ZiT1Om%C}k=*?|pG}(cwx(F+iQ|{GN1oT;> zvGXGNY57Sxlf1^g$KA+0(7_O0e!}i0>`cc1Ge9vK$E@h_fLzIDP=7=8BQNaEjQ#%& z044%m$N!HvfD1VXw1;3IY@SYbLMbSywe+@I39=h1bXK0Bl7vkg8xj?U+EKKVDD@4c ziAPW=nuW4iBiV!6dJ$o_fw+6N0s6B%LsCCtcoY#fx+Mgw7P2imE?=o4?dZ(_A_stk z!Z(gk(%t!Mg?~UTY7YIQ{H{l$A)N2k=KHn9UTv{YyT+GTvOI+MGR=G07~Xf^7|!%6 zGbfICmBoy#n2lk-RO^#!=aRJaTdOphWZk%F%ru@imNzlvuJ9#q7~T>J=FU|sf_cxZ zJo`>CA7S=)vccT-mx5UWL72Yj{=pmyUWntIsR{_*Kt&CTP_|y_)vRNKIsg8_yrDkA z%0Q@VD%oJZEubrl3;ArQUYaRRv4)PWcG8w-*lDwn<%S`8s_s-1yZ^INSfNN%P`GV- z9ZB|)BsvmEv@Mefh~y$-LIf}?jEqHO6Cy2$v;v`r>rW=3K?LLA;@j5GUIA^P^MdT4 zb2eVVYcBnM<8Sz}$RalLK(HVStJ0n8YUq}xN_t`4W+4Y4R0YMM-K*8~*0OD@2%&=u ze?0i(!=HcfaXOMqL_h33S(=wXjAJ5VF1#H<=gSPkzkH3MTSF@V&@f|VNjx>&{8UrP5^ zY3VIhVi}RZ!i8!o_OO;kjO8H2l-P+ygxpCkPL%;#7z>bN2kdbQN@my5?`w3N!wBJ2 z$`uhtR$eB3e1|?g+U5ZG5J1WGgqo7E_Qr+n6(9)FtYKS|D8)($kw|vL;FuLh@THBR zV#!Ysw@J%#>y}SE8rJFf4o)Wki~Ef*y!aJ^qYF2PV@Eir(s`Ie2>>Q`I310-P(~@= zNQoHAW_T(`0;M7!r4oo#HW}?<4Tde$p;#d?K581J3S-Um$ODFZEUvo0#cTAe4F+T} zVWbkkZb4-J07+VI_sV6LNTjhn(^puJ9G{-C%<+j-A~^n4SoUggz6PA1bjSJYBF>K` zGQ(rnP)UE?{pH|?q^SE7SIo!X=>9A!afSQUtou!D>;2rX3A3$g2 z-{Jnmzrp>;;Qx*L?`!cIGi$@2cmEx`SGs>4k;C>}>3%iIrv#LmMf(LrF2y|ypL5`k z4}Suf?>u&A*cy9hfk0#aOCm=y#i5cBNFRpe;|G_O0G!W&ZIb-~IKRQ6wWE!k{Q)=+ z*E;|@>HjR#R~OjPHqZVjZDbkWgW4B5w2y0#@d)<047Fc1R7L+=O)l-*6E80qDtNHZ zYO|9A9d-b==wIy7O9~1K*z3ShHoal5iCaJp)6eWJa-IZzqydpMAVWg-)&kh%)2PXb znv`slp`*`gw^;3lLw%&dG$b<_tbM2gFj7HKZf_?$E%vtd0ixSt?XV1qLirFJb*fP5 zuI|!S%OML1tWHb0Bq-=Rco>lVdJ^5x0L~R`W9va_t;Nx)!A%HS0LIJOl zh~?eb#4iMlqu$H$$Cdiy@6#D367J&I01^y0#+4m((C9?!BH$=Ewo-SQ{XWsMP;_%4A@Y#jS z?*aIZz6YFna?#^~iCvr={@wBKN+bg)iIGTvdFlA~mc~ZrFTXPHd3y2Warl%me`Rv< ziHish9zHw&{yC6vfRQqN5rt0KwJp9T_!o0fM8_e zPN;;Fz8BDVP}GFba5gs#;lxOgEvP`Sz=1A65fCnb+CrBNS$NTfFoqxk!O)sNN+Hk4v=LX{pLn7olcZ$e*`#|?OQ$qhSB92!NLi3v!eQ&yocyh zM1iPrR<$*t&77w{BDOjc)PTSOsSlB4-S8H;e<;+WIbM0jRI+>HRdXdm4Tav6Re%~A zGW>>8uc6c<@fjX;#avSw0;!o3hbQ*ATZD-Nuo+d6gCcw@g-ewtuXwv5zAWtV#@Jo(cUld)q~wG(8grukFKyeVbAl#1b|Yx0zU)-)9h z$g11UBvrZuz@g0?FBmJB(zuI#$!mwV1m(%sof&3EVT5<)Tt<<}nzzntSO;ik+z#B; z5K!ySP$Sety-%IX6gFH{15lms*R1hs*0^`Sv+u2a)44OGucY-;&2~UIp$kB=X{EO? zVO*MPQ$U^e^1<_+lb!yowcf0??qj~J>Z|JNIeorgzrm~DFfI1!otsB_L9ITJx5mBK zy>&W%x^{Z)jEc!=8r?FdOCN6>Yn)o|(RyN-I>0@8nGP#s?wi&12Ue|NbotkG#+!0b z^_2<(z$L$C4yL_vq>)Ll^z8L)Wi~y`828Mo_JVZ};5+fpj5|HXm($LhCQbgdVsBcp zyXez2X9;86>DmnBdO@+jV5_%a>&y|R{RmUA)mPBtRpm0Oj0wxHra8TF96lrX^@U!2p&Kj#mp1wIO>?FaziFe_v~fo4Gqq0eg6XEf8g@K0@iVnE zYnhgvOz}e#Tjnxy&o@psI+@jtGka&YG7leNdIp#ykKM%J<9GuH9-BB#=+VI0h91Su zoZA?d*}@5|t7I}tu4S0P^rW1x;=y!eH@n={y1(P@Wgcu}G7ikD+QDvJ)_B!e)s)%Y z>eH?pZVbw`0lm>ByPlcDDAM44rqcxOU*Y!VyWBo?%%@%#(3t(2RbI_1x8@z)TRP8? znPOj2)2Etk$m`9l*H=fqp8hgK+Xgl`y)3K6PkJDREZe?_pKifVXcljYt1Cv}gE32PVru+#$Hi=We zwLJy<^_i;e#n^|5)vE2qPVA%H2h*YY3wgB|9=}XdBU)4~fyYcm*7j`PzZ$CrQ296; zz4;YZ!-vPO1uXX`3e@&VHp~5+;;ilYJVwKEd-dpzx3qc{Jbc+mny*;AqnzujDA`fM zoh{)*+01WJHif@-8_;1g48$y_9X^oE50D@i4rY=?2og~ndwjEp{+;vw9D4B% zBIv6*3-7T1AV3OG6%mw4+GzTlp8kffYd9@9Uwi8ir--k*bqFs8+J&q6##_Y)aenI8 z4ct8(eriYv>S`8|mysA2<9h{_%!q8J-|W@n74)xrHIfgY0Zu*4W}?6B)u{g+6aNR6 Q`(Hep2v5C*A<9boA1-#AlK=n! delta 11522 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 B?7{#5 diff --git a/utils/prompt_manager.py b/utils/prompt_manager.py index 372beb8..affb5c2 100644 --- a/utils/prompt_manager.py +++ b/utils/prompt_manager.py @@ -7,6 +7,7 @@ Manages the construction of prompts for different AI generation tasks. import os import traceback import logging # Add logging +import re # 添加正则表达式支持 from .resource_loader import ResourceLoader # Use relative import within the same package class PromptManager: @@ -107,6 +108,89 @@ class PromptManager: if content: self._refer_cache[filename] = content + def find_directory_fuzzy_match(self, name, directory=None, files=None): + """ + 对文件名进行模糊匹配,查找最匹配目标名称的文件 + + Args: + name: 目标名称 + directory: 目录路径,如果提供则从目录中读取文件列表 + files: 文件名列表,如果提供则直接使用 + + Returns: + tuple: (最佳匹配文件名, 匹配分数) 如果没有匹配则返回 (None, 0) + """ + logging.info(f"尝试对文件名进行模糊匹配: {name}") + + try: + # 准备文件列表 + all_files = [] + if files: + all_files = files + elif directory and os.path.isdir(directory): + all_files = [f for f in os.listdir(directory) if os.path.isfile(os.path.join(directory, f))] + + if not all_files: + logging.warning(f"没有可用于匹配的文件") + return None, 0 + + logging.info(f"找到 {len(all_files)} 个文件可用于模糊匹配") + + # 从名称中提取关键词 + # 通过常见分隔符分割(+、空格、_、-等) + parts = re.split(r'[+\s_\-]', name) + keywords = [] + for part in parts: + # 只保留长度大于1的有意义关键词 + if len(part) > 1: + keywords.append(part) + + # 尝试匹配更短的语义单元(例如中文的2-3个字的词语) + for i in range(len(name) - 1): + keyword = name[i:i+2] # 提取2个字符 + if len(keyword) == 2 and all('\u4e00' <= c <= '\u9fff' for c in keyword): + keywords.append(keyword) + + logging.info(f"用于文件模糊匹配的关键词: {keywords}") + + # 对每个文件进行评分 + file_scores = {} + for filename in all_files: + score = 0 + file_lower = filename.lower() + + # 精确匹配,去掉扩展名比较 + name_without_ext = os.path.splitext(name)[0].lower() + file_without_ext = os.path.splitext(filename)[0].lower() + + if name_without_ext == file_without_ext: + # 精确匹配给高分 + score += 10 + else: + # 为每个匹配的关键词增加分数 + for keyword in keywords: + if keyword.lower() in file_lower: + score += 1 + + # 如果得分大于0(至少有匹配),记录该文件 + if score > 0: + file_scores[filename] = score + + # 选择得分最高的文件 + if file_scores: + best_match = max(file_scores.items(), key=lambda x: x[1]) + found_file = best_match[0] + score = best_match[1] + logging.info(f"模糊匹配成功!匹配文件: {found_file},匹配分数: {score}") + return found_file, score + else: + logging.warning(f"模糊匹配未找到任何包含关键词的文件") + return None, 0 + + except Exception as e: + logging.exception(f"文件模糊匹配过程中出错: {e}") + return None, 0 + def _get_style_content(self, style_name): """获取Style文件内容,优先从缓存获取,如果不存在则尝试从目录加载""" # 首先检查缓存 @@ -121,35 +205,18 @@ class PromptManager: style_name = os.path.splitext(style_name)[0] # 移除扩展名 # 尝试模糊匹配缓存中的文件名 - for cache_key in self._style_cache.keys(): - cache_key_lower = cache_key.lower() - style_name_lower = style_name.lower() - - # 完全匹配 - if cache_key_lower == style_name_lower: - return self._style_cache[cache_key] - - # 部分匹配 - # 攻略风格 - if ("攻略" in style_name_lower or "干货" in style_name_lower) and "攻略" in cache_key_lower: - logging.info(f"模糊匹配 - 找到部分匹配的Style文件: '{cache_key}' 匹配 '{style_name}'") - return self._style_cache[cache_key] - # 轻奢风格 - if "轻奢" in style_name_lower and "轻奢" in cache_key_lower: - logging.info(f"模糊匹配 - 找到部分匹配的Style文件: '{cache_key}' 匹配 '{style_name}'") - return self._style_cache[cache_key] - # 推荐风格 - if ("推荐" in style_name_lower or "种草" in style_name_lower) and "推荐" in cache_key_lower: - logging.info(f"模糊匹配 - 找到部分匹配的Style文件: '{cache_key}' 匹配 '{style_name}'") - return self._style_cache[cache_key] - # 美食风格 - if "美食" in style_name_lower and "美食" in cache_key_lower: - logging.info(f"模糊匹配 - 找到部分匹配的Style文件: '{cache_key}' 匹配 '{style_name}'") - return self._style_cache[cache_key] + cache_files = list(self._style_cache.keys()) + matched_key, score = self.find_directory_fuzzy_match(style_name, files=cache_files) + + if matched_key and score > 0: + return self._style_cache[matched_key] # 如果没有在缓存中找到模糊匹配,尝试从prompts_dir加载 if self.prompts_dir: - style_path = os.path.join(self.prompts_dir, "Style", style_file) + style_dir = os.path.join(self.prompts_dir, "Style") + style_path = os.path.join(style_dir, style_file) + + # 精确路径匹配 if os.path.exists(style_path): content = ResourceLoader.load_file_content(style_path) if content: @@ -158,38 +225,21 @@ class PromptManager: self._style_cache[style_file] = content return content - # 如果直接加载失败,尝试列出目录中的所有文件并进行模糊匹配 - style_dir = os.path.join(self.prompts_dir, "Style") + # 如果精确匹配失败,尝试目录中的模糊匹配 if os.path.isdir(style_dir): - try: - files = os.listdir(style_dir) - style_name_lower = style_name.lower() - - for file in files: - file_lower = file.lower() - # 检查关键词匹配 - matched = False - if ("攻略" in style_name_lower or "干货" in style_name_lower) and "攻略" in file_lower: - matched = True - elif "轻奢" in style_name_lower and "轻奢" in file_lower: - matched = True - elif ("推荐" in style_name_lower or "种草" in style_name_lower) and "推荐" in file_lower: - matched = True - elif "美食" in style_name_lower and "美食" in file_lower: - matched = True - - if matched: - matched_path = os.path.join(style_dir, file) - logging.info(f"模糊匹配 - 在目录中找到部分匹配的Style文件: '{file}' 匹配 '{style_name}'") - content = ResourceLoader.load_file_content(matched_path) - if content: - # 保存到缓存 - self._style_cache[style_name] = content - self._style_cache[file] = content - return content - except Exception as e: - logging.warning(f"尝试列出Style目录内容时出错: {e}") + matched_file, score = self.find_directory_fuzzy_match(style_name, directory=style_dir) + if matched_file and score > 0: + matched_path = os.path.join(style_dir, matched_file) + content = ResourceLoader.load_file_content(matched_path) + if content: + # 保存到缓存 + self._style_cache[style_name] = content + self._style_cache[matched_file] = content + file_without_ext = os.path.splitext(matched_file)[0] + self._style_cache[file_without_ext] = content # 同时缓存不带扩展名的版本 + return content + logging.warning(f"未能找到Style文件: '{style_name}',尝试过以下位置: 缓存, {self.prompts_dir}/Style/") return None def _get_demand_content(self, demand_name): @@ -206,41 +256,18 @@ class PromptManager: demand_name = os.path.splitext(demand_name)[0] # 移除扩展名 # 尝试模糊匹配缓存中的文件名 - for cache_key in self._demand_cache.keys(): - cache_key_lower = cache_key.lower() - demand_name_lower = demand_name.lower() - - # 完全匹配 - if cache_key_lower == demand_name_lower: - return self._demand_cache[cache_key] - - # 部分匹配:检查需求名称是否是缓存键的一部分,或者缓存键是否是需求名称的一部分 - # 例如"亲子家庭文旅需求"能匹配到"亲子向文旅需求" - if "亲子" in demand_name_lower and "亲子" in cache_key_lower: - logging.info(f"模糊匹配 - 找到部分匹配的Demand文件: '{cache_key}' 匹配 '{demand_name}'") - return self._demand_cache[cache_key] - if "情侣" in demand_name_lower and "情侣" in cache_key_lower: - logging.info(f"模糊匹配 - 找到部分匹配的Demand文件: '{cache_key}' 匹配 '{demand_name}'") - return self._demand_cache[cache_key] - if "职场" in demand_name_lower and "职场" in cache_key_lower: - logging.info(f"模糊匹配 - 找到部分匹配的Demand文件: '{cache_key}' 匹配 '{demand_name}'") - return self._demand_cache[cache_key] - if "学生" in demand_name_lower and "学生" in cache_key_lower: - logging.info(f"模糊匹配 - 找到部分匹配的Demand文件: '{cache_key}' 匹配 '{demand_name}'") - return self._demand_cache[cache_key] - if "银发" in demand_name_lower and "夕阳红" in cache_key_lower: - logging.info(f"模糊匹配 - 找到部分匹配的Demand文件: '{cache_key}' 匹配 '{demand_name}'") - return self._demand_cache[cache_key] - if "夕阳红" in demand_name_lower and "银发" in cache_key_lower: - logging.info(f"模糊匹配 - 找到部分匹配的Demand文件: '{cache_key}' 匹配 '{demand_name}'") - return self._demand_cache[cache_key] - if "周边" in demand_name_lower and "周边" in cache_key_lower: - logging.info(f"模糊匹配 - 找到部分匹配的Demand文件: '{cache_key}' 匹配 '{demand_name}'") - return self._demand_cache[cache_key] + cache_files = list(self._demand_cache.keys()) + matched_key, score = self.find_directory_fuzzy_match(demand_name, files=cache_files) + + if matched_key and score > 0: + return self._demand_cache[matched_key] # 如果没有在缓存中找到模糊匹配,尝试从prompts_dir加载(向后兼容) if self.prompts_dir: - demand_path = os.path.join(self.prompts_dir, "Demand", demand_file) + demand_dir = os.path.join(self.prompts_dir, "Demand") + demand_path = os.path.join(demand_dir, demand_file) + + # 精确路径匹配 if os.path.exists(demand_path): content = ResourceLoader.load_file_content(demand_path) if content: @@ -249,41 +276,19 @@ class PromptManager: self._demand_cache[demand_file] = content return content - # 如果直接加载失败,尝试列出目录中的所有文件并进行模糊匹配 - demand_dir = os.path.join(self.prompts_dir, "Demand") + # 如果精确匹配失败,尝试目录中的模糊匹配 if os.path.isdir(demand_dir): - try: - files = os.listdir(demand_dir) - demand_name_lower = demand_name.lower() - - for file in files: - file_lower = file.lower() - # 检查关键词匹配 - matched = False - if "亲子" in demand_name_lower and "亲子" in file_lower: - matched = True - elif "情侣" in demand_name_lower and "情侣" in file_lower: - matched = True - elif "职场" in demand_name_lower and "职场" in file_lower: - matched = True - elif "学生" in demand_name_lower and "学生" in file_lower: - matched = True - elif ("银发" in demand_name_lower or "夕阳红" in demand_name_lower) and ("银发" in file_lower or "夕阳红" in file_lower): - matched = True - elif "周边" in demand_name_lower and "周边" in file_lower: - matched = True - - if matched: - matched_path = os.path.join(demand_dir, file) - logging.info(f"模糊匹配 - 在目录中找到部分匹配的Demand文件: '{file}' 匹配 '{demand_name}'") - content = ResourceLoader.load_file_content(matched_path) - if content: - # 保存到缓存 - self._demand_cache[demand_name] = content - self._demand_cache[file] = content - return content - except Exception as e: - logging.warning(f"尝试列出Demand目录内容时出错: {e}") + matched_file, score = self.find_directory_fuzzy_match(demand_name, directory=demand_dir) + if matched_file and score > 0: + matched_path = os.path.join(demand_dir, matched_file) + content = ResourceLoader.load_file_content(matched_path) + if content: + # 保存到缓存 + self._demand_cache[demand_name] = content + self._demand_cache[matched_file] = content + file_without_ext = os.path.splitext(matched_file)[0] + self._demand_cache[file_without_ext] = content # 同时缓存不带扩展名的版本 + return content # 如果所有尝试都失败 logging.warning(f"未能找到Demand文件: '{demand_name}',尝试过以下位置: 缓存, {self.prompts_dir}/Demand/") @@ -415,15 +420,17 @@ class PromptManager: return None, None def get_content_prompts(self, topic_item): - """Constructs the system and user prompts for content generation based on a topic item.""" - logging.info(f"Constructing content prompts for topic: {topic_item.get('object', 'N/A')}...") + """Constructs the system and user prompts for content generation.""" + logging.info("Constructing prompts for content generation...") + try: - # --- System Prompt --- + # --- System Prompt --- system_prompt = self._system_prompt_cache.get("content") if not system_prompt: if not self.content_system_prompt_path: - logging.error("Content system prompt path not provided during PromptManager initialization.") + logging.error("Content system prompt path not provided.") return None, None + system_prompt = ResourceLoader.load_file_content(self.content_system_prompt_path) if system_prompt: self._system_prompt_cache["content"] = system_prompt @@ -432,154 +439,138 @@ class PromptManager: return None, None # --- User Prompt --- - user_prompt = "" - - # 1. 添加Demand部分 (直接使用 topic_item['logic'] 的描述性文本) - try: - demand_description = topic_item.get('logic') - if demand_description: - user_prompt += f"Demand Logic:\n{demand_description}\n" - else: - logging.warning("Warning: 'logic' key missing or empty in topic_item for Demand prompt.") - except Exception as e: - logging.exception("Error processing Demand description:") - - # 2. Object Info - 先列出所有可用文件,再注入匹配文件的内容 - try: - object_name_from_topic = topic_item.get('object') # e.g., "尚书第建筑群" - object_file_basenames = [] - matched_object_file_path = None - matched_object_basename = None - - # 遍历查找 Object 文件 - for dir_info in self.resource_dir_config: - if dir_info.get("type") == "Object": - for file_path in dir_info.get("file_path", []): - basename = os.path.basename(file_path) - object_file_basenames.append(basename) - - # 尝试匹配当前 topic 的 object (仅当尚未找到匹配时) - if object_name_from_topic and not matched_object_file_path: - cleaned_resource_name = basename - if cleaned_resource_name.startswith("景点信息-"): - cleaned_resource_name = cleaned_resource_name[len("景点信息-"):] - if cleaned_resource_name.endswith(".txt"): - cleaned_resource_name = cleaned_resource_name[:-len(".txt")] - - if cleaned_resource_name and cleaned_resource_name in object_name_from_topic: - matched_object_file_path = file_path - matched_object_basename = basename - # 注意:这里不 break,继续收集所有文件名 - - # 构建提示词 - Part 1: 文件列表 - if object_file_basenames: - user_prompt += "Object信息:\n" - # user_prompt += f"{object_file_basenames}\n\n" # 直接打印列表可能不够清晰 - for fname in object_file_basenames: - user_prompt += f"- {fname}\n" - user_prompt += "\n" # 加一个空行 - logging.info(f"Listed {len(object_file_basenames)} available object files.") - else: - logging.warning("No resource directory entry found with type 'Object', or it has no file paths.") - - # 构建提示词 - Part 2: 注入匹配文件内容 - if matched_object_file_path: - logging.info(f"Attempting to load content for matched object file: {matched_object_basename}") - matched_object_content = ResourceLoader.load_file_content(matched_object_file_path) - if matched_object_content: - user_prompt += f"{matched_object_basename}:\n{matched_object_content}\n\n" - logging.info(f"Successfully loaded and injected content for: {matched_object_basename}") - else: - logging.warning(f"Object file matched ({matched_object_basename}) but could not be loaded or is empty.") - elif object_name_from_topic: # 只有当 topic 中指定了 object 但没找到匹配文件时才警告 - logging.warning(f"Could not find a matching Object resource file to inject content for '{object_name_from_topic}'. Only the list of files was provided.") - - except KeyError: - logging.warning("Warning: 'object' key potentially missing in topic_item.") - except Exception as e: - logging.exception("Error processing Object prompt section:") - - # 3. 添加Product信息 (if applicable) - try: - product_name = topic_item.get('product') - product_logic_description = topic_item.get('product_logic') # Directly use this description - if product_name: - # Add Product Logic description first (if available) - if product_logic_description: - user_prompt += f"Product Logic:\n{product_logic_description}\n" - else: - logging.warning(f"Warning: 'product_logic' key missing or empty for product '{product_name}'.") - - # Then, load Product Info file - product_file_path = None - for dir_info in self.resource_dir_config: - if dir_info.get("type") == "Product": - for file_path in dir_info.get("file_path", []): - if product_name in os.path.basename(file_path): - product_file_path = file_path - break - if product_file_path: break - - if product_file_path: - product_content = ResourceLoader.load_file_content(product_file_path) - if product_content: - user_prompt += f"Product Info:\n{product_content}\n" - else: - logging.warning(f"Product file could not be loaded: {product_file_path}") - else: - logging.warning(f"Product file path not found in config for: {product_name}") - except KeyError: - logging.warning("Warning: Missing 'product' key in topic_item for Product prompt.") - except Exception as e: - logging.exception("Error processing Product prompt:") - - # 4. 添加Style信息 (加载文件 based on topic_item['style']) - try: - style_name = topic_item.get('style') - if style_name: - style_content = self._get_style_content(style_name) - if style_content: - user_prompt += f"Style Info:\n{style_content}\n" - else: - logging.warning(f"Style file not found or empty for: {style_name}") - else: - logging.warning("Warning: 'style' key missing or empty in topic_item.") - except Exception as e: - logging.exception("Error processing Style prompt:") - - # 5. 添加Target Audience信息 (加载文件 based on topic_item['target_audience']) - try: - target_audience_name = topic_item.get('target_audience') - if target_audience_name: - target_audience_content = self._get_demand_content(target_audience_name) - if target_audience_content: - user_prompt += f"Target Audience Info:\n{target_audience_content}\n" - else: - logging.warning(f"Target Audience file not found or empty for: {target_audience_name}") - else: - logging.warning("Warning: 'target_audience' key missing or empty in topic_item.") - except Exception as e: - logging.exception("Error processing Target Audience prompt:") - - # 6. 添加Refer信息 (加载所有Refer文件的内容) - try: - refer_content_all = self._get_all_refer_contents() - if refer_content_all: - user_prompt += f"Refer Info:\n{refer_content_all}" - else: - logging.warning("No content loaded from Refer files.") - except Exception as e: - logging.exception("Error processing Refer files:") - - # --- End of prompt construction logic --- + style = "" + demand = "" + refers = "" + object_info = "" - logging.info(f"Content prompts constructed. System: {len(system_prompt)} chars, User: {len(user_prompt)} chars.") - return system_prompt, user_prompt + # Extract style from topic + if "style" in topic_item and topic_item["style"]: + style_name = topic_item["style"] + style_content = self._get_style_content(style_name) + if style_content: + style = f"Style: {style_name}\n{style_content}\n\n" + else: + logging.warning(f"Style content for '{style_name}' not found.") + + # Extract demand from topic + if "target_audience" in topic_item and topic_item["target_audience"]: + demand_name = topic_item["target_audience"] + demand_content = self._get_demand_content(demand_name) + if demand_content: + demand = f"Demand: {demand_name}\n{demand_content}\n\n" + else: + logging.warning(f"Demand content for '{demand_name}' not found.") + + # Add refer contents + refers_content = self._get_all_refer_contents() + if refers_content: + refers = f"Reference:\n{refers_content}\n\n" + + # Get object information + object_name = topic_item.get("object", "") + if object_name: + # 优化:遍历resource_dir_config查找对象描述 + found_object_info = False + + # 1. 搜集所有可能的资源文件 + all_description_files = [] + for dir_info in self.resource_dir_config: + if dir_info.get("type") in ["Object", "Description"]: + all_description_files.extend(dir_info.get("file_path", [])) + + # 2. 尝试精确匹配 + for file_path in all_description_files: + if object_name in os.path.basename(file_path): + info = ResourceLoader.load_file_content(file_path) + if info: + object_info = f"Object: {object_name}\n{info}\n\n" + logging.info(f"找到对象'{object_name}'的精确匹配资源文件: {file_path}") + found_object_info = True + break + + # 3. 如果精确匹配失败,尝试模糊匹配 + if not found_object_info and all_description_files: + logging.info(f"尝试模糊匹配对象'{object_name}'的资源文件") + + # 提取所有文件名 + file_names = [os.path.basename(f) for f in all_description_files] + # 模糊匹配 + matched_filename, score = self.find_directory_fuzzy_match(object_name, files=file_names) + + if matched_filename and score > 0: + # 找到匹配的完整路径 + for file_path in all_description_files: + if os.path.basename(file_path) == matched_filename: + info = ResourceLoader.load_file_content(file_path) + if info: + object_info = f"Object: {object_name}\n{info}\n\n" + logging.info(f"模糊匹配找到对象'{object_name}'的资源文件: {file_path},匹配分数: {score}") + found_object_info = True + break + + if not found_object_info: + logging.warning(f"未找到对象'{object_name}'的任何匹配资源文件") - except KeyError as e: - # Catch potential KeyErrors from accessing topic_item if a required key is missing early on - logging.error(f"Error constructing content prompts: Missing essential key '{e}' in topic_item: {topic_item}") - return None, None + # Get product information if any + product_name = topic_item.get("product", "") + if product_name: + product_info = "" + # 优化:遍历resource_dir_config查找产品描述 + found_product_info = False + + # 搜集所有可能的产品资源文件 + all_product_files = [] + for dir_info in self.resource_dir_config: + if dir_info.get("type") == "Product": + all_product_files.extend(dir_info.get("file_path", [])) + + # 尝试精确匹配 + for file_path in all_product_files: + if product_name in os.path.basename(file_path): + info = ResourceLoader.load_file_content(file_path) + if info: + product_info = f"Product: {product_name}\n{info}\n\n" + logging.info(f"找到产品'{product_name}'的精确匹配资源文件: {file_path}") + found_product_info = True + break + + # 如果精确匹配失败,尝试模糊匹配 + if not found_product_info and all_product_files: + logging.info(f"尝试模糊匹配产品'{product_name}'的资源文件") + + # 提取所有文件名 + file_names = [os.path.basename(f) for f in all_product_files] + # 模糊匹配 + matched_filename, score = self.find_directory_fuzzy_match(product_name, files=file_names) + + if matched_filename and score > 0: + # 找到匹配的完整路径 + for file_path in all_product_files: + if os.path.basename(file_path) == matched_filename: + info = ResourceLoader.load_file_content(file_path) + if info: + product_info = f"Product: {product_name}\n{info}\n\n" + logging.info(f"模糊匹配找到产品'{product_name}'的资源文件: {file_path},匹配分数: {score}") + found_product_info = True + break + + if not found_product_info: + logging.warning(f"未找到产品'{product_name}'的任何匹配资源文件") + + # 添加产品信息到对象信息中 + if product_info: + object_info += product_info + + # Construct final user prompt + user_prompt = f"""请为我创建一个旅游文案。 + +{style}{demand}{refers}{object_info} + +请考虑以上所有信息,创作一篇{topic_item.get('target_audience','')}文旅内容。""" + + return system_prompt, user_prompt except Exception as e: - logging.exception("Error constructing content prompts:") + traceback.print_exc() + logging.error(f"Error creating content prompts: {str(e)}") return None, None \ No newline at end of file