news 2026/5/11 12:12:11

Context Engineering与Prompt Engineering实战:构建高效AI应用的关键技术

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Context Engineering与Prompt Engineering实战:构建高效AI应用的关键技术


背景与痛点:为什么“说人话”这么难?

过去一年,我陆续给三款 SaaS 产品接入了大模型能力:客服机器人、数据洞察助手、内部知识问答。上线前都觉得自己 prompt 写得挺“性感”,结果一上真实流量就翻车:

  • 用户多问两句,模型就开始“装失忆”,答非所问;
  • 把整段对话历史都塞进去,一次请求就占掉 6k tokens,账单飙红;
  • 换成长上下文窗口模型,延迟又直接翻倍,用户侧疯狂转圈。

归根结底,问题集中在两条线:

  1. Context 管理:到底该给模型看多少历史?怎样在“记得住”和“传得快”之间做权衡?
  2. Prompt 设计:如何让模型在有限长度内稳定输出期望格式,又不被几句口语带偏?

下面把我趟出来的实战套路拆给大家。

技术对比:窗口、向量、摘要,谁才是最佳配角?

先放一张总览图,方便后面引用:

1. 滑动窗口(Windowing)

  • 原理:只保留最近 N 轮对话,超出的直接丢弃。
  • 优点:实现简单,token 可控。
  • 缺点:一旦关键信息在 N 轮之前,模型就永久失忆。

2. 向量召回 + 动态拼接(RAG 式)

  • 原理:把历史对话或文档切片向量化,按用户问题语义检索 Top-K 最相关片段,再拼进 prompt。
  • 优点:理论上“无限记忆”,且 token 随 K 值线性增长,可预测。
  • 缺点:依赖向量库质量,检索错误会直接带偏模型;每次召回都要一次向量搜索,增加 P99 延迟。

3. 摘要链(Summary Chain)

  • 原理:每当对话轮次达到阈值,先让模型自己总结前文,存成摘要,后续只传摘要+最近 N 轮。
  • 优点:兼顾长记忆与长度控制。
  • 缺点:多一次 LLM 调用,摘要可能丢失细节;摘要本身也要占 token。

4. 混合策略(Hybrid)

线上最常用:最近 3 轮完整对话 + 动态向量召回 2 条历史 + 上一步摘要。
经验值:在 4k 上下文模型里,可把平均输入压到 2k tokens 以内,召回率保持 90%+。

核心实现:给你一套能直接抄的 Python 骨架

下面代码演示“混合策略”在对话系统中的落地,依赖 openai>=1.0 与 chromadb(向量库)。
为了阅读方便,我拆成三步讲:

1. 对话状态机封装

# dialog_session.py import time from typing import List, Dict import openai from chromadb import Client as ChromaClient from chromadb.config import Settings class DialogSession: """ 负责三件事: 1. 维护原始对话历史 2. 生成/更新摘要 3. 向量库存储 & 召回 """ SUMMARY_TRIGGER = 6 # 轮数阈值 WINDOW_SIZE = 3 # 最近保留 RETRIEVAL_TOPK = 2 # 向量召回条数 def __init__(self, openai_key: str, collection_name: str = "chat_history"): openai.api_key = openai_key self.chroma = ChromaClient(Settings(anonymized_telemetry=False)) self.collection = self.chroma.get_or_create_collection(collection_name) self.raw_history: List[Dict[str, str]] = [] # 完整历史 self.summary: str = "" # 摘要 def add_turn(self, role: str, content: str): """记录一轮对话""" self.raw_history.append({"role": role, "content": content}) # 向量化入库,方便后续语义检索 self.collection.add( documents=[content], metadatas=[{"role": role, "ts": time.time()}], ids=[f"{time.time()}"] ) def _generate_summary(self) -> str: """调用 LLM 生成摘要""" prompt = ( "请将以下对话浓缩成 2 句话以内,保留关键事实与上下文:\n" + "\n".join(f"{m['role']}: {m['content']}" for m in self.raw_history) ) rsp = openai.chat.completions.create( model="gpt-3.5-turbo", messages=[{"role": "user", "content": prompt}], max_tokens=120 ) return rsp.choices[0].message.content.strip() def _retrieve_related(self, query: str) -> List[str]: """向量召回 Top-K 相关历史""" res = self.collection.query(query_texts=[query], n_results=self.RETRIEVAL_TOPK) return [d for d in res["documents"][0]] def build_prompt(self, user_input: str) -> List[Dict[str, str]]: """组装最终 prompt""" # 1. 触发摘要 if len(self.raw_history) > self.SUMMARY_TRIGGER and not self.summary: self.summary = self._generate_summary() # 2. 向量召回 related = self._retrieve_related(user_input) # 3. 截取最近窗口 recent = self.raw_history[-self.WINDOW_SIZE:] # 4. 拼装 system + context system = ["你是智能客服助手,请根据背景信息回答。"] if self.summary: system.append(f"历史摘要:{self.summary}") if related: system.append("相关背景:\n" + "\n".join(related)) messages = [{"role": "system", "content": "\n".join(system)}] messages.extend(recent) messages.append({"role": "user", "content": user_input}) return messages

2. Prompt Engineering 模板

再给一个“万能填空”版,适合输出结构化 JSON,也方便后续做字段校验。

# prompt_templates.py def json_bot_template(goal: str, required_keys: List[str], context: str = "") -> str: """ 返回一段 system prompt,要求模型必须输出合法 JSON, 并包含指定字段,否则就重试。 """ key_list = ", ".join(required_keys) return f""" {context} 你的目标是:{goal} 回答时请严格遵循以下格式,不要输出任何多余文字: {{ "{required_keys[0]}": <内容>, "{required_keys[1]}": <内容>, ... }} 确保 JSON 可被 Python json.loads 解析。 """

调用示例:

messages = [ {"role": "system", "content": json_bot_template( goal="判断用户意图并抽取参数", required_keys=["intent", "product", "date"], context="你是电商售后助手。")}, {"role": "user", "content": "我想换货,订单里那双鞋尺码小了"} ]

3. 端到端调用

# main.py from dialog_session import DialogSession import openai, os, json session = DialogSession(openai_key=os.getenv("OPENAI_KEY")) def chat(user_input: str) -> str: messages = session.build_prompt(user_input) rsp = openai.chat.completions.create( model="gpt-3.5-turbo", messages=mes, temperature=0.3, max_tokens=400 ) assistant_msg = rsp.choices[0].message.content session.add_turn("user", user_input) session.add_turn("assistant", assistant_msg) return assistant_msg if __name__ == "__main__": while True: user = input("User: ") print("Bot:", chat(user))

跑通后,你可以用tokencount工具观察:一轮真实对话平均 1.2k~1.5k tokens,比直接丢全史节省 60%+,且摘要 + 召回能覆盖 90% 的“跨轮引用”场景。

性能考量:省 token 也要省时间

  1. token 预算公式
    总输入 = system + summary + retrieved + window + user
    上线前用 1000 条真实日志跑一遍分位统计,确保 P95 不超过模型上限的 75%,给网络抖动留余量。

  2. 向量库延迟
    Chroma 本地 Docker 版在 5 万条 768 维向量下,Top-K 查询约 30~50ms;若对延迟敏感,可提前做“批量预召回”放进 Redis,用户请求时直接 O(1) 读取。

  3. 摘要频率
    摘要也是 LLM 调用,建议异步线程做,或在“用户正在输入”间隙触发,避免卡住首 token 时间。

  4. 并行生成
    对结构化输出,可让模型一次返回带字段的 JSON,减少多轮追问;若字段多,可拆成两次并行调用再合并,降低单请求 max_tokens。

避坑指南:生产环境 5 个深坑

  1. token 估算不准
    中文 & 英文混排时,官方tiktoken会多算 5~10%,预算要再留 10% 安全垫。

  2. 摘要雪崩
    摘要本身也会累加 token,记得给摘要长度设硬上限(如 120 tokens),超长就再摘要一次,防止无限套娃。

  3. 向量 ID 冲突
    时间戳当 ID 在并发高时会碰撞,改用uuid.uuid4()

  4. JSON 输出多余解释
    即使 system 里强调“不要废话”,小概率仍会夹带 “Here is the json:” 前缀,解析前务必 strip() 再做json.loads,失败就重试。

  5. 温度双标
    摘要和召回对事实准确性要求高,temperature 设 0.1~0.3;创意型回答可单独调高,但别全局复用同一参数。

开放式思考

  1. 当上下文突破 100 万字时,摘要+向量还能线性扩展吗?是否需要“分层记忆”或“图索引”新架构?
  2. 多模态(图文、音频)场景下,Context Engineering 的 token 概念被重新定义,你会如何量化成本?
  3. Prompt 自动优化(如 DSPy、APE)正在兴起,人工模板还有多大生存空间?还是说“人机共写”才是终局?

把上面的代码和模板搬到你的项目里,跑通日志看看 token 曲线,再回来聊聊你的答案。祝你少踩坑,多拿 A/B 正向指标!


版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/8 10:20:26

如何提升茅台预约成功率?智能系统的5个关键策略

如何提升茅台预约成功率&#xff1f;智能系统的5个关键策略 【免费下载链接】campus-imaotai i茅台app自动预约&#xff0c;每日自动预约&#xff0c;支持docker一键部署 项目地址: https://gitcode.com/GitHub_Trending/ca/campus-imaotai 您是否还在为茅台预约成功率低…

作者头像 李华
网站建设 2026/5/1 11:02:40

Vin象棋:基于YOLOv5的智能象棋连线工具革新方案

Vin象棋&#xff1a;基于YOLOv5的智能象棋连线工具革新方案 【免费下载链接】VinXiangQi Xiangqi syncing tool based on Yolov5 / 基于Yolov5的中国象棋连线工具 项目地址: https://gitcode.com/gh_mirrors/vi/VinXiangQi 在数字化时代&#xff0c;传统象棋训练面临识别…

作者头像 李华
网站建设 2026/5/9 3:36:25

5步精通AutoDock Vina:分子对接从理论到实战的进阶指南

5步精通AutoDock Vina&#xff1a;分子对接从理论到实战的进阶指南 【免费下载链接】AutoDock-Vina AutoDock Vina 项目地址: https://gitcode.com/gh_mirrors/au/AutoDock-Vina 痛点引入 配体-受体结合预测耗时且复杂&#xff1f;传统对接工具配置繁琐、结果准确性不足…

作者头像 李华
网站建设 2026/5/6 3:54:12

如何解决书签管理难题?这款工具让信息检索效率提升3倍

如何解决书签管理难题&#xff1f;这款工具让信息检索效率提升3倍 【免费下载链接】neat-bookmarks A neat bookmarks tree popup extension for Chrome [DISCONTINUED] 项目地址: https://gitcode.com/gh_mirrors/ne/neat-bookmarks 重构浏览器书签管理逻辑 在信息爆炸…

作者头像 李华
网站建设 2026/5/2 20:48:16

基于ChatTTS 1031 1983的AI辅助开发实践:从语音合成到自动化测试

背景与痛点&#xff1a;语音合成在自动化测试里的“慢”与“卡” 去年做车载语音助手测试时&#xff0c;我们每天要跑两千多条用例&#xff0c;每条用例都要把文本转成语音&#xff0c;再丢给识别模块做回归。最早用的云端大模型方案&#xff0c;延迟 2~4 s 不等&#xff0c;G…

作者头像 李华
网站建设 2026/5/2 0:44:31

ChatGPT中文翻译英文SCI论文的指令优化与实战指南

背景痛点&#xff1a;学术翻译的“三座大山” 写 SCI 时&#xff0c;把中文初稿译成英文往往比做实验还磨人。机翻工具普遍面临三大硬伤&#xff1a; 术语漂移——“拓扑绝缘体”被翻成 “topological insulator” 没错&#xff0c;可一旦上下文提到“拓扑保护”&#xff0c;…

作者头像 李华