如何让LLM能够给出真正想要的答案

Xiao Qiang Lv4

在上一篇文章LLM在现实中的赋能,提到了很多LLM的衍生工程,agent、RAG,目的都是为了让LLM能够给出接近用户问题的答案的回答。对于RAG是什么以及怎么做到的我已经写了一篇文章来介绍的,这里再给大家具体介绍一下agent是如何给LLM加上决策的翅膀。在本文中,我主要会介绍一下agent的运作原理以及一些agent在实施过程中的需要注意的关键问题,最后再基于当前主流的框架 langchainllamaIndex介绍agent的实现细节。

agent框架运作

接下来,我将介绍一下agent的原理以及我认为的其中几个比较重要的关键点

原理

)众所周知的是,LLM都是训练好的模型。训练的过程是将已有的材料数据输入到编写好的模型中,通过多轮训练形成最后输出模型。例如训练好的 deepseek-chatdeepseek-reasonergpt-o1等,但是这意味当用户给出了输入之后,LLM只能通过已有的知识给出输出。所以原有的交互过程入下图所示:
Pasted image 20250922162314.png)
Agent 的出现部分是为了解决 LLM 静态知识不足的问题,但更核心的价值在于让 LLM 能够通过外部工具和环境交互来扩展能力。Agent 框架使 LLM 在一定程度上表现出自主性、适应性、感知能力和目标导向特征。其本质是将 推理(Reasoning)行动(Acting) 结合,使模型能够根据推理过程决定如何调用工具并利用结果,从而生成更合适的响应。
Pasted image 20250922171225.png
通过查看当前主流框架 langchainLlamaIndex的分析,发现两者都采用了 Thought/action/observation的思想,在框架中都有自己的输出模版

  • LlamaIndex的输出prompt
    Pasted image 20250923172518.png
  • Langchain的promptPasted image 20250923172611.png
    所以根据上述两个框架的实现,agent最终又落到了prompt engineer上

agent什么时候会停止当前的loop

每个框架中都会设置一个LLM搜索答案的最大深度,如果超过最大深度或者LLM自身认为它得到了最终的答案,就会将这些结果整理并输出给用户。

为什么agent给出准确的答案

因为在使用LLM的时候,所有的框架都会给他们一段系统级别的prompt,在这些prompt中会告诉他可以使用一些注册好的工具,他可以自主决策是否要使用工具。比如出现了一些,我想要查找当前最新的xxx的时候,LLM就是在thoughts中输出 考虑到用户需要了解最新的xxx,我应该先调用search tool,其中 调用search tool就是Action,然后外部工具又会给LLM输入最为observation,这样反复的循环,最终在可以介绍的循环范围内,停止LLM的交互,将结果返回给用户。经过这样多轮的推理,就可以降低AI幻觉的出现,给予用户较为准确的答案。

1
2
3
4
5
6
7
8
9
10
11
12
"The output should be in one of the following formats:\n"
"1. To call a tool:\n"
"```\n"
"Thought: <thought>\n"
"Action: <action>\n"
"Action Input: <action_input>\n"
"```\n"
"2. To answer the question:\n"
"```\n"
"Thought: <thought>\n"
"Answer: <answer>\n"
"```\n"

影响最终token产成速度

在现实中有很多信息会影响最终数据的生成,这里不会关心如何解决这些问题,但会把可能导致效率低下的问题列举出来

  • 当前工具和LLM接口调用的返回速度较慢
  • 当前LLM的推理速度比较慢
  • prompt构建的不到位,导致LLM不能较好的理解用户的意图,或者长度过长
  • react的次数较多

如何实现一个最小化的agent

实现细节

首先我们来拆分一下这个任务,前面已经详细的分析了agent的原理,就是 Thought/Action/Observation。拆分成具体的任务就是

  • Thought,将user context+prompt向LLM输入,得到LLM的决策结果
  • Action,使用工具
  • Observation,获得工具的结果,决策工具获取的结果是否能够满足用户的需求
    👆🏻三个步骤具体化如下
  • Thought,使用不同的对应的sdk调用LLM,定义system prompt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
REACT_PROMPT_TEMPLATE = f"""
你是一个可以使用工具的智能助手。你可以使用以下工具:
{TOOL_DESCS}
请严格按以下格式回答(每次只输出一个 Thought/Action/Final Answer):
Thought: 你当前的思考
Action: 要使用的工具名,必须是 [{TOOL_NAMES}] 之一
Action Input: 工具的输入参数,必须是合法 JSON
Observation: 工具返回的结果(由系统填充,你无需输出)
...(这个 Thought/Action/Observation 可以重复 N 次)
Thought: 我现在可以回答了
Final Answer: 你的最终答案
开始!
Question: {{input}}
{{history}}
"""

def call_llm(prompt: str) -> str:
"""调用 OpenAI LLM(你也可以替换为本地模型)"""
from openai import OpenAI
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"), base_url="https://api.deepseek.com")
response = client.chat.completions.create(
model="deepseek-chat",
messages=[{"role": "user", "content": prompt}],
temperature=0.0,
max_tokens=512,
stream=False
)
return response.choices[0].message.content.strip()
  • Action,解析LLM给出的输出,是否包含一些特殊的关键字,从而做出对应的动作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
def parse_react_output(text: str) -> Dict[str, Any]:  
"""解析 LLM 输出,提取 Thought / Action / Action Input / Final Answer""" lines = text.split("\n")
result = {"type": None, "content": None, "action_input": None}

for line in lines:
if line.startswith("Thought:"):
result["type"] = "thought"
result["content"] = line[len("Thought:"):].strip()
elif line.startswith("Action:"):
result["type"] = "action"
action_name = line[len("Action:"):].strip()
result["content"] = action_name
elif line.startswith("Action Input:"):
try:
# 尝试解析 JSON action_input = json.loads(line[len("Action Input:"):].strip())
result["action_input"] = action_input
except:
result["action_input"] = line[len("Action Input:"):].strip()
elif line.startswith("Final Answer:"):
result["type"] = "final_answer"
result["content"] = line[len("Final Answer:"):].strip()

return result
  • Observation,将用户的输入以及调用工具获得结果,再次输入给大模型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
def run_react_agent(question: str, max_steps: int = 5) -> str:  
history = ""

for step in range(max_steps):
# 1. 构造提示词
prompt = REACT_PROMPT_TEMPLATE.format(input=question, history=history)

# 2. 调用 LLM print(f"\n[Step {step + 1}] 调用 LLM...")
llm_output = call_llm(prompt)
print(f"LLM 输出:\n{llm_output}\n{'-'*50}")

# 3. 解析输出
parsed = parse_react_output(llm_output)

if parsed["type"] == "final_answer":
return parsed["content"]

elif parsed["type"] == "action":
action_name = parsed["content"]
action_input = parsed["action_input"]

# 4. 查找并执行工具
tool = next((t for t in TOOLS if t.name == action_name), None)
if not tool:
observation = f"Error: 工具 '{action_name}' 不存在"
else:
try:
# 如果 action_input 是 dict,解包;否则直接传入
if isinstance(action_input, dict):
observation = tool.func(**action_input)
else:
observation = tool.func(str(action_input))
except Exception as e:
observation = f"Tool error: {str(e)}"

print(f"[工具调用] {action_name}({action_input}) → {observation}")

# 5. 追加到历史
history += f"\nThought: {parsed.get('content', '...')}"
history += f"\nAction: {action_name}"
history += f"\nAction Input: {json.dumps(action_input, ensure_ascii=False)}"
history += f"\nObservation: {observation}"

print(f"[Step {step + 1}] 历史:\n{history}\n{'-'*50}")

else:
# 无效输出,当作 Thought 继续
history += f"\nThought: {parsed.get('content', '...')}"

return "达到最大步数,未能得出最终答案。"

测试

  • 这里我给定的问题是 周杰伦最新的专辑是什么? 用上述agent生成的结果如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
python ./minimum_agent.py   

[Step 1] 调用 LLM...
LLM 输出:
Thought: 我知道周杰伦是一位著名的歌手,但我不确定他最新的专辑是什么。为了提供准确的信息,我应该搜索最新的相关新闻或官方发布。

Action: Search
Action Input: {"query": "周杰伦最新专辑"}
--------------------------------------------------
[工具调用] Search({'query': '周杰伦最新专辑'}) → 直接回答: Zhou Jilun's latest album is expected in August or September 2025. He recently released a new song titled "即兴曲" in June 2025. His previous album, "最伟大的作品," was released in July 2022.
搜索结果 (5 条):
1. [时隔3年,继《最伟大的作品》后,周杰伦宣布要发新专辑 - 上观](https://m.jfdaily.com/wx/detail.do?id=857039): # 时隔3年,继《最伟大的作品》后,周杰伦宣布要发新专辑

纵览
2025-02-09 06:55

来源:上观新闻
作者:九派新闻

2月8日,周杰伦在社交媒体宣布他的新专辑预计在今年暑假期间发布,这让粉丝们兴奋不已。

2月2日,周杰伦在社交平台上发文,称自己半夜还在跟方文山弄歌词。他打趣到:“重点是,他真的还写得出来,他应该不是以前拖拖拉拉的方文山了。”

在周杰伦附上的聊天对话里可以看到,...
2. [周杰伦2000-2020所有专辑总集结 - 知乎专栏](https://zhuanlan.zhihu.com/p/483651514): 2016-周杰伦的床边故事

Image 23

本专辑为周杰伦与妻子昆凌结婚生子后发行的首张专辑,为周杰伦个人第14张专辑。新专辑以床边故事命名,专辑设计打造成有声书概念,诉说10个与众不同、充满想像的音乐故事。专辑中与张惠妹首度合唱,是继《依然范特西》专辑中的《千里之外》与费玉清的合作后,再次跨公司与线上歌手合唱,并且收录于专辑中。

01.床边故事

02.说走就走

03.一点点

04....
3. [周杰伦_百度百科](https://baike.baidu.com/item/%E5%91%A8%E6%9D%B0%E4%BC%A6/129156): 1/2

### 为他人创作

| | | | | |
--- ---
| 歌曲名称 | 职能 | 演唱者 | 所属专辑 | 发行时间 |
| 星动力 | 作曲 | 刘畊宏 | 单曲 | 2024-1-12 |
| AMIGO | 作曲 | 玖壹壹 | 单曲 | 2022-10-25 |
| 叱咤风云 | 作曲, 电吉他演奏 | 范逸臣, 柯有伦 | 单曲 | 2021-1-10 ...
[Step 1] 历史:

Thought: Search
Action: Search
Action Input: {"query": "周杰伦最新专辑"}
Observation: 直接回答: Zhou Jilun's latest album is expected in August or September 2025. He recently released a new song titled "即兴曲" in June 2025. His previous album, "最伟大的作品," was released in July 2022.
搜索结果 (5 条):
1. [时隔3年,继《最伟大的作品》后,周杰伦宣布要发新专辑 - 上观](https://m.jfdaily.com/wx/detail.do?id=857039): # 时隔3年,继《最伟大的作品》后,周杰伦宣布要发新专辑

纵览
2025-02-09 06:55

来源:上观新闻
作者:九派新闻

2月8日,周杰伦在社交媒体宣布他的新专辑预计在今年暑假期间发布,这让粉丝们兴奋不已。

2月2日,周杰伦在社交平台上发文,称自己半夜还在跟方文山弄歌词。他打趣到:“重点是,他真的还写得出来,他应该不是以前拖拖拉拉的方文山了。”

在周杰伦附上的聊天对话里可以看到,...
2. [周杰伦2000-2020所有专辑总集结 - 知乎专栏](https://zhuanlan.zhihu.com/p/483651514): 2016-周杰伦的床边故事

Image 23

本专辑为周杰伦与妻子昆凌结婚生子后发行的首张专辑,为周杰伦个人第14张专辑。新专辑以床边故事命名,专辑设计打造成有声书概念,诉说10个与众不同、充满想像的音乐故事。专辑中与张惠妹首度合唱,是继《依然范特西》专辑中的《千里之外》与费玉清的合作后,再次跨公司与线上歌手合唱,并且收录于专辑中。

01.床边故事

02.说走就走

03.一点点

04....
3. [周杰伦_百度百科](https://baike.baidu.com/item/%E5%91%A8%E6%9D%B0%E4%BC%A6/129156): 1/2

### 为他人创作

| | | | | |
--- ---
| 歌曲名称 | 职能 | 演唱者 | 所属专辑 | 发行时间 |
| 星动力 | 作曲 | 刘畊宏 | 单曲 | 2024-1-12 |
| AMIGO | 作曲 | 玖壹壹 | 单曲 | 2022-10-25 |
| 叱咤风云 | 作曲, 电吉他演奏 | 范逸臣, 柯有伦 | 单曲 | 2021-1-10 ...
--------------------------------------------------

[Step 2] 调用 LLM...
LLM 输出:
Thought: 我现在可以回答了
Final Answer: 周杰伦最新的专辑是2022年7月发行的《最伟大的作品》。根据最新消息,周杰伦已宣布新专辑预计在2025年暑假期间(8月或9月)发布,并在2025年6月先行发布了新歌《即兴曲》。
--------------------------------------------------


🎯 最终答案:
周杰伦最新的专辑是2022年7月发行的《最伟大的作品》。根据最新消息,周杰伦已宣布新专辑预计在2025年暑假期间(8月或9月)发布,并在2025年6月先行发布了新歌《即兴曲》。

最终在浏览中搜索,来验证结果是否正确Pasted image 20250923180851.png
LLM通过自己的决策获得和实际情况相同的结果。

总结

在使用agent之前,对于其定义和本身都感觉十分的模糊。通过这次的整体梳理,突然发现agent好像还是prompt工程的一种延伸,只不过是一类更加特殊的prompt。给LLM定义了一个特殊的角色,可以使用工具的角色。至此以后,agent的神秘感不在,以后更多的可能是关注其性能问题,如何能够在更短时间内获得用户想要的数据以及如何在token大量输入的情况下也可以让LLM能够快速的输出。

参考

  • Title: 如何让LLM能够给出真正想要的答案
  • Author: Xiao Qiang
  • Created at : 2025-09-24 09:12:42
  • Updated at : 2025-09-24 11:01:43
  • Link: http://fdslk.github.io/LLM/agent/2025/09/24/LLM-Agent-general-understanding/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments