☰
复杂提示词架构搭建实战:微信小程序五行MBTI跨界对话
2026/10/20 15:30:33 网站建设 项目流程

前阵子帮一个朋友看他的微信小程序项目《见格MBTI》,核心功能很有意思——用户输入自己的出生信息或性格描述,小程序调用大模型,输出一整套“五行人格 × MBTI人格”的跨体系解读。这个功能听起来像是套壳问答,但真正落地时才发觉,难点根本不在于调API,而在于怎么让大模型在两套完全异源的知识体系之间稳定地建立对话映射,不跑偏、不胡诌、输出格式还可控。这篇文章就把我们实际搭建复杂提示词架构的过程拆开讲清楚,包含整套Prompt设计思路、小程序端的调用链路、踩过的坑和排查方法,给正在做类似“传统文化+现代心理学”类小程序的人一个可复用的参考。

1. 项目定位与整体架构拆解

1.1 跨界对话的核心价值:为什么是五行和MBTI

先说产品动机。五行是中国传统认知里的一套动态关系模型,金木水火土本身不是静止的标签,而是一套生克制化的关系网络。MBTI则是基于荣格类型学发展出来的现代人格测评工具,通过精力来源、信息获取、决策方式、生活态度四个维度把人分成16种类型。这两套体系在表面上差异巨大,但底层有一个共同点:都在尝试用一种结构化的方式解释“人的性格倾向和行为模式”。

我们在设计《见格MBTI》的时候,想做的不只是“算出你的五行属性,再算出你的MBTI”这种并行输出,而是真正意义上的跨界对话——让大模型把两套体系之间的对应关系、张力、互补性表达出来。比如一个“火”属性偏强的人,在MBTI里更可能对应哪些类型?反过来,一个INTP型的人,在五行能量结构里会更贴近“水”还是“金”?这种映射不是定死的公式,而是需要大模型在理解两套知识结构的前提下,基于用户具体输入做动态判断。

这个定位决定了整条技术路线的走向:绝对不能用一个写死的规则表去匹配五行和MBTI,那样做出来的东西没有生命力;也绝对不能完全放任大模型自由发挥,否则用户会得到一堆看似有道理实则虚无缥缈的废话。正确的做法是,用一套精心设计的提示词架构,把大模型的生成能力约束在一个“既有知识框架、又有弹性推理”的空间里。

1.2 小程序的角色与架构选型

微信小程序在这个项目里承担的是“轻量触达”的角色。用户不需要下载App,点开即用,天然适合分享裂变。但我们一开始就面临着几个现实约束:

第一,小程序前端不能直接调用大模型接口。微信小程序要求所有请求域名必须配置在合法域名白名单里,而且大多数大模型服务商并不提供直接面向小程序的SDK,甚至有些接口的域名无法被直接白名单化。所以,必须有一个中转服务层。

第二,小程序的包体积限制。微信小程序主包限制在2MB以内,这意味着我们不可能把任何重量级的SDK塞进前端,所有复杂逻辑必须放在服务端。

第三,交互体验要求。大模型生成完整回复通常需要几秒到十几秒,如果小程序端傻等一个完整的HTTP响应才更新UI,用户体验会很差。所以,服务端需要支持流式输出(SSE),把模型生成的内容逐段推送到小程序端。

基于这三点,我们的整体架构确定为三层:

  • 前端小程序层:承担信息采集(用户输入)、流式渲染、结果展示与分享。
  • 后端代理服务层:承担提示词组装、大模型API调用、流式转发、敏感内容过滤、上下文管理。
  • 大模型服务层:承载领域对话能力,根据后端传入的提示词生成内容。

这个架构本身不复杂,但它决定了提示词必须由后端统一管理。这样做的好处非常明显:提示词更新不需要发小程序版本,后端改完立即生效。我们在实际开发中把提示词拆成了独立的配置文件,配合版本号管理,回滚也方便。

2. 复杂提示词架构的搭建过程

2.1 核心设计思路:把提示词当成一套“剧本+演员手册”

一开始我们想得很简单,写一段Prompt让模型扮演“五行MBTI融合分析师”,然后就把用户输入丢进去。测试之后发现效果很差:模型有时候只讲五行不讲MBTI,有时候输出大段空泛的性格描述,有时候格式乱得没法在小程序里结构化展示。

后来我们换了个思路——把提示词拆成四个层次,每个层次解决一个独立问题。整套结构类比一下就是:“剧本”定义角色和剧情目标,“演员手册”给角色背景知识和说话风格,“流程表”规定每一幕怎么演,“交作业模板”规定台词用什么样的格式写出来。

第一层是系统角色设定。明确告诉大模型它现在是谁、任务目标是什么、必须遵守的边界有哪些。这一层不涉及具体知识,只做角色和意图的锚定,防止模型在对话中途“人格漂移”。

第二层是知识注入层。把五行体系的核心知识结构、MBTI体系的核心维度说明、两套体系之间的常见对应逻辑,以结构化文本的形式写进提示词。注意,这里不是丢一大堆百科词条,而是精心筛选过的“最小可用知识集”,避免上下文被冗余信息撑爆。

第三层是对话流程控制层。定义大模型处理用户输入的步骤:先解析用户输入,提炼关键性格特征;再判断对应的五行倾向;然后推断MBTI类型;最后给出跨体系融合解读和行动建议。这四步一步都不能乱。

第四层是输出格式层。强制规定大模型返回的JSON结构,包括字段名、含义、取值枚举等。小程序端拿到这份JSON后直接解析渲染,不需要让大模型生成自然语言段落再由前端做语义提取——那种方式既不稳定又浪费token。

2.2 系统角色与边界条件设计实操

系统提示词这一部分,我们踩过最深的坑是“角色设定太宽”。最初版本写的是“你是一位深谙五行学说和MBTI心理学的大师”,结果模型每次都在开头自我介绍一下身份,回答内容却蜻蜓点水。后来改成了更具体的角色定义,直接编织进业务目标里:

你是一个服务于「五行×MBTI跨界人格对话」场景的智能分析师。 你的职责不是向用户普及五行或MBTI的基础概念,而是基于用户的个人描述, 给出结构化的跨体系人格解读。 严格约束: 1. 不输出与五行、MBTI分析无关的内容; 2. 不要主动询问用户隐私信息(如生辰八字精确时间、真实姓名等); 3. 所有结论必须以两套体系的融合视角给出,避免只讲其中一套; 4. 面对不确定的判断,使用“倾向于”“可能更贴近”等措辞,禁止武断定性。

这段提示词里有三个细节值得注意。第一,用“不是...而是...”结构直接否定了模型的错误倾向,比单纯说“不要介绍概念”有效得多。第二,把合规要求直接写进提示词,避免用户诱导模型讨论不当话题。第三,用“倾向性措辞”约束模型的确定性表达,这从根上减少了用户较真追问的概率。

角色设定确定后,还要配合温度参数。我们测试下来,这类分析解读型场景把temperature设在0.4到0.6之间最合适。太高了输出不稳定,同一个输入每次说法都不一样;太低了显得机械,缺少灵性。最终固定为0.5。

2.3 知识注入层的结构化组织方式

知识注入是整个提示词架构的基石,也是最需要反复打磨的部分。我们的做法是给大模型提供一份“结构化知识清单”,而不是一段连续文本。

五行部分,我们重点注入的不是简单的性格形容词表,而是五行之间的关系逻辑:

[五行知识框架] - 五行基本属性:金(收敛、肃杀、决断)、木(生发、规划、仁善)、 水(流动、智慧、变通)、火(热烈、外放、礼仪)、土(承载、稳定、信任)。 - 五行相生:木生火、火生土、土生金、金生水、水生木。 - 五行相克:木克土、土克水、水克火、火克金、金克木。 - 分析原则:判断一个人的主导五行时,需结合输入信息中 体现出的行为模式、情绪特征、决策风格,而非仅凭字面标签。

这里有一个取舍:我们故意不把“金代表肺、木代表肝”这类中医五行对应关系放进去,因为产品定位于人格对话,不涉及健康领域。知识注入一定要克制,只放当前任务需要的知识,否则大模型会被无关信息带偏,还有可能触碰到医疗建议的合规红线。

MBTI部分,我们同样做了精简,只保留四个维度的含义和16种类型的简要倾向:

[MBTI知识框架] - 精力来源:E(外向,从社交获取能量) / I(内向,从独处获取能量)。 - 信息获取:S(感觉,关注现实细节) / N(直觉,关注抽象模式)。 - 决策方式:T(思考,逻辑优先) / F(情感,价值优先)。 - 生活态度:J(判断,喜欢计划) / P(知觉,喜欢灵活)。 - 16型人格需基于上述四个维度的组合进行推导,禁止杜撰不存在的维度。

在知识注入层之后,我们还加了一段“跨体系映射参考”,这是一个开放性的引导,不是封闭的规则表,它允许模型灵活推断,同时提示模型建立两个体系间的对应关系。

2.4 对话流程控制:让模型按步骤走而不跳步

流程控制层是把“角色+知识”落地的关键。我们使用了一个带编号步骤的指令块,让大模型在生成回答时严格按照顺序处理:

[处理流程] 第一步:解析用户输入,提取与性格、行为、偏好相关的关键词和特征描述。 第二步:结合五行知识框架,判断用户性格倾向对应的主导五行元素(可取1-2个)。 第三步:结合MBTI知识框架,推断用户在四个维度上的偏好及对应人格类型。 第四步:综合两套体系,生成融合解读,包含:主导特质、优势分析、 潜在盲区、发展建议。

为什么强调流程必须分步而不是让模型一次完成?因为我们在测试中发现,不分步骤时模型经常跳步,比如只做了MBTI推导,然后就直接跳到发展建议,完全不提五行。分步指令相当于给模型的思维过程加上了“轨道”,虽然不能百分之百保证不脱轨,但稳定性大幅提升。

另外一个关键技巧是,在流程说明后面补一句“在最终输出中不得出现步骤标记”,否则模型会把“第一步”“第二步”原样写进给用户的输出里,体验很差。

2.5 输出格式控制:用JSON Schema锁死结构

最后是输出格式层。这层直接决定了小程序渲染的难易程度。我们采用JSON结构输出,并在提示词里逐字段说明:

[输出格式] 你必须输出严格的JSON对象,字段如下: { "dominant_element": "五行元素,取值为金/木/水/火/土", "element_traits": "该五行主导下用户核心特质的简述,不超过50字", "mbti_type": "四字母MBTI类型", "mbti_traits": "该MBTI类型核心特质的简述,不超过50字", "mapping_analysis": "两套体系之间的融合分析,不少于80字,不多于200字", "strengths": "基于两套体系的优势解读,列出2-3点", "blind_spots": "潜在盲区解读,列出2-3点", "suggestion": "发展建议,80字以内" }

这里有一个特别重要的细节:必须在提示词里明确字段长度上限。如果不说,模型生成的字段可能长达几百字,既浪费token又让页面排版极其难看。我们在长度约束后加了“少于”“不多于”这种精确限定,实测比用“简洁”这种模糊词有效得多。

另一个细节是:在JSON生成后,我们要求模型直接输出JSON,不要包一层markdown代码块。因为小程序端后续要做JSON.parse,如果模型输出了json ...包裹的内容,解析就会失败。虽然可以在后端做预处理,但最好让模型一开始就按裸JSON输出。

3. 小程序端调用链路的实现细节

3.1 后端服务设计:Model API的封装与流式转发

后端服务我们用Node.js实现,主要解决两件事:一是统一封装大模型API调用逻辑,二是把模型的流式输出透传给小程序端。这里给出一段核心路由代码框架:

const express = require('express'); const axios = require('axios'); const { buildPrompt } = require('./promptBuilder'); const router = express.Router(); router.post('/analyze', async (req, res) => { try { const userInput = req.body.userInput; const conversationId = req.body.conversationId || null; // 构建完整提示词:系统提示词 + 历史上下文 + 当前用户输入 const messages = buildPrompt(userInput, conversationId); res.setHeader('Content-Type', 'text/event-stream; charset=utf-8'); res.setHeader('Cache-Control', 'no-cache'); res.setHeader('Connection', 'keep-alive'); const modelResponse = await callModelApi(messages); // 透传流式数据 modelResponse.data.on('data', chunk => { const parsed = parseSSEChunk(chunk); if (parsed && parsed.content) { res.write(JSON.stringify({ type: 'content', content: parsed.content })); } }); modelResponse.data.on('end', () => { res.write(JSON.stringify({ type: 'done' })); res.end(); }); } catch (error) { res.status(500).json({ error: '分析服务暂时不可用' }); } });

这里有几个值得细说的点。

第一是SSE格式。小程序端wx.request不支持原生的EventSource,所以我们实际上是手动解析服务端发来的SSE流。具体做法是后端收到大模型流式响应后,将每一段数据封装成一行JSON字符串,用data:前缀发送,小程序端再用onChunkReceived监听逐段解析。这一步如果不做,用户要等完全生成后才能看到结果,体感差距非常大。

第二是上下文管理。我们采用了轻量级的滑动窗口方案:后端把用户最开始的输入信息作为固定记忆,最近两轮对话内容拼入上下文,更早的内容一律丢弃。这样既保留了必要的连续性,又严格控制了token消耗。

第三是异步错误处理。大模型API经常出现网络超时或服务端5xx错误,如果不在前端做好重试提示,用户会以为小程序崩了。我们的方案是后端捕获错误后向小程序返回一个error类型的事件,前端拿到后展示友好的重试引导,而不是直接凉掉页面。

3.2 前端小程序交互与渲染策略

小程序端的实现核心集中在三个页面逻辑:输入页、加载页、结果页。我们在一开始考虑过用WebView加载H5页面来渲染内容,后来放弃了这个方案,因为原生页面在分享卡片、动画过渡和渲染性能上都有明显优势。

输入页要解决的是用户“不知道说什么”的问题。我们设计了几种快捷输入方式:用户可以选择“跟随引导”——按提示输入自己的性格偏好、日常行为模式;也可以直接输入一段自由描述。但无论哪种方式,取到的原始文本并不直接发给大模型,而是先做一次简单的关键词抽取和信息规整,再传给后端。

加载页的体验设计很容易被忽视,但对留存影响很大。大模型生成内容通常需要3到8秒,用户等不了白屏。我们的方案是做一个动态的过渡动画,同时先把用户输入内容回显在页面上,配合“正在从两个维度分析你的人格结构...”这种过程暗示,让用户理解当前状态不是卡死而是计算中。

结果页采用分块渲染的方式。因为服务端是流式返回,JSON中的字段是一个个生成的。我们的策略是收到dominant_element字段后立即展示五行标签,收到mbti_type后展示MBTI标签,其余长文本字段到达后再逐步补充。这样用户感知到的是“内容一点点出现”,而不是“一整块突然冒出来”,心理体验会好很多。

前端还需要做一次结果格式兜底校验。由于大模型输出天然带随机性,即使提示词里规定了JSON格式,仍然有小概率出现解析失败的情况。我们的方案是后端在返回给前端之前做一次JSON.parse校验,如果失败则自动触发一次重试生成;如果重试仍然失败,就降级返回一段纯文本输出,保证用户至少能看到分析内容。

4. 常见问题与排查技巧实录

4.1 提示词越调越乱,模型输出开始“人格分裂”

这是一个我们过程中反复遇到的问题。有一次我们把营养建议也加进了提示词,目的是让输出内容更丰富,结果模型开始大段输出饮食建议,完全偏离了人格分析主题。排查后发现根本原因是知识注入层混入了与核心任务无关的内容,模型在角色设定模糊的情况下自主扩大了职责范围。

解决方法是严格执行知识隔离:核心任务需要的数据留在提示词里,一切非核心内容放到“禁止涉及”列表里。我们在系统提示词里明确写了一句“以下内容与本对话无关,禁止主动提及:健康建议、命理推算、取名建议、婚配建议”,效果立竿见影。

这个问题的本质是提示词的“信息熵”过高。大模型在生成时会更倾向于使用信息量大的上下文,如果无关知识塞得太多,它会把注意力分配到错误的地方。控制知识注入的纯度,是提示词工程里最容易被低估的一环。

4.2 用户同一个问题反复追问,输出内容前后矛盾

上线后发现一批投诉:用户第一次问“我适合什么工作方向”得到的回答和第二次问的结论完全不一样。这背后有两个原因:一是大模型生成的随机性,二是我们为控制token没有保存完整的对话记忆。

针对这个问题,我们的解法分三层。第一层是引入固定的“用户画像摘要”机制:用户第一次输入后,后端提取核心特征生成一段摘要文本,后续每一轮对话中都会把摘要放进提示词,相当于让大模型始终感受到统一的用户画像。第二层是把temperature从0.5降到0.4,减少随机性。第三层是放宽滑动窗口,把最近三轮对话全部保留而不是两轮。

这个调整之后,前后一致性明显改善。当然这里要提醒一句:如果产品定位就是“每次随机探索”,那可以忽略这条经验;但我们的产品定位是“稳定的人格分析工具”,一致性就是生命线。

4.3 输出格式不稳定,前端JSON解析频繁失败

JSON解析失败这个问题在开发初期几乎每周都要碰几次。最典型的情况是模型在JSON前后加了markdown代码块标记。我们在提示词里明确写了“直接输出裸JSON,不要包含markdown代码块标记”,但偶尔还是会有漏网之鱼。

后来我们做了一道双保险:在后端解析层加了一个sanitize函数,如果首次解析失败,就尝试剥离代码块标记、修正多余的逗号之后再做二次解析;如果仍然失败,则触发重试。这里的关键是重试次数要设上限,我们设了2次,超过就直接降级为文本输出,不无限等下去。

另外一个细节是:JSON字段里有引号或换行符时,模型可能没有正确转义,导致解析失败。我们的做法是在提示词里给出了一个“字段内容中禁止包含双引号和换行符”的规则,同时在sanitize函数里做了一层转义处理。

4.4 并发高峰时段模型响应极慢,体验断崖式下降

有一天上线了某平台的推广活动,流量突然涨了十几倍,后端代理服务的并发调用撑不住,大量请求排队等待模型响应,页面一直转圈。排查后发现,问题不只是模型API本身的并发限制,还有我们自己的服务处理模型响应时使用了同步等待,导致Node.js事件循环被阻塞。

解决方法是全面异步化。我们把大模型调用改为非阻塞模式,利用消息队列削峰填谷;同时针对同一个用户的多轮请求做合并,减少重复调用;另外在网关层做了并发限流,超过阈值的请求直接返回“当前人数较多,请稍后重试”的提示。

这里也分享一个小经验:大模型响应慢时,不要只盯着模型服务商,先看自己的代理层是不是成了瓶颈。很多团队把性能问题全部归因于外部API,实际上自己的代码往往才是那个卡脖子的环节。

4.5 常见问题速查表

最后整理一份我们在实际运营中沉淀下来的问题排查表,方便新加入项目的成员快速定位问题:

现象可能原因排查方向
模型只讲五行不讲MBTI提示词流程控制失效检查流程控制层是否被其他高权重指令覆盖,确认步骤编号未被遗漏
输出内容空泛无实质知识注入层过薄补充最小可用知识集,确保模型具备体系内的基础概念
JSON解析频繁失败模型输出带格式杂质后端增加sanitize兜底,并在提示词里强化裸JSON要求
多轮回答前后矛盾上下文管理丢失引入固定用户画像摘要,扩大滑动窗口长度
高峰时段响应极慢并发调用排队阻塞服务端异步化、消息队列削峰、客户端增加引导性提示
内容涉及敏感话题系统提示词约束不足在角色设定层补充严格负面清单,前置内容安全模型检测

5. 提示词迭代与版本管理的工程化实践

5.1 提示词配置文件与版本回滚机制

随着功能迭代,我们把提示词从Python代码里硬编码的字符串,迁移成了独立的维护体系。每套提示词都有版本号、更新人、变更说明、生效时间四个基本信息,并存放在后端配置中心。小程序端请求时带上当前版本号,服务端根据版本号拉取对应的提示词模板。

这份投入非常值得。没有版本管理之前,有一次我和朋友同时改了提示词,互相覆盖,导致线上突然出现混乱输出,花了很长时间才定位到是配置被意外改动。有了版本管理和线上配置与测试配置分离的机制之后,这类事故彻底杜绝了。

提示词版本管理的几个要点:

  • 每次变更必须有明确度量:比如“温度从0.5调到0.4”“增加禁言列表”等,能量化才能复盘。
  • 大规模改动前先在小流量上A/B测试,比如5%的请求走新版本提示词,对比满意度后再全量发布。
  • 保留最近3个可用的历史版本,一旦新版提示词引发投诉,可以在1分钟内完成回滚。

5.2 调参经验:temperature和top_p的平衡

在大模型API的所有参数里,temperature和top_p直接影响内容生成的确定性,这两个值我们反复测试了很久。总结下来:

参数项目测试范围最终取值使用说明
temperature0.3-0.80.4越低输出越稳定,但低于0.3会显得机械重复;高于0.6后每次回答差异过大
top_p0.8-0.950.9控制候选词范围,与temperature配合使用而非替代
max_tokens512-2048900太长浪费成本,太短会切掉建议部分

还有一个小经验:当temperature较低时,说明模型倾向于保守,输出的创意性会减弱。对于我们的场景,这也是可以接受的。做人格分析类产品,用户的信任感首先来自“每次问结果都差不多”,其次才是有趣的惊喜感。如果优先追求创意丰富,可以把每个输出字段单独设定温度,但这个方案会显著增加工程复杂度,目前我们没有实施。

6. 关于内容安全与产品合规的排查提示

这部分单独开一节说,因为太容易踩雷。五行命理、MBTI测评这类话题天然带敏感属性,如果内容表现不当,轻则被内容安全平台拦截,重则带来合规风险。

第一,在提示词中明确禁止输出医疗、投资、生育等专业领域的具体建议。我们有意识地在系统提示词里加入了一条“禁止输出涉及医疗诊断、疾病预测、投资理财、法律咨询等专业建议”,防止模型被用户诱导越界。

第二,关于五行与命理,产品文案里必须把表达从“命运预测”转向“性格倾向分析”。这个转向不是文字游戏,而是产品定位的根本:我们不是告诉用户“你的命运注定如何”,而是提供一个“从不同文化视角认识自己”的工具。这个定位差异会直接影响提示词设计——我们要求模型输出所有内容都用“倾向”“可能”“更适合”这类非确定性措辞。

第三,对涉政、黄赌毒等敏感输入,必须前置拦截。我们不依赖大模型自身的拒绝能力,而是在后端接入内容安全服务做一级过滤,命中黑名单就直接返回“暂不支持该类型问题”,不走模型调用流程。这样既节省token,也避免大模型输出不可控内容。

第四,数据隐私。用户输入的性格描述、出生日期等信息都是敏感数据。后端密钥管理严格独立,用户的对话记录默认不落地存储;如果产品需要做用户画像分析,也必须先经过脱敏再去匿名统计。

7. 后续扩展:从“对话工具”到“人格实验室”

这次做完《见格MBTI》这类跨界对话产品,我觉得复杂提示词架构的核心收获是:给大模型设定一套可复用、可迭代的约束框架,远比追求某一次的惊艳输出重要得多。

我们已经在这套架构的基础上规划了三个扩展方向:一是加入更多人格分析体系,比如九型人格、大五人格,与五行和MBTI形成多体系交叉对话;二是增加对比分析模式,让用户邀请好友一起测试并生成关系解读;三是引入历史名人或虚构角色的人格对照,增加娱乐性和分享传播性。

这里顺便说一个踩过的坑:扩展体系时,千万不要直接往知识注入层里平铺新体系内容。每种新体系都需要独立的知识结构、映射逻辑、输出模板。正确做法是把提示词架构中的“知识槽位”做抽象,按体系平行填充,就像数据库表结构一样,而不是让一段提示词里堆积所有体系的内容。

最后再说一句我的体会:提示词工程的本质,是在模型的能力边界和产品需求之间建立一层约束网。网太松,模型会乱跑;网太密,模型的智能优势又发挥不出来。找到那个“既稳又活”的点,需要不断测试、不断积累。希望这篇文章能给正在做类似AI+文化创意类小程序的朋友一些启发,少走几步弯路。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询