在前两篇里,我完成了从宏观认知到场景聚焦的思维跃迁。今天我将继续,完成一次完整的端对端实践 —— 从一个模糊的创意“我想做一个倾听、理解,回应我的AI伙伴”,到最后构建出一个具备上下文感知、人格化表达、长期记忆和安全机制的可运行原型系统。这不仅仅是一次技术实现,还是一场融合用户需求洞察、系统架构设计和AI能力调用的综合实践。
我们将遵守第一篇讲述的“开发路径五步法”:需求定义->技术选型->开发集成->评估优化->部署运维,围绕“心理健康陪伴机器人”这一个具体的案例,深入拆解每一个环节的关键决策点和实现细节。
依然,我们不需要对深度学习有多少的复杂掌握,不需要是算法专家,我们将会基于主流的大模型平台(OpenAI、Deepseek)、低代码工具链和开源框架(Langchain、LlamaIndex),用工程化的方式,把大模型的能力“组合起来”,形成一个真正可用的产品。
我们的目标是
- 一套可以复用的情感聊天机器人需求分析框架
- 一份清晰的技术框架图和组件选型建议
- 多个关键功能模块的实现代码示例(提示工程模板、向量数据库接入、记忆管理逻辑)
- 对AI产品“可控性”和“人性化”之间平衡的理解
- 最重要的:亲手构建第一个大模型应用的信心和能力!
1. 需求分析:定义这个情感伙伴
任何成功的应用,都开始于对“用户是谁”和“解决什么问题“的深刻理解。对于情感机器人而言,尤其重要 —— 它处理的就是,最敏感,最复杂的人类心理活动。
1.1 明确目标用户和核心场景
让我们以这个选题为例子,先来三个基本问题
- 谁会用他? 可能有:感到孤独的年轻人、压力过大的职场人、缺乏倾诉渠道的学生、不愿面对传统心理咨询的个体、或者需要日常情绪支持的慢性病患者
- 在什么情境下使用?: 深夜失眠时的情绪宣泄、工作受挫后的自我怀疑、人际关系冲突后的迷茫、或仅仅是想要一个“不会评判我”的倾听者
- 他们真正需要的是什么?不是诊断,也不是治疗,而是被听见、被理解、被共情。心理学研究表明,有效的倾听本身就具有疗愈作用。我们的目标不是替代心理咨询师,而是提供一条低门槛、及时响应的“情感缓冲带”
产品定位:一款基于大模型的非医疗级心理健康支持助手,旨在通过自然语言对话,为用户提供情绪接纳、认识疏导和正向反馈,帮助其缓解短期压力、提高自我觉察能力。
1.2 功能需求分层设计
将抽象需求转换为具体功能,建议采用“核心功能+增强功能+安全边界”的三层结构,如表↓
| 层级 | 功能项目 | 说明 |
|---|---|---|
| 核心功能 | 实时情绪识别与共情回忆 | 能够感知用户话语里的情绪倾向(悲伤、焦虑、愤怒),并且做出匹配的情感回应 |
| 上下文连贯对话 | 维持多轮对话的记忆与逻辑一致性,避免“失忆式回复” | |
| 积极倾听和开放式提问 | 引导用户表达,而非急于给出建议 | |
| 增强功能 | 长期记忆与个性化认知档案 | 记录用户习惯、偏好、过往情绪模式,实现“越聊越懂你” |
| 情绪趋势可视化 | 提供周/月情绪波动图标,辅助自我反思 | |
| 正念练习推荐 | 根据当前情绪状态推送冥想音频、呼吸训练等轻干预内容 | |
| 安全边界 | 危机识别与转介机制 | 检测到自残、自杀等高风险表述的时候,主动提示并提供专业求助渠道 |
| 伦理准则与价值观对齐 | 确保AI不鼓励极端行为、不传播错误信息、不进行价值评判 |
MVP(最小可行产品)建议:
初期聚焦核心功能+安全边界,快速验证对话质量和用户接受度,后续迭代增强功能
1.3 非功能性需求:不可忽视的“软指标”
除了“能做什么”,我们还要考虑“做得好不好“。下面是一些软指标:
- 响应速度:理想延迟 < 2s,避免打断情绪流动
- 人格一致:AI应该有稳定的声音风格(温柔、中立、耐心)
- 隐私保护:对话数据加密存储,用户可以随时删除历史记录
- 可解释性:让用户知道”AI并不是真正的人“,避免情绪依赖错位(就像之前有一个美国小孩把ChatGPT当成了精神支柱,被诱导之后情绪反而不健康,进而自杀,因为没有提醒它,ChatGPT只是一个AI)
2. 技术选型
明确好了”做什么“,接下来要决定”怎么造”。这一类主题的技术栈虽然轻量,但是依然涉及到了多个关键组件的协同。
我们采用分层架构设计,便于模块化开发和后期拓展,如图:

2.1 大模型选择
首先要纠正一个很严肃的错误认知:
开源LLM是免费的。
从技术、经济、战略层都是错误的。如果我们要构建一个严肃的产品,这种想法是万万不可的,甚至可能是危险且天真的。开源LLM并非免费 —— 它们只不过是把成本从许可,转移到了工程、基础设施、维护与战略风险之上。


如下表,如果是闭源模型(以 GPT-5、通义千问Max为代表)语言能力强、稳定性高且生态完善,但是成本较高,根据OpenAI官方报价,GPT5的模型输入输出的1M Token 分别是1.5美刀与14美刀。已经算贵的了。同时还有数据出境的风险,适合快速验证与商业产品的场景;开源模型(Llama3、Qwen-7B)具备数据可控、可本地部署、成本低的优势,但是对于推理资源要求高而且需要调优、更适用于敏感场景和私有化部署。
| 选项 | 代表模型 | 优势 | 劣势 | 推荐用途 |
|---|---|---|---|---|
| 闭源API | GPT5、通义千问Max | 语言能力强、稳定性高、生态完善 | 数据出海,成本高 | 快速验证、商业化产品 |
| 开源模型 | Llama、Qwen | 数据可控,可以本地部署、成本低 | 需要调优,推理资源要求高 | 敏感场景、私有化部署 |
建议:初期用Deepseek,GPT等 API进行快速原型开发、成熟之后考虑换成私有化部署开源模型。
2.2 开发框架:LangChain、LlamaIndex、自研
在大模型应用开发中,LangChain、LlamaIndex和自研框架的选择需要结合场景复杂度、开发效率和功能需求综合考虑:
- LangChain:适合构建复杂Agent流程、支持多种模型、工具集成,社区比较活跃
- LlamaIndex:专精于RAG和结构化数据检索,适合只是增强型应用。
- 自研轻量框架:简单对话系统,控制精细,但是开发成本很高。
推荐组合:LangChain + 向量数据库(Chroma/Pinecone)构建基础对话流,后期按需引入LlamaIndex做知识补强。
2.3 记忆存储:短期 and 长期
- 短期记忆(会话内):之前做过LangChainJS,所以我这里可以用
ConversationBufferMemory(把历史记录原封不动地又加到上下文里,传给大模型))和SummaryMemory(使用简单的便宜的模型,总结历史记录,然后把摘要加到上下文,传给大模型),把最近N轮对话拼接成上下文传递给大模型。 长期记忆(跨会话): 使用某种模型,将用户的关键陈述(比如“我喜欢蓝色”,“我的工作是程序员,我最近在学AI开发”)提取为记忆片段,存到向量数据库,最后通过语义搜索实现“回忆“
举个例子:当用户说”我做噩梦了“,系统可以检索以往”睡眠问题“相关的记忆,做出回应:”你之前也做过噩梦,是不是最近压力又变大了?你还好吗?有没有什么我可以帮到你的?“ 这个回答就会让用户感到非常的人情味。
2.4 安全过滤:必要的”防火墙“
建议采用“双层过滤”机制:
- 输入层过滤: 使用规则引擎或者轻量的大模型检测敏感词、攻击性语言;
- 输出层监控:对AI生成内容做合规性检查,防止生成有害建议。
可集成开源方案有:ModerateContent(内容安全审核模型)或者阿里云内容安全API。
3.项目初始化
我这边构建了一个基本的学习用项目:
可以直接参考 readme 说明进行构建,和我一起,进行学习吧~
这里直接做一个LangChain的调用:
LangChain,之前我们做过,LCEL(LangChain Expression Language)
就是构建处理流程的核心方式,通过直观的“管道”(|操作符)把不同的组件串联起来,进而形成可以复用、可以拓展的处理链条。
LCEL的经典架构就是 Prompt | Model | output_parser。核心就是实现“输入处理->模型调度->输出解析”的完整链条。
最核心的一点就是LangChain的组件化 —— 把大模型的交互的各个环节拆成了独立的各个组件(提示词构建、模型调用、输出与解析)最后通过|符号(类似于Unix的管道)把这些组件按照顺序连接起来,形成数据处理的“流水线”
在Prompt->model->output_Parser这个链条里,数据会按照顺序流过每个组件:原始输入先进入Prompt组件,被格式化为模型可以理解的提示词;格式化之后的提示词再进入model,大模型生成原始的输出,最后这个输出,进入output_parser组件,被解析成更容易读懂的格式(字符串,特定格式的JSON,字典)。这个流程就是像工厂的流水线一样,每个环节只关心自己的任务,最后输出一个成品
各组件的角色与作用:
- Prompt:负责把原始输入(用户问题、上下文信息)格式化为符合大模型要求的提示词结构
- model:大语言模型(核心推理)model是链的核心,负责接收Prompt生成的完整提示词,进行推理并且生成原始输出。
- output_parser: 输出解析器(结果格式化) output_Parser负责将模型的原始输出转换为更加易用的格式。
当调用chain.invoke(inputs)的时候,整个流程就会自动触发Python运行。假设输入为用户问题,inputs = {"user_input": "我最近老是失眠,怎么办"}。
执行步骤就是:
- Prompt接受inputs,生成完整的提示词,再传递给model。
- model接受提示词,然后生成原始输出,传递给output_parser。
- output_parser接受model的原始输出,解析为特定格式的数据,多为字符串。最后返回最终结果。
下面是我仓库里的部分代码:
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from app.config.settings import Settings
from app.chat.prompts import KAGUYA_SYSTEM_PROMPT
class Engine:
def __init__(self):
settings = Settings()
self.api_key = settings.api_key
self.model = settings.model
self.api_base_url = settings.api_base_url
self.langchain_available = settings.langchain_available
self.llm = None
self.chain = None
if self.api_key and self.langchain_available:
try:
# 1. 初始化模型
# 通过Langchain的chatOpenAI组件,利用第三方API平台
kwargs = {
"model": self.model,
"temperature": 0.7,
"api_key": self.api_key,
}
if self.api_base_url:
kwargs["base_url"] = self.api_base_url
self.llm = ChatOpenAI(**kwargs)
# 2. 定义AI人格和行为准则(提示词模板)
self.template = """{system_prompt}
{{long_term_memory}}
对话历史:{{history}}
用户:{{input}}
kaguya:""".format(system_prompt=KAGUYA_SYSTEM_PROMPT)
# 3. 创建提示词模板和链(LCEL 表达式)
self.prompt = ChatPromptTemplate.from_template(self.template)
self.out_parser = StrOutputParser()
# 构建链:chain = prompt | model | output_parser
self.chain = self.prompt | self.llm | self.out_parser
print("√ LangChain LCEL链初始化成功")
except Exception as e:
print("警告: LangChain 初始化失败,将使用传统方式:{}".format(e))
self.llm = None
self.chain = None
else:
print("警告:缺少API Key或者LangChain不可用")
def chat(self, user_input: str, history: str = "", long_term_memory: str = "") -> str:
if not self.chain:
return "模型未初始化成功"
return self.chain.invoke({
"input": user_input,
"history": history,
"long_term_memory": long_term_memory,
})
我们直接在main文件里面调用且运行代码:

这样就得到了回复。我们的项目总算是有了一个开始!
这种写法的好处就在于:
- 灵活性:每个组件可以独立替换(比如说我想换GPT5.3模型,我只需要替换掉model组件,不需要修改Prompt和Parser
- 可拓展性:可以在链里插入组件(比如说Memory组件实现对话历史记忆,形成Prompt->Memory->Model->Parser)
可读性:通过 | 符号直观地展示流程,比传统的嵌套函数更加容易理解(是的,说的就是你,Typescript)
4. 最后
在开始正式的项目之前,我们还需要了解,Transform架构,文本生成机制,Prompt工程入门,上下文管理技巧,Agent架构重塑,检索增强生成等内容。在后续的几个篇章里,了解完这些内容后,我将正式开启代码的编写。