文章目录
-
- 前言
- [一、局限性1:幻觉(最常见!)------ 编造不存在的信息](#一、局限性1:幻觉(最常见!)—— 编造不存在的信息)
- [二、局限性2:上下文丢失------ 记不住长对话中的关键信息](#二、局限性2:上下文丢失—— 记不住长对话中的关键信息)
- [三、局限性3:逻辑推理薄弱------ 复杂逻辑、数学计算容易错](#三、局限性3:逻辑推理薄弱—— 复杂逻辑、数学计算容易错)
- [四、局限性4:工具调用混乱------ 不知道什么时候该调用工具](#四、局限性4:工具调用混乱—— 不知道什么时候该调用工具)
- [五、局限性5:对模糊需求的处理能力差------ 不会追问关键信息](#五、局限性5:对模糊需求的处理能力差—— 不会追问关键信息)
- 六、总结:LLM局限性的核心规避原则
目前国内还是很缺AI人才的,希望更多人能真正加入到AI行业,共同促进行业进步。想要系统学习AI知识的朋友可以看看我的教程http://blog.csdn.net/jiangjunshow,教程通俗易懂,风趣幽默,从深度学习基础原理到各领域实战应用都有讲解。
前言
各位小伙伴,前面咱们把LLM当Agent的"大脑",玩得风生水起------调用API、写Prompt、驱动Agent干活,感觉LLM无所不能?
但实际开发中你会发现:LLM不是"完美大脑",它有不少天生的"短板"------比如会编假数据(幻觉)、记不住长对话(上下文丢失)、复杂逻辑算错(数学/推理漏洞)。这些局限性如果不规避,Agent很可能出大问题:推荐不存在的奶茶、算错库存补货量、把用户地址搞混......
今天咱们就扒一扒LLM的5个核心局限性,每个问题都配"真实场景+避坑技巧+代码解决方案",用2025年最新的实战经验,帮你在Agent开发中绕开这些坑,让Agent更靠谱、更稳定!
一、局限性1:幻觉(最常见!)------ 编造不存在的信息
什么是幻觉?
LLM会"一本正经地胡说八道"------编造不存在的事实、数据、名称,甚至伪造API返回结果,自己却完全意识不到。
真实场景(奶茶推荐Agent)
用户问:"你们店有没有青提芝士奶茶?"
- LLM(幻觉发作):"有的!青提芝士奶茶是我们的爆款,少糖少冰口感最佳,售价19元,现在下单30分钟送达~"
- 实际情况:店里根本没有这款奶茶,库存、价格都是编的!
为什么会出现?
- LLM的训练数据是"截止到某个时间点"的(比如GPT-4o截止到2025年中),之后的新信息可能不知道;
- 遇到不确定的问题,LLM会"猜"一个看起来合理的答案,而不是说"不知道";
- Prompt中没有明确"不知道就如实说",LLM为了"完成任务"会强行编造。
避坑技巧+代码解决方案
核心思路:让LLM"知之为知之,不知为不知",关键信息必须验证
- Prompt中明确禁止幻觉:加入"不确定的信息不要编造,直接回复'没有相关信息'";
- 关键信息绑定外部工具:产品列表、库存、价格等动态信息,必须调用API/数据库获取,不让LLM凭空回答;
- 使用"事实检查"机制:让LLM先判断"这个信息是否需要验证",再决定是否调用工具。
代码实战(幻觉抑制版奶茶推荐Agent)
python
import os
import json
from dotenv import load_dotenv
from openai import OpenAI
load_dotenv()
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"), timeout=30)
# 模拟外部工具:查询店铺真实产品列表
def get_real_products() -> list:
"""返回店铺真实存在的奶茶列表"""
return [
{"name": "青提茉莉", "price": 18, "toppings": ["椰果", "脆波波"]},
{"name": "西瓜啵啵", "price": 19, "toppings": ["脆波波"]},
{"name": "芋泥鲜奶", "price": 22, "toppings": ["芋圆"]}
]
def milk_tea_recommend_agent(user_input: str) -> str:
# Prompt中加入幻觉抑制和事实检查规则
prompt = f"""
# 角色
你是奶茶推荐Agent,只能推荐店铺真实存在的产品,不编造任何信息。
# 核心规则
1. 先判断用户询问的产品是否在提供的真实产品列表中;
2. 真实产品列表:{json.dumps(get_real_products(), ensure_ascii=False)};
3. 存在的产品:推荐时说明价格和配料,语言亲切;
4. 不存在的产品:直接回复"抱歉,我们店暂时没有{产品名},推荐尝试青提茉莉/西瓜啵啵,清爽又解渴~",不要编造价格、库存等信息;
5. 不确定的信息:一律回复"没有相关信息",不猜测。
用户输入:{user_input}
"""
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": prompt}],
temperature=0.3 # 低温度减少幻觉
)
return response.choices[0].message.content.strip()
# 测试:询问不存在的产品
if __name__ == "__main__":
user_input = "你们店有没有青提芝士奶茶?"
print("用户输入:", user_input)
print("Agent回复:", milk_tea_recommend_agent(user_input))
# 输出:抱歉,我们店暂时没有青提芝士奶茶,推荐尝试青提茉莉/西瓜啵啵,清爽又解渴~
二、局限性2:上下文丢失------ 记不住长对话中的关键信息
什么是上下文丢失?
LLM的上下文窗口是有限的(比如GPT-3.5-turbo是16k token,GPT-4o是128k token),长对话中,前面提到的关键信息(比如用户的忌口、地址、预算)会被"遗忘"。
真实场景(订单处理Agent)
用户:"我要一杯少糖去冰的珍珠奶茶,送到XX路123号,预算20以内。"
Agent:"好的,确认订单:少糖去冰珍珠奶茶,配送地址XX路123号,16元,是否下单?"
用户:"再加一杯椰果奶茶,同样少糖去冰。"
Agent(上下文丢失):"好的,确认订单:少糖去冰椰果奶茶,请问配送地址是哪里?预算多少?"
- 问题:忘记了用户之前说的地址和预算!
为什么会出现?
- 每轮对话的
messages列表会累积,如果超过模型的上下文窗口,早期信息会被截断; - LLM不会主动"记忆"关键信息,需要开发者手动提取并传递。
避坑技巧+代码解决方案
核心思路:主动提取并保存关键信息,每轮对话都带上
- 关键信息提取:从对话中提取用户的地址、预算、忌口等核心信息,用字典/数据库保存;
- 上下文压缩:长对话中,只保留关键信息和最近几轮对话,删除无关内容;
- 每轮对话传递关键信息:把保存的关键信息,在每轮Prompt中明确告知LLM。
代码实战(上下文记忆版订单处理Agent)
python
import os
from dotenv import load_dotenv
from openai import OpenAI
load_dotenv()
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"), timeout=30)
class OrderAgent:
def __init__(self):
# 保存关键信息(模拟记忆模块)
self.user_info = {
"address": None,
"budget": None,
"sugar": None,
"ice": None,
"orders": []
}
def extract_key_info(self, user_input: str, llm_response: str):
"""提取用户输入和LLM回复中的关键信息,更新到user_info"""
# 调用LLM辅助提取关键信息(避免手动写复杂正则)
extract_prompt = f"""
从用户输入和Agent回复中,提取以下关键信息:
1. 配送地址(address):如XX路123号
2. 预算(budget):如20以内、18元
3. 甜度(sugar):如少糖、无糖
4. 冰量(ice):如去冰、少冰
5. 订单内容(orders):如珍珠奶茶、椰果奶茶
输出JSON格式,没有的信息填null。
用户输入:{user_input}
Agent回复:{llm_response}
"""
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": extract_prompt}],
response_format={"type": "json_object"}
)
extracted = json.loads(response.choices[0].message.content.strip())
# 更新user_info(只更新非null的信息)
for key, value in extracted.items():
if value is not None and key in self.user_info:
if key == "orders":
self.user_info[key].extend(value)
else:
self.user_info[key] = value
def handle_order(self, user_input: str) -> str:
# 构建Prompt:带上已保存的关键信息
prompt = f"""
# 角色
你是订单处理Agent,负责奶茶订单的接收和确认,记住用户的关键信息,不要重复询问。
# 已掌握的用户信息
配送地址:{self.user_info['address'] or '未提供'}
预算:{self.user_info['budget'] or '未提供'}
甜度偏好:{self.user_info['sugar'] or '未提供'}
冰量偏好:{self.user_info['ice'] or '未提供'}
已点订单:{self.user_info['orders'] or '无'}
# 任务指令
1. 若用户新增订单,结合已掌握的信息,补充缺失的内容(如地址未提供则询问);
2. 不要重复询问已掌握的信息;
3. 确认订单时,列出所有已点产品、配送地址、总金额(假设奶茶均价16元)。
用户输入:{user_input}
"""
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": prompt}],
temperature=0.3
)
llm_response = response.choices[0].message.content.strip()
# 提取关键信息并更新记忆
self.extract_key_info(user_input, llm_response)
return llm_response
# 测试长对话
if __name__ == "__main__":
agent = OrderAgent()
# 第一轮对话
user1 = "我要一杯少糖去冰的珍珠奶茶,送到XX路123号,预算20以内。"
print("用户1:", user1)
resp1 = agent.handle_order(user1)
print("Agent1:", resp1)
# 输出:确认订单:少糖去冰珍珠奶茶,配送地址XX路123号,金额16元(符合预算20以内)。是否确认下单?
# 第二轮对话(新增订单)
user2 = "再加一杯椰果奶茶,同样少糖去冰。"
print("\n用户2:", user2)
resp2 = agent.handle_order(user2)
print("Agent2:", resp2)
# 输出:确认订单:1.少糖去冰珍珠奶茶 2.少糖去冰椰果奶茶,配送地址XX路123号,总金额32元。是否确认下单?
三、局限性3:逻辑推理薄弱------ 复杂逻辑、数学计算容易错
什么是逻辑推理薄弱?
LLM擅长语言理解,但不擅长复杂逻辑推理(比如多步骤决策)和精确数学计算(比如库存补货量、订单金额统计),容易出现低级错误。
真实场景(库存监控Agent)
库存数据:珍珠15(阈值20)、椰果8(阈值15)、芋圆5(阈值10)
补货规则:补货量 = 阈值 × 2 - 当前库存
- LLM计算结果:珍珠补货20×2-15=25(正确)、椰果15×2-8=22(正确)、芋圆10×2-5=10(错误!应该是15)
- 问题:简单的数学计算出错,导致补货量不足。
为什么会出现?
- LLM是语言模型,不是计算器,没有内置的精确计算模块;
- 复杂逻辑需要"一步步推导",LLM可能跳过中间步骤,导致结果错误;
- 温度参数过高(比如0.7以上),会增加逻辑错误的概率。
避坑技巧+代码解决方案
核心思路:把复杂逻辑、数学计算"交给代码",LLM只负责决策和调度
- 数学计算用代码实现:库存统计、金额计算、日期处理等,直接用Python代码写,不依赖LLM;
- 复杂逻辑拆分成步骤:让LLM把复杂任务拆成子任务,每个子任务用代码执行;
- 低温度+逻辑验证 :调小
temperature(0.1~0.3),并让LLM输出推理步骤,方便验证。
代码实战(精确计算版库存监控Agent)
python
import os
import json
from dotenv import load_dotenv
from openai import OpenAI
load_dotenv()
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"), timeout=30)
# 数学计算用代码实现(避免LLM出错)
def calculate_replenish(current_stock: int, threshold: int) -> int:
"""精确计算补货量:补货量 = 阈值 × 2 - 当前库存"""
return max(0, threshold * 2 - current_stock) # 确保补货量不为负
def inventory_agent(stock_data: dict) -> str:
# 预设阈值
thresholds = {"珍珠": 20, "椰果": 15, "芋圆": 10, "脆波波": 12}
# 1. 代码计算补货量(精确无错)
replenish_list = []
for material, current in stock_data.items():
threshold = thresholds.get(material, 0)
if current < threshold:
replenish_qty = calculate_replenish(current, threshold)
replenish_list.append({
"material": material,
"current_stock": current,
"threshold": threshold,
"replenish_quantity": replenish_qty
})
# 2. LLM只负责生成自然语言回复(不参与计算)
prompt = f"""
你是库存监控Agent,根据以下精确计算的补货清单,生成简洁明了的库存预警通知。
补货清单:{json.dumps(replenish_list, ensure_ascii=False)}
输出格式:分点列出需要补货的原料、当前库存、需补货量,语言专业简洁。
"""
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": prompt}],
temperature=0.1
)
return response.choices[0].message.content.strip()
# 测试:计算芋圆补货量
if __name__ == "__main__":
stock_data = {"珍珠": 15, "椰果": 8, "芋圆": 5}
print("库存数据:", stock_data)
print("库存预警通知:")
print(inventory_agent(stock_data))
# 输出:
# 1. 珍珠:当前库存15,阈值20,需补货25
# 2. 椰果:当前库存8,阈值15,需补货22
# 3. 芋圆:当前库存5,阈值10,需补货15(正确!)
四、局限性4:工具调用混乱------ 不知道什么时候该调用工具
什么是工具调用混乱?
LLM在判断"是否需要调用工具""调用哪个工具"时,容易出现决策错误------比如不需要工具时强行调用,需要工具时却直接回答,或者调用错误的工具。
真实场景(工具调用决策Agent)
用户问:"奶茶有哪些口味?"(不需要调用工具,直接回答)
- LLM决策:"需要调用订单查询工具,查询可用口味"(错误!)
用户问:"我的订单什么时候送达?"(需要调用订单查询工具) - LLM决策:"你的订单预计30分钟后送达"(错误!没有调用工具,凭空猜测)
为什么会出现?
- Prompt中没有明确工具的"能力边界",LLM不知道哪些问题需要工具;
- 工具太多时,LLM难以区分不同工具的用途;
- 没有给出决策示例,LLM不知道如何判断。
避坑技巧+代码解决方案
核心思路:明确工具边界、给出决策规则和示例,让LLM"有章可循"
- 工具能力清单化:明确列出每个工具的用途、输入参数、输出结果;
- 决策规则明确化:用"if-else"的形式,告诉LLM不同场景下的决策逻辑;
- 提供决策示例:给出正确和错误的决策案例,帮助LLM理解。
代码实战(精准决策版工具调用Agent)
python
import os
import json
from dotenv import load_dotenv
from openai import OpenAI
load_dotenv()
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"), timeout=30)
# 工具能力清单
TOOLS = [
{
"name": "weather",
"description": "查询实时天气(温度、降雨概率),输入参数:城市名",
"usage": "用户问天气相关问题时调用"
},
{
"name": "order_query",
"description": "查询订单状态、配送时间,输入参数:订单号",
"usage": "用户问订单相关问题时调用"
},
{
"name": "product_list",
"description": "查询奶茶口味、价格,无输入参数",
"usage": "用户问奶茶口味、价格时调用"
}
]
def tool_decision_agent(user_input: str) -> dict:
prompt = f"""
# 角色
你是工具调用决策Agent,负责判断是否需要调用工具、调用哪个工具,决策必须准确。
# 工具能力清单
{json.dumps(TOOLS, ensure_ascii=False)}
# 决策规则
1. 能直接回答的问题(如"你是谁""奶茶是什么")→ 不调用工具,直接回复;
2. 需要外部信息的问题:
- 天气相关 → 调用weather工具;
- 订单相关 → 调用order_query工具;
- 奶茶口味/价格 → 调用product_list工具;
3. 没有对应工具的问题 → 回复"无法提供该信息,请换个问题"。
# 决策示例
示例1:用户输入"北京今天天气怎么样?" → need_tool=true,tool_name=weather,tool_params={"city": "北京"}
示例2:用户输入"我的订单ORDER001什么时候到?" → need_tool=true,tool_name=order_query,tool_params={"order_id": "ORDER001"}
示例3:用户输入"奶茶有哪些口味?" → need_tool=true,tool_name=product_list,tool_params={}
示例4:用户输入"你好" → need_tool=false,reply="你好!我是奶茶店智能助手,有什么可以帮你?"
# 输出格式
JSON格式,字段:
- need_tool: true/false
- tool_name: 工具名(weather/order_query/product_list/none)
- tool_params: 工具参数(字典)
- reply: 给用户的回复(不需要工具时填)
用户输入:{user_input}
"""
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": prompt}],
response_format={"type": "json_object"},
temperature=0.2
)
return json.loads(response.choices[0].message.content.strip())
# 测试不同场景
if __name__ == "__main__":
# 场景1:需要调用product_list工具
user1 = "奶茶有哪些口味?"
print("用户1:", user1)
print("决策结果:", tool_decision_agent(user1))
# 输出:{"need_tool": true, "tool_name": "product_list", "tool_params": {}, "reply": ""}
# 场景2:需要调用order_query工具
user2 = "我的订单ORDER002什么时候送达?"
print("\n用户2:", user2)
print("决策结果:", tool_decision_agent(user2))
# 输出:{"need_tool": true, "tool_name": "order_query", "tool_params": {"order_id": "ORDER002"}, "reply": ""}
# 场景3:不需要调用工具
user3 = "你好!"
print("\n用户3:", user3)
print("决策结果:", tool_decision_agent(user3))
# 输出:{"need_tool": false, "tool_name": "none", "tool_params": {}, "reply": "你好!我是奶茶店智能助手,有什么可以帮你?"}
五、局限性5:对模糊需求的处理能力差------ 不会追问关键信息
什么是对模糊需求的处理能力差?
用户的需求往往是模糊的(比如"帮我点杯适合夏天的奶茶"),LLM如果没有明确的追问规则,可能会直接推荐,而不是追问关键信息(如甜度、冰量、预算),导致推荐不符合预期。
真实场景(奶茶推荐Agent)
用户:"帮我点杯适合夏天的奶茶。"
- LLM回复:"推荐西瓜啵啵,少糖少冰,19元~"(错误!没有追问用户的甜度偏好、预算、是否有忌口)
- 问题:用户可能是"无糖党",或者预算15元以内,推荐不符合需求。
为什么会出现?
- Prompt中没有明确"模糊需求需要追问",LLM默认直接给出答案;
- 没有列出需要追问的关键信息(如甜度、冰量、预算、忌口);
- 没有规定追问的顺序,LLM可能遗漏重要信息。
避坑技巧+代码解决方案
核心思路:明确模糊需求的判断标准和追问规则,让LLM"主动问清楚"
- 定义模糊需求的判断标准:比如"没有提到甜度、冰量、预算、忌口的需求,都是模糊需求";
- 列出需要追问的关键信息:按优先级排序(如甜度→冰量→预算→忌口);
- 每次只追问一个问题:避免一次性问多个,让用户反感。
代码实战(精准追问版奶茶推荐Agent)
python
import os
import json
from dotenv import load_dotenv
from openai import OpenAI
load_dotenv()
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"), timeout=30)
def milk_tea_agent(user_input: str, user_info: dict = None) -> tuple:
"""
返回:(agent_reply, updated_user_info)
updated_user_info:更新后的用户信息(包含追问到的关键信息)
"""
user_info = user_info or {"sugar": None, "ice": None, "budget": None, "allergic": None}
# 关键信息清单(按优先级排序)
key_info = ["sugar", "ice", "budget", "allergic"]
# 检查是否有缺失的关键信息
missing_info = [info for info in key_info if user_info[info] is None]
prompt = f"""
# 角色
你是奶茶推荐Agent,用户需求模糊时,按优先级追问关键信息,每次只问一个问题。
# 关键信息优先级
1. sugar(甜度):全糖/半糖/少糖/无糖
2. ice(冰量):多冰/少冰/去冰/常温
3. budget(预算):如20以内、15元左右
4. allergic(忌口):如珍珠、椰果
# 任务指令
1. 若有缺失的关键信息:按优先级追问第一个缺失的信息,语气友好;
2. 若所有关键信息都齐全:推荐适合夏天的奶茶(清爽型),说明理由,贴合用户信息;
3. 不要一次性问多个问题,不要推荐不符合预算或忌口的饮品。
# 当前用户信息
{json.dumps(user_info, ensure_ascii=False)}
缺失的信息:{missing_info or '无'}
用户输入:{user_input}
"""
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": prompt}],
temperature=0.4
)
agent_reply = response.choices[0].message.content.strip()
# 提取用户回复中的关键信息(如果是回答追问)
if missing_info:
extract_prompt = f"""
从用户输入中提取{missing_info[0]}({key_info_dict[missing_info[0]]}),没有则返回null。
key_info_dict:{{"sugar": "甜度", "ice": "冰量", "budget": "预算", "allergic": "忌口"}}
用户输入:{user_input}
"""
extract_response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": extract_prompt}],
temperature=0.1
)
extracted_value = extract_response.choices[0].message.content.strip()
if extracted_value != "null":
user_info[missing_info[0]] = extracted_value
return agent_reply, user_info
# 测试模糊需求追问流程
if __name__ == "__main__":
user_info = {}
# 第一轮:用户需求模糊
user1 = "帮我点杯适合夏天的奶茶。"
print("用户1:", user1)
reply1, user_info1 = milk_tea_agent(user1, user_info)
print("Agent1:", reply1)
print("更新后用户信息:", user_info1)
# 输出:Agent1:请问你想要什么甜度的奶茶呀?(全糖/半糖/少糖/无糖);user_info1:{"sugar": None, "ice": None, "budget": None, "allergic": None}
# 第二轮:用户回答甜度
user2 = "少糖。"
print("\n用户2:", user2)
reply2, user_info2 = milk_tea_agent(user2, user_info1)
print("Agent2:", reply2)
print("更新后用户信息:", user_info2)
# 输出:Agent2:请问你想要什么冰量的奶茶呀?(多冰/少冰/去冰/常温);user_info2:{"sugar": "少糖", "ice": None, "budget": None, "allergic": None}
# 第三轮:用户回答冰量+预算
user3 = "去冰,预算20以内。"
print("\n用户3:", user3)
reply3, user_info3 = milk_tea_agent(user3, user_info2)
print("Agent3:", reply3)
print("更新后用户信息:", user_info3)
# 输出:Agent3:推荐青提茉莉奶茶,少糖去冰,18元(符合20以内预算),清爽果味超适合夏天~;user_info3:{"sugar": "少糖", "ice": "去冰", "budget": "20以内", "allergic": None}
六、总结:LLM局限性的核心规避原则
LLM的局限性看似多,但核心规避原则只有一个:让LLM做它擅长的事(语言理解、决策调度、自然语言生成),把它不擅长的事(精确计算、长时记忆、逻辑验证)交给代码和外部工具 。
整理成一张表,方便你快速查阅:
| 局限性 | 核心规避方法 | 工具/技巧 |
|---|---|---|
| 幻觉 | 禁止编造,关键信息验证 | Prompt规则+外部API/数据库 |
| 上下文丢失 | 主动提取关键信息,每轮传递 | 记忆模块+上下文压缩 |
| 逻辑推理薄弱 | 复杂逻辑、计算交给代码 | Python函数+步骤拆分 |
| 工具调用混乱 | 明确工具边界、决策规则和示例 | 工具清单+决策示例 |
| 模糊需求处理差 | 定义模糊标准,按优先级追问 | 关键信息清单+分步追问 |
记住:Agent的强大,不是因为LLM完美无缺,而是因为我们用代码和工具,弥补了LLM的短板------让LLM负责"思考和决策",让代码负责"执行和验证",两者结合,才能打造出稳定、靠谱的智能Agent。
如果你觉得这篇够实用、能直接解决开发中的坑,欢迎点赞!
