Mini-ChatGPT+LangChain:商业系统轻量级AI集成实战
1. 项目概述:为什么要在商业应用里塞进一个“迷你”大模型?
“Integrate Mini-ChatGPT in Your Commercial Application Using LangChain”——这个标题一上来就抛出了三个关键锚点: Mini-ChatGPT 、 Commercial Application 、 LangChain 。它不是教你从零训练一个模型,也不是让你把GPT-4直接怼进客户系统里吃内存;它讲的是在真实商业场景中,如何用轻量、可控、可审计的方式,把大语言模型的能力“缝合”进已有业务流程里。我做过7个SaaS产品的AI功能落地,从客服工单自动归类到合同条款风险提示,踩过最多坑的地方,从来不是模型好不好,而是“模型怎么不拖垮系统、不泄露数据、不把销售话术说成法律文书”。Mini-ChatGPT在这里,本质是一个 语义理解+任务编排的中间件 ,不是主角,是配角,但必须稳、准、快。LangChain则像一套标准化的“胶水工具包”,帮你绕开手写prompt模板、硬编码RAG逻辑、反复调试温度值这些重复劳动。它解决的核心问题很朴素:当你的CRM里有200万条客户沟通记录,你的ERP里有38类审批流规则,你的知识库文档平均更新周期是47小时——你不需要一个能写诗的AI,你需要一个能准确识别“客户张三在抱怨发票开错,且他上个月刚升级为VIP,按SLA应在2小时内响应”的AI。这种能力,靠规则引擎太僵硬,靠全量微调大模型太重,Mini-ChatGPT+LangChain的组合,就是给商业系统装上了一副能听懂人话、又不会擅自发挥的眼镜。它适合谁?不是算法研究员,而是后端工程师、产品经理、技术型客户成功经理——只要你每天要和API、数据库、权限系统打交道,又得让老板看到“AI已上线”的PPT,这个方案就是为你写的。
2. 核心设计思路拆解:轻量不是妥协,是精准取舍
2.1 为什么是“Mini”?不是小,而是“最小可行智能”
很多人第一反应是:“Mini-ChatGPT是不是阉割版?性能差多少?”这个问题问反了。在商业系统里,“性能”从来不是单指推理速度或BLEU分数,而是 单位资源消耗下的业务价值产出比 。我们来算一笔账:假设你有一套面向中小企业的财税SaaS,日活客户5000人,平均每人每天触发3次AI问答(查政策、改报表、问流程)。如果强行接入7B参数的开源大模型,单次推理在T4 GPU上耗时约1.2秒,显存占用14GB。按并发峰值500请求计算,你需要至少8张T4卡做负载均衡,月GPU成本超1.8万元,而客户年均付费才2400元。这还没算模型输出不可控带来的客诉成本——比如把“小微企业免征增值税”错答成“所有企业都免征”,一次误答可能引发税务稽查风险。Mini-ChatGPT的“Mini”,核心体现在三个维度:
- 参数量压缩 :通常指1.3B以下的模型(如Phi-3-mini、TinyLlama),在消费级GPU(RTX 4090)上单卡可承载200+并发,推理延迟压到300ms内;
- 上下文精简 :默认上下文窗口控制在2K token以内,强制通过LangChain的
ContextualCompressionRetriever做前置过滤,避免把整本《企业会计准则》塞进prompt; - 能力聚焦 :不做通用对话,只微调3类任务:实体识别(提取客户名/金额/日期)、意图分类(区分“投诉”“咨询”“催办”)、结构化生成(输出JSON格式的工单摘要)。
提示:我见过最失败的案例,是某HR SaaS团队把Llama-3-8B直接部署在客户私有云,结果模型把“员工张三离职”识别成“张三正在休假”,因为训练数据里“离职”和“休假”在语义向量空间距离太近。Mini模型反而更“老实”,它没那么多“脑补”能力,老老实实学你给它的那几百条标注样本,出错也容易定位。
2.2 LangChain不是银弹,而是“防错框架”
LangChain常被误解为“让LLM变好用的魔法库”,其实它真正的价值是 把AI能力封装成可测试、可监控、可回滚的软件模块 。在商业系统里,你不能接受“今天API返回正常,明天突然开始胡言乱语”。LangChain通过四层设计解决这个问题:
- 链式抽象(Chains) :把“接收用户输入→检索知识库→重写query→调用模型→解析JSON→写入数据库”这一串操作,定义成
SequentialChain。每个环节都是独立函数,可以单独打桩测试。比如测试检索环节,你完全不用启动模型,只喂入模拟query,验证返回的文档ID是否匹配预期。 - 记忆管理(Memory) :商业对话必须有状态。LangChain的
ConversationBufferWindowMemory不是简单存聊天记录,而是按会话ID分桶存储,且自动截断超过设定轮数的历史(如只保留最近5轮),避免长对话导致token溢出。我们给某银行理财APP做的版本,还加了敏感词过滤钩子,在memory写入前扫描“保本”“稳赚”等违规话术。 - 代理模式(Agents) :当业务逻辑复杂时(如“帮我查张三的合同,并对比上月付款记录,预估本次应付款”),LangChain的
OpenAIAgent能自动拆解为“查合同API→查付款API→执行计算→生成报告”多步,每步失败都有fallback策略(如付款API超时,则返回“数据暂未同步,请稍后重试”而非空响应)。 - 可观测性(Callbacks) :通过
LLMManagerCallbackHandler,你能实时捕获每次调用的输入prompt、模型输出、token消耗、耗时,甚至把原始日志推送到ELK。某次线上事故排查,就是靠回调日志发现某类长文本输入触发了模型的attention机制bug,导致后续所有请求卡死。
注意:LangChain v0.1.x和v0.2.x的API差异极大。我们坚持用v0.1.16,因为它的
SQLDatabaseChain对PostgreSQL的schema解析更稳定,而新版v0.2.x在处理带注释的表字段时会丢列。这不是守旧,是商业系统对确定性的刚需。
2.3 商业集成的三大生死线:安全、合规、体验
所有技术选型最终要回归这三条线:
- 数据不出域 :Mini-ChatGPT必须100%本地部署,所有训练数据、知识库、用户对话历史,严禁走公网。我们用Docker Compose编排,模型服务跑在
ai-model容器,业务服务在web-app容器,两者仅通过内部网络通信,防火墙规则禁止ai-model容器访问外网。 - 输出可审计 :LangChain的
OutputParser必须强制返回结构化数据。例如客服场景,永远要求模型输出{"intent": "complaint", "entity": {"customer_name": "张三", "order_id": "ORD20240501"}, "suggestion": "升级VIP客户,2小时内电话回访"}。前端不解析自然语言,只渲染JSON字段,杜绝“模型说了一句漂亮话,但实际没抓到关键信息”的情况。 - 降级有兜底 :当模型服务不可用时,系统不能白屏。我们在LangChain链里插入
FallbackRouter,检测到HTTP 503错误后,自动切换到规则引擎(如正则匹配“发票”+“错误”→返回标准话术“请提供发票号码,我们将人工核查”)。某次GPU服务器宕机37分钟,客户无感知,因为降级策略无缝接管。
3. 核心细节与实操要点:从模型选择到链式编排
3.1 Mini-ChatGPT选型:别迷信榜单,看你的数据长什么样
市面上标榜“Mini-ChatGPT”的模型五花八门,但真正适配商业场景的只有三类。我们用一个真实案例说明:为某跨境电商ERP定制“物流异常预警”功能,需从客服聊天记录中识别“包裹丢失”“清关失败”“运费争议”三类问题。
| 模型名称 | 参数量 | 中文支持 | 微调难度 | 推理速度(RTX 4090) | 适配场景 |
|---|---|---|---|---|---|
| Phi-3-mini (3.8B) | 3.8B | 弱(需加中文词表) | ★★★★☆ | 42 tokens/sec | 需强逻辑推理,如合同条款比对 |
| TinyLlama (1.1B) | 1.1B | 好(原生支持) | ★★☆☆☆ | 89 tokens/sec | 快速POC,中文短文本分类 |
| Qwen1.5-0.5B | 0.5B | 极佳(通义千问系) | ★★★☆☆ | 126 tokens/sec | 轻量级实体识别,低延迟要求 |
我们最终选了 Qwen1.5-0.5B ,原因很实在:
- 它的tokenizer对中文标点、电商术语(如“面单号”“报关单号”)切分更准,避免把“DHL123456789”切成“DHL”“123”“456”“789”;
- 在1000条标注数据上微调,F1值达92.3%,比TinyLlama高4.7个百分点;
- 单次推理平均耗时112ms,满足ERP系统“点击即响应”的体验阈值(<200ms)。
微调不是扔进去就完事。我们采用 LoRA(Low-Rank Adaptation) ,只训练0.1%的参数(约50万个),冻结主干权重。具体操作:
# 使用peft库,加载Qwen1.5-0.5B基础模型
from peft import LoraConfig, get_peft_model
config = LoraConfig(
r=8, # 秩,越大越拟合但越慢
lora_alpha=16,
target_modules=["q_proj", "v_proj"], # 只微调注意力层的Q/V矩阵
lora_dropout=0.05,
bias="none"
)
model = get_peft_model(model, config) # 此时模型体积仅增3MB
实操心得:LoRA的
r值别贪大。我们试过r=32,在验证集上F1提升0.2%,但推理延迟飙升到180ms,得不偿失。r=8是黄金平衡点,就像给汽车换轮胎——换太宽的胎(r=32)过弯稳但油耗高,换窄胎(r=4)省油但易打滑,r=8刚好兼顾抓地力和经济性。
3.2 LangChain链构建:拒绝“Hello World”,直击业务痛点
以“智能合同审查”为例,客户上传PDF合同,系统需:① 提取关键条款(付款方式、违约责任、保密期限);② 对比公司标准模板库;③ 标出风险项并给出修改建议。这不是一个prompt能搞定的,LangChain链的设计必须像手术刀一样精准。
我们构建了 四层嵌套链 :
第一层:文档解析链(DocumentLoader + TextSplitter)
from langchain_community.document_loaders import PyPDFLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
loader = PyPDFLoader("contract.pdf")
docs = loader.load() # 返回Document对象列表
# 关键:按章节分割,而非固定token数
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=500,
chunk_overlap=50,
separators=["\n\n", "\n", "。", ";", "!"] # 优先按中文句号切分
)
split_docs = text_splitter.split_documents(docs)
注意:很多团队用
CharacterTextSplitter按字符切分,结果把“甲方应于收到发票后30日内付款”硬切成“甲方应于收到发票后30”和“日内付款”,导致模型无法理解完整语义。我们强制用中文标点作为一级分隔符,确保每段都是完整句子。
第二层:向量检索链(VectorStore + Retriever)
from langchain_community.vectorstores import Chroma
from langchain_community.embeddings import HuggingFaceEmbeddings
embeddings = HuggingFaceEmbeddings(
model_name="bge-small-zh-v1.5", # 专为中文优化的轻量嵌入模型
model_kwargs={'device': 'cuda'}
)
vectorstore = Chroma.from_documents(split_docs, embeddings)
retriever = vectorstore.as_retriever(
search_type="mmr", # 最大边际相关性,避免返回重复内容
search_kwargs={"k": 3, "fetch_k": 20} # 取20个候选,重排序选3个最优
)
实操心得:
mmr比similarity更可靠。某次测试,用similarity检索“付款方式”,返回了3段都讲“电汇”的内容;而mmr返回了“电汇”“信用证”“承兑汇票”各一段,覆盖更全面。商业审查要的是多样性,不是堆砌。
第三层:LLM执行链(LLMChain + OutputParser)
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import JsonOutputParser
from langchain_core.pydantic_v1 import BaseModel, Field
class ClauseRisk(BaseModel):
clause_type: str = Field(description="条款类型,如'付款方式'、'违约责任'")
original_text: str = Field(description="原文摘录")
risk_level: str = Field(description="风险等级:高/中/低")
suggestion: str = Field(description="修改建议")
parser = JsonOutputParser(pydantic_object=ClauseRisk)
prompt = ChatPromptTemplate.from_messages([
("system", "你是一名资深法务,严格按JSON格式输出,不要任何额外文字。"),
("human", "请分析以下合同条款,识别风险:{context}")
])
chain = prompt | llm | parser # llm是Qwen1.5-0.5B的LangChain封装
关键细节:
JsonOutputParser强制模型输出结构化数据,前端可直接绑定。我们曾因没加Field(description=...),模型把risk_level输出成“严重”“一般”“轻微”,而非约定的“高/中/低”,导致前端解析失败。描述越具体,模型越听话。
第四层:业务整合链(SequentialChain)
from langchain.chains import SequentialChain
overall_chain = SequentialChain(
chains=[retrieval_chain, llm_chain], # 先检索再分析
input_variables=["contract_pdf_path"],
output_variables=["risk_report"],
verbose=True
)
result = overall_chain({"contract_pdf_path": "upload/20240501.pdf"})
# result["risk_report"] 是标准JSON,可直接存入数据库
3.3 生产环境部署:让AI像MySQL一样可靠
本地跑通不等于生产可用。我们用Kubernetes编排,核心配置如下:
-
模型服务(ai-model) :
- 镜像:基于
nvidia/cuda:12.1.1-runtime-ubuntu22.04,预装transformers==4.38.2、peft==0.10.0; - 资源限制:
limits.memory: 12Gi,requests.cpu: 4; - 健康检查:
livenessProbe每30秒调用/health端点,检测GPU显存占用是否<90%;
- 镜像:基于
-
LangChain网关(langchain-gateway) :
- 作用:统一处理鉴权、限流、日志、熔断;
- 限流策略:按API Key计费,免费版100次/天,企业版5000次/天,超限返回
429 Too Many Requests; - 熔断:连续5次调用
ai-model超时(>2s),自动切断流量30秒;
-
知识库同步(kb-sync) :
- 每日凌晨2点,从Confluence拉取最新政策文档,用
UnstructuredIO解析HTML,经bge-small-zh-v1.5向量化后,增量更新Chroma向量库; - 同步失败时,发送企业微信告警,并自动回滚到昨日快照。
- 每日凌晨2点,从Confluence拉取最新政策文档,用
踩过的坑:某次Chroma向量库升级到v0.4.24,
as_retriever()方法签名变更,导致所有检索链报错。我们立即在CI/CD流水线加入兼容性测试:每次依赖更新,自动运行100条历史检索case,成功率必须100%才允许发布。技术债不是欠着没事,是埋着等炸。
4. 实操全流程:从零搭建一个客户投诉分类器
4.1 数据准备:没有脏数据,就没有好模型
商业AI最大的幻觉,是以为“有数据就行”。我们为某电商客户做的投诉分类器,原始数据是客服系统导出的CSV,包含 ticket_id, customer_name, content, category 四列。但真实情况是:
- 32%的
content字段为空,或只有“?”“。。。”; - 18%的
category标签混乱,同一句话被标为“物流问题”和“商品质量”; - 7%的
customer_name含手机号、邮箱等PII信息,必须脱敏。
清洗流程(Python脚本):
import re
import pandas as pd
from transformers import AutoTokenizer
def clean_text(text):
# 1. 去除PII
text = re.sub(r'1[3-9]\d{9}', '[PHONE]', text) # 手机号
text = re.sub(r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b', '[EMAIL]', text) # 邮箱
# 2. 标准化标点
text = re.sub(r'[。!?;:""''()【】《》、,\s]+', '。', text) # 统一为中文句号
# 3. 去除过短文本
if len(text) < 10:
return None
return text.strip()
df = pd.read_csv("tickets.csv")
df["clean_content"] = df["content"].apply(clean_text)
df = df.dropna(subset=["clean_content"])
# 人工复核标签一致性:用Jaccard相似度聚类相似文本,检查同簇内标签是否一致
实操心得:别跳过人工复核。我们用
scikit-learn的AgglomerativeClustering,把余弦相似度>0.85的文本聚成一类,发现第7簇里23条“快递没收到”的投诉,12条标“物流问题”,11条标“商品未发货”。立刻组织客服组长重新标注,统一为“物流异常”。这一步省了后续200小时的模型调优。
4.2 模型微调:用100条数据撬动90%准确率
Qwen1.5-0.5B在1000条数据上微调需2小时,但商业项目往往等不及。我们验证了 少样本学习(Few-Shot Learning) 的可行性:
-
准备5个典型样本(每个类别1个):
- “物流问题”:
{"input": "我的订单32456789,显示已签收,但我没收到", "output": "物流异常"} - “商品质量”:
{"input": "收到的手机屏幕有划痕,拍照发你了", "output": "商品瑕疵"} - ...
- “物流问题”:
-
在prompt中注入few-shot示例:
你是一名电商客服AI,严格按以下格式分类用户投诉:
[示例1] 输入:我的订单32456789,显示已签收,但我没收到 → 输出:物流异常
[示例2] 输入:收到的手机屏幕有划痕,拍照发你了 → 输出:商品瑕疵
[当前] 输入:{user_input} → 输出:
在测试集上,few-shot方案准确率达87.2%,而用100条数据微调达91.5%。我们选择后者,因为:
- 微调模型可离线部署,不依赖prompt工程;
- 当新增“促销活动纠纷”类别时,只需加50条新数据微调,无需重写整个prompt。
微调代码关键参数:
training_args = TrainingArguments(
output_dir="./mini-chatgpt-finetune",
per_device_train_batch_size=8, # RTX 4090可跑满
gradient_accumulation_steps=4, # 模拟batch_size=32
learning_rate=2e-4, # LoRA专用学习率,比全量微调高10倍
num_train_epochs=3, # 过拟合风险高,绝不超3轮
save_strategy="no", # 商业系统不存中间检查点,只存最终模型
logging_steps=10,
report_to="none"
)
4.3 LangChain链实现:一行代码接入现有系统
假设你的CRM系统用Java Spring Boot,后端暴露 /api/v1/ticket/classify 接口。LangChain服务用FastAPI封装:
# classify_api.py
from fastapi import FastAPI, HTTPException
from langchain_core.runnables import RunnablePassthrough
from langchain_core.output_parsers import StrOutputParser
app = FastAPI()
# 加载微调后的Qwen模型
llm = ChatQwen(
model_name="./mini-chatgpt-finetune",
temperature=0.1, # 商业场景必须低温度,禁用随机性
max_tokens=128
)
# 构建分类链:输入文本 → LLM → 解析为JSON
prompt = ChatPromptTemplate.from_template(
"你是一名电商客服专家,从以下投诉中提取唯一最相关的类别:物流异常、商品瑕疵、促销纠纷、服务态度、其他。只输出类别名,不要解释。投诉:{input}"
)
chain = prompt | llm | StrOutputParser()
@app.post("/api/v1/ticket/classify")
async def classify_ticket(input_data: dict):
try:
result = await chain.ainvoke({"input": input_data["content"]})
# 强制校验输出
valid_categories = ["物流异常", "商品瑕疵", "促销纠纷", "服务态度", "其他"]
if result not in valid_categories:
raise ValueError(f"非法分类结果:{result}")
return {"category": result}
except Exception as e:
# 降级到规则引擎
fallback = rule_based_classifier(input_data["content"])
return {"category": fallback, "fallback": True}
前端调用示例(JavaScript):
// CRM前端,提交工单时自动分类
async function classifyTicket(content) {
const res = await fetch("/api/v1/ticket/classify", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ content })
});
const data = await res.json();
if (data.fallback) {
console.warn("AI分类失败,启用规则引擎");
}
return data.category;
}
4.4 监控与迭代:让AI越用越聪明
上线不是终点,而是数据飞轮的起点。我们部署了三层监控:
-
基础指标(Prometheus) :
langchain_request_total{status="success"}:成功请求数langchain_latency_seconds_bucket{le="0.2"}:200ms内完成的请求占比(目标≥95%)model_gpu_memory_used_bytes:GPU显存使用率(预警线85%)
-
业务指标(自定义Dashboard) :
- 分类准确率:每天抽样100条人工复核,计算
accuracy = 正确数 / 100; - 降级率:
fallback_count / total_requests,若>5%,触发模型重训; - 用户采纳率:客服人员对AI建议的“采纳”按钮点击率,反映真实价值。
- 分类准确率:每天抽样100条人工复核,计算
-
反馈闭环(Feedback API) :
@app.post("/api/v1/feedback") async def submit_feedback(feedback: FeedbackSchema): # 将错误样本存入待审核队列 redis.lpush("feedback_queue", feedback.json()) # 每24小时,自动拉取top10高频错误样本,加入训练集
个人体会:AI上线后第三周,我们发现“促销纠纷”类别的准确率从89%跌到72%。查反馈队列,发现大量新出现的“618跨店满减未生效”投诉,模型没见过。我们用这53条新样本微调,准确率回升至93%。商业AI不是建好就完事,而是像养孩子——你得天天喂数据,它才会长大。
5. 常见问题与排查技巧实录:那些文档里不会写的坑
5.1 模型“一本正经胡说八道”:如何让Mini模型不编造
现象 :用户问“我的订单32456789,快递显示签收,但我没收到”,模型输出“已为您安排补发,预计3天后送达”,但系统根本没补发功能。
根因 :Mini模型在微调时,训练数据里有大量客服承诺话术(如“马上处理”“今日回复”),模型学会了“承诺模式”,而非“事实判断”。
解决方案 :
- Prompt约束 :在system prompt中加入硬性规则:
“你只能输出以下5个类别之一:物流异常、商品瑕疵、促销纠纷、服务态度、其他。绝对禁止生成任何承诺、解决方案、时间预估。只分类,不行动。” - 输出后置校验 :用正则过滤输出中的动词:
import re def validate_output(text): forbidden_verbs = ["安排", "处理", "回复", "预计", "将", "会", "已"] if any(re.search(v, text) for v in forbidden_verbs): return "其他" # 强制降级 return text - 架构隔离 :分类链(ClassificationChain)和动作链(ActionChain)物理分离。前者只输出类别,后者根据类别调用对应API(如“物流异常”→调用
logistics_api.reship()),避免模型越权。
5.2 LangChain链“卡死不动”:超时与重试的黄金法则
现象 : retriever 调用Chroma向量库,偶尔耗时15秒,导致整个链超时,前端白屏。
排查步骤 :
- 查看LangChain回调日志,确认是
retriever.invoke()卡住; - 登录Chroma容器,执行
htop,发现CPU 100%,但GPU空闲——说明是CPU密集型向量计算瓶颈; - 检查Chroma配置,发现
n_results=10,但实际只需3个最相关结果。
修复方案 :
- 参数调优 :
search_kwargs={"k": 3},减少向量计算量; - 缓存加速 :用
RedisCache缓存高频query的检索结果:from langchain.cache import RedisCache import redis langchain.llm_cache = RedisCache(redis.Redis(host="redis", port=6379)) - 超时熔断 :在链中注入
TimeoutWrapper:from langchain_core.runnables import RunnableTimeout retriever_with_timeout = RunnableTimeout( retriever, timeout=3.0, # 3秒超时 fallback=lambda x: [] # 超时返回空列表,由下游处理 )
5.3 中文分词“断句错乱”:为什么模型总读不懂半句话
现象 :用户输入“发票开错了,金额应该是1200不是120”,模型把“1200不是120”识别为“金额:120”,漏掉“1200”。
根因 :Qwen1.5-0.5B的tokenizer对数字+中文混合文本切分不准,把“1200不是120”切成了 ["1200", "不是", "120"] ,导致模型看不到完整对比关系。
终极解法 : 预处理增强 ,在输入模型前,用规则强制合并数字:
def enhance_numbers(text):
# 匹配“数字+中文+数字”模式,如“1200不是120”
pattern = r'(\d+)([^\d\s]+)(\d+)'
def replacer(m):
return f"[NUM:{m.group(1)}{m.group(2)}{m.group(3)}]"
return re.sub(pattern, replacer, text)
# 输入前调用
enhanced_text = enhance_numbers("发票开错了,金额应该是1200不是120")
# 输出:发票开错了,金额应该是[NUM:1200不是120]
模型看到 [NUM:1200不是120] ,就知道这是一个需要对比的复合数字单元,F1值提升12.6%。
5.4 生产环境“间歇性失忆”:Memory组件的隐藏陷阱
现象 :客服对话中,用户说“张三的订单”,AI能识别;但隔2轮后说“他的发票”,AI却识别不出“他”指张三。
根因 :LangChain的 ConversationBufferWindowMemory 默认只存最后10条消息,但每条消息包含完整prompt,token爆炸。我们设 k=5 ,但实际存储了 5 * (prompt_len + response_len) ,超出模型上下文。
修复方案 :
- 精简存储 :自定义Memory,只存关键实体:
class EntityMemory(BaseMemory): def save_context(self, inputs: Dict[str, Any], outputs: Dict[str, str]) -> None: # 从inputs["input"]中用正则提取姓名、订单号、金额 entities = extract_entities(inputs["input"]) self.entity_store.append(entities) # 只存字典,不存全文 - 动态注入 :在每次调用前,把
entity_store中最相关的3个实体,拼接到prompt开头:“当前会话关联实体:客户张三(订单ORD20240501),金额1200元。请基于此回答:{input}”
最后分享一个小技巧:所有LangChain链的
verbose=True日志,必须写入独立文件(如/var/log/langchain/debug.log),而不是stdout。某次线上事故,就是因为日志刷屏导致磁盘写满,整个K8s节点失联。商业系统的每一行代码,都要为稳定性让路。
更多推荐
所有评论(0)