0%

当前LLM的tool use风格

简要说明目前的LLM使用tools的风格,目前tool selection基本完全不需要developer介入,和早期的风格有所差异。

早期的一些ReAct的实现中,可能可以看到类似的System prompt:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
template = '''Answer the following questions as best you can. You have access to the following tools:

{tools}

Use the following format:

Question: the input question you must answer
Thought: you should always think about what to do
Action: the action to take, should be one of [{tool_names}]
Action Input: the input to the action
Observation: the result of the action
... (this Thought/Action/Action Input/Observation can repeat N times)
Thought: I now know the final answer
Final Answer: the final answer to the original input question

Begin!

Question: {input}
Thought:{agent_scratchpad}'''

但在目前Langgraph对langgraph.prebuilt.create_react_agent的实现来看,System prompt默认为空。可以通过如下代码hook以检查这一特点:

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
def get_llm():
... # omitted

@tool
def add(a: int, b: int):
"""Add two numbers."""
return a + b

llm = get_llm()
original_generate = llm._generate

def patched_generate(self, messages, stop=None, run_manager=None, **kwargs):
print("---Intercepting LLM Call---")
print("Messages:")
for msg in messages:
print(f" - {msg.pretty_repr()}")

print("\nKWargs (including tools):")
print(json.dumps(kwargs, indent=2))
print("---------------------------\n")

return original_generate(messages, stop=stop, run_manager=run_manager, **kwargs)

llm._generate = patched_generate.__get__(llm, llm.__class__)

# agent = create_react_agent(llm, tools=[add], prompt="I am a humorous robot.")
agent = create_react_agent(llm, tools=[add])

result = agent.invoke({"messages": [("human", ("3 + 3"))]})

同时如果在create_react_agent的prompt参数处传入一个str,则System message就原原本本地是你所传入的参数(同样可以通过上面的代码验证)。事实上,之前也有人在对相同的问题感到困惑(上述代码来源即在此链接中)。

这个问题的答案参见各个API的doc,以OpenAI doc为例,每次使用API时都可以把tools列表(只包含签名+描述等文本)作为参数同步上传,LLM已经经过相关finetuning,会自动决定是否使用以及用什么样的tool。于是create_react_agent只需要检查API返回值是否为tool call即可维持ReAct的循环,不用再像老版本的langchain.agents.react.agent.create_react_agent那样需要在prompt中指定ReAct的循环方式(最开头的prompt就来自这个旧ReAct agent的doc)。

因此langgraph版的ReAct基本就是一个控制流,尽管也提供了pre/post_model_hook方便改动,但这部分还不如直接改成手写方便调整逻辑链条。另外各个LLM chat工具在这个prompt问题上会频繁犯错,需要特别注意。

欢迎关注我的其它发布渠道