前言
在大型语言模型(LLMs)领域,Context Engineering(上下文工程)是一项至关重要的精细艺术,尤其在构建高效能AI智能体时更显其价值。这项技术专注于精心筛选信息,并将其精准置入LLM有限的“内容窗口”中,为模型后续处理提供最优的信息环境。
LLM的核心工作区正是其“内容窗口”。然而,这个工作区的容量是有限的——上下文工程的精髓就在于为这个有限的空间进行信息筛选,确保LLM获得执行任务所需的“恰到好处”的信息:既要包含完成任务的所有必要元素,又要避免冗余信息的干扰。
什么是上下文?为什么它如此重要?
想象一下,如果你走进办公室,突然对同事说:“那个项目怎么样了?”同事肯定会一脸茫然。但如果你先说:“我上个月负责的客户服务升级项目”,再问“那个项目怎么样了?”,同事立即明白你在问什么。
这就是上下文的力量——它为对话提供了背景和理解的基础。
在AI对话中,上下文就是我们提供给AI的背景信息、对话历史和相关知识。它决定了AI是否能真正理解我们的意图。
AI的“记忆”有什么特点?
每个AI都有一个工作记忆区,就像我们的短期记忆。但这个记忆区有两个重要特点:容量有限,不能无限存储信息,智能系统的上下文窗口也有固定大小。主流模型的上下文长度从4K到128K token不等(1个token约等于0.75个英文单词);需要引导,需要我们提供合适的背景线索,既要包含必要元素,又要避免冗余。。
这就好比给一个新同事交代工作:说得太简单,他听不懂;说得太详细,他可能抓不住重点。
代码实战
就拿有上下文跟没有上下文模型的反馈来看效果(show me code)
import requests
import json
import time
# ==================== 全局配置 ====================
# 请根据你的聚合平台信息修改以下配置
BASE_URL = "https://api.ufunai.cn/v1" # 替换为你的平台地址
API_KEY = "sk-xxxxx" # 替换为你的API密钥
MODEL_NAME = "gpt-4-turbo" # 指定要测试的模型名称
def test_without_context():
"""无上下文测试"""
print("=== 无上下文测试 ===")
# 直接提问,不提供任何背景
prompt = "介绍一下这位作家"
response = call_model(prompt)
print(f"问题: {prompt}")
print(f"回答: {response}")
print()
return response
def test_with_context():
"""有上下文测试"""
print("=== 有上下文测试 ===")
# 提供充分的上下文
prompt = """
背景信息:
- 鲁迅(1881年9月25日-1936年10月19日),原名周树人,浙江绍兴人
- 他是中国现代文学的奠基人之一,代表作有《狂人日记》、《阿Q正传》等
- 他的作品对中国社会和文化产生了深远影响
问题:介绍一下这位作家
"""
response = call_model(prompt)
print(f"问题: 介绍一下这位作家")
print(f"回答: {response}")
print()
return response
def test_conversation():
"""对话式上下文测试"""
print("=== 对话式上下文测试 ===")
# 模拟多轮对话
conversation = [
{"role": "user", "content": "我想了解中国现代文学"},
{"role": "assistant",
"content": "好的,中国现代文学有很多杰出的作家,比如鲁迅、茅盾、巴金等。您对哪位作家特别感兴趣?"},
{"role": "user", "content": "鲁迅"},
{"role": "assistant",
"content": "鲁迅是中国现代文学的奠基人之一,他的作品深刻反映了当时的社会现实。您想了解他的哪方面?"},
{"role": "user", "content": "他的代表作有哪些?"}
]
response = call_model_with_history(conversation)
print("对话历史:")
for msg in conversation:
print(f"{msg['role']}: {msg['content']}")
print(f"最终回答: {response}")
print()
return response
def call_model(prompt):
"""调用模型(单轮对话)"""
headers = {
'Content-Type': 'application/json',
'Authorization': f'Bearer {API_KEY}'
}
payload = {
"model": MODEL_NAME,
"messages": [{"role": "user", "content": prompt}],
"max_tokens": 500,
"temperature": 0.7
}
try:
response = requests.post(
f"{BASE_URL}/chat/completions",
headers=headers,
json=payload,
timeout=30
)
if response.status_code == 200:
try:
result = response.json()
content = result['choices'][0]['message']['content']
return content
except Exception:
return f"响应非JSON: {response.text[:1000]}"
else:
return f"请求失败: HTTP {response.status_code} - {response.text[:1000]}"
except Exception as e:
return f"请求异常: {str(e)}"
def call_model_with_history(messages):
"""调用模型(带对话历史)"""
headers = {
'Content-Type': 'application/json',
'Authorization': f'Bearer {API_KEY}'
}
payload = {
"model": MODEL_NAME,
"messages": messages,
"max_tokens": 500,
"temperature": 0.7
}
try:
response = requests.post(
f"{BASE_URL}/chat/completions",
headers=headers,
json=payload,
timeout=30
)
if response.status_code == 200:
try:
result = response.json()
content = result['choices'][0]['message']['content']
return content
except Exception:
return f"响应非JSON: {response.text[:1000]}"
else:
return f"请求失败: HTTP {response.status_code} - {response.text[:1000]}"
except Exception as e:
return f"请求异常: {str(e)}"
def compare_results():
"""对比不同上下文情况下的回答"""
print("上下文工程实战演示")
print("=" * 50)
# 无上下文测试
result1 = test_without_context()
# 有上下文测试
result2 = test_with_context()
# 对话式上下文测试
result3 = test_conversation()
# 分析对比
print("=== 对比分析 ===")
print(f"无上下文回答长度: {len(result1) if isinstance(result1, str) else 0} 字符")
print(f"有上下文回答长度: {len(result2) if isinstance(result2, str) else 0} 字符")
print(f"对话式回答长度: {len(result3) if isinstance(result3, str) else 0} 字符")
# 简单的内容质量分析
keywords = ["鲁迅", "周树人", "狂人日记", "阿Q正传"]
print("\n关键词覆盖情况:")
for keyword in keywords:
count1 = result1.count(keyword) if isinstance(result1, str) else 0
count2 = result2.count(keyword) if isinstance(result2, str) else 0
count3 = result3.count(keyword) if isinstance(result3, str) else 0
print(f"'{keyword}': 无上下文({count1}) 有上下文({count2}) 对话式({count3})")
if __name__ == "__main__":
# 检查配置
if BASE_URL is None or API_KEY is None:
print("请先修改代码中的配置信息")
print("需要修改的配置:")
print(f"BASE_URL: {BASE_URL}")
print(f"API_KEY: {API_KEY}")
else:
compare_results()
程序运行结果如下:
上下文工程实战演示
==================================================
=== 无上下文测试 ===
问题: 介绍一下这位作家
回答: 请问您可以提供这位作家的名字或者相关信息吗?这样我可以更详细地介绍他/她的作品和生平等信息。
=== 有上下文测试 ===
问题: 介绍一下这位作家
回答: 鲁迅,原名周树人,是中国现代文学的重要奠基人之一,出生于浙江绍兴。他的作品在中国文学史上具有划时代的意义,不仅因其深刻的社会批判和人性探索,也因其独特的文学风格和表现手法。鲁迅的文学创作涵盖了小说、散文、杂文、诗歌等多种体裁,其中《狂人日记》被视为中国现代文学的开端,通过讽刺和批判揭示了社会的种种问题和人性的扭曲。《阿Q正传》则通过主人公阿Q的形象,揭示了民众的愚昧和被压迫的悲哀,同时也批判了旧社会的残酷与不公。鲁迅的作品不仅在文学上具有高度成就,同时也对中国社会和文化产生了深远的影响,被誉为文化大革命的精神旗帜之一。
=== 对话式上下文测试 ===
对话历史:
user: 我想了解中国现代文学
assistant: 好的,中国现代文学有很多杰出的作家,比如鲁迅、茅盾、巴金等。您对哪位作家特别感兴趣?
user: 鲁迅
assistant: 鲁迅是中国现代文学的奠基人之一,他的作品深刻反映了当时的社会现实。您想了解他的哪方面?
user: 他的代表作有哪些?
最终回答: 鲁迅的代表作品有很多,其中比较著名的有:
1. 《呐喊》:这是鲁迅的第一部短篇小说集,收录了《狂人日记》、《阿Q正传》等经典作品,揭示了封建社会的种种弊端。
2. 《彷徨》:这也是一部短篇小说集,包括《孔乙己》、《药》等作品,同样展现了社会的黑暗和人性的复杂。
3. 《故事新编》:这是鲁迅晚期的创作,采用寓言和讽刺的形式,批判了当时的社会现实。
4. 杂文集《热风》、《坟》等,其中包含了鲁迅对文化、社会、政治等方面的深刻见解。
这些作品都是中国现代文学中的经典,对理解鲁迅的思想和中国现代社会的发展都有很大的帮助。
=== 对比分析 ===
无上下文回答长度: 46 字符
有上下文回答长度: 262 字符
对话式回答长度: 264 字符
关键词覆盖情况:
'鲁迅': 无上下文(0) 有上下文(3) 对话式(5)
'周树人': 无上下文(0) 有上下文(1) 对话式(0)
'狂人日记': 无上下文(0) 有上下文(1) 对话式(1)
'阿Q正传': 无上下文(0) 有上下文(1) 对话式(1)
从返回的结果可以看出
|
场景 |
回答与问题的相关性 |
说明 |
|---|---|---|
|
无上下文 |
0-20% |
无法确定"这位作家"指谁,回答往往需要进一步澄清 |
|
有上下文提示词 |
80-90% |
明确知道讨论对象是鲁迅,回答直接相关 |
|
多轮对话上下文 |
95-100% |
不仅知道是鲁迅,还了解用户的学习意图和知识背景 |
有上下文能显著提升回答质量回答相关性提高4倍以上
常见的上下文问题
背景信息不足:AI的回答泛泛而谈,不够精准。比如你说“推荐几本书”,AI可能推荐大众畅销书。但如果你说“我是程序员,想学习项目管理,推荐几本书”,AI就能推荐更专业的书籍。
信息过多过杂:AI会“分心”,回答偏离核心。就像同时给新人交代10项工作,他反而不知道先做什么。
信息前后矛盾:AI会感到困惑,不知道以哪个为准。比如先说“客户预算有限”,后说“不用考虑价格”,AI就不知道该如何处理。
三个实用技巧,让你的对话更顺畅
先搭舞台,再唱戏:在问问题之前,先建立清晰的背景。
比如不要直接问“这个怎么样?”,而是说“我正在考虑买一台笔记本电脑,主要用于办公和偶尔的视频剪辑,预算5000左右。联想小新这个型号怎么样?”
保持对话的连续性:像真人聊天一样,让对话自然延续。
不要每次提问都当作全新的对话,而是基于之前的讨论继续深入。比如:“刚才我们讨论的营销方案,如果目标客户是年轻人,需要调整哪些部分?”
适时总结,轻装前行:当对话较长时,适时地进行总结。
比如:“我们来梳理一下目前确定的要点:1. 主打年轻人群 2. 侧重社交媒体 3. 预算10万。基于这三点,下一步具体怎么做?”
总结
上下文工程既是科学也是艺术。技术上,它涉及token管理、信息架构和对话状态维护;艺术上,它要求我们像与人交流一样,懂得如何铺垫、如何强调、如何收束。
一句话总结:把之前说过的话,作为前置条件给到大模型,让大模型在后续的对话中把这个前置条件作为事件背景,这样大模型就能更好的理解你了!
下次与AI对话时,不妨多想一步:我给的信息足够让AI理解我的真实需求吗?背景清晰吗?上下文连贯吗?
掌握了上下文的艺术,你会发现AI不再是机械地回答,而是真正理解你需求的智能助手。这不仅是技术,更是沟通的艺术——而这份艺术,完全掌握在你的手中。
好的对话,从好的上下文开始。从现在起,做个会“铺垫”的对话高手吧!
源代码如需获取,请关注公众号,发送消息ufunai-context获取,扫一扫即可获取!
创作不易,码字更不易,如果觉得这篇文章对你有帮助,记得点个关注、在看或收藏,给作者一点鼓励吧~
810

被折叠的 条评论
为什么被折叠?



