You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Langchain工具调用陷入循环求助:查询IP时重复调用get_machine_ip

LangChain工具重复调用陷入循环问题

我想用LangChain实现:用户询问IP地址时调用get_machine_ip工具,该工具仅返回一个IP地址。从日志看工具已执行,但出现重复调用,程序陷入循环,求排查思路。

代码实现

from langchain_ollama import ChatOllama
from langchain.agents import AgentExecutor, create_tool_calling_agent
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.chat_history import BaseChatMessageHistory
from langchain_community.chat_message_histories import ChatMessageHistory
from langchain_core.runnables.history import RunnableWithMessageHistory
from langchain_core.tools import tool

from ip import get_caller_ip

llm = ChatOllama(
    model="llama3.2",
    temperature=0.1,
)

prompt = ChatPromptTemplate.from_messages(
    [
        (
            "system",
            """You are a helpful assistant. Respond in 20 words or fewer.
            If the user asks about their IP address, use the get_machine_ip tool.
            Example: 
            User prompt: What is my Ip address? 
            Assistant response: 127.0.0.1""",
        ),
        MessagesPlaceholder(variable_name="history"),
        MessagesPlaceholder(variable_name="agent_scratchpad"),
        ("human", "{user_input}"),
    ]
)

store = {}

@tool
def get_machine_ip():
    """Returns IPv4 address."""
    return get_caller_ip()

toolkit = [get_machine_ip]

agent = create_tool_calling_agent(llm, toolkit, prompt)

agent_executor = AgentExecutor(
    agent=agent,
    tools=toolkit,
    verbose=True,
)

def get_session_history(session_id: str) -> BaseChatMessageHistory:
    if session_id not in store:
        store[session_id] = ChatMessageHistory()
    return store[session_id]

def ask_ollama_stream(prompt, session_id):
    with_message_history = RunnableWithMessageHistory(
        agent_executor,
        get_session_history,
        input_messages_key="user_input",
        history_messages_key="history",
    )
    return with_message_history.stream({"user_input": prompt}, config={"configurable": {"session_id": session_id}})

def ask_ollama(prompt, session_id):
    with_message_history = RunnableWithMessageHistory(
        agent_executor,
        get_session_history,
        input_messages_key="user_input",
        history_messages_key="history",
    )
    return with_message_history.invoke({"user_input": prompt}, config={"configurable": {"session_id": session_id}})

运行日志

Entering new AgentExecutor chain...
Invoking: `get_machine_ip` with `{}`
Fetching IP address...
188.2.12.232
Invoking: `get_machine_ip` with `{}`
Fetching IP address...
188.2.12.232
Invoking: `get_machine_ip` with `{}`

问题排查及解决方法

  • 明确提示词终止逻辑:在系统提示词中添加“拿到工具返回的IP地址后直接输出,无需再调用工具”,让LLM清楚调用工具后的行为。修改后的系统提示词:

    你是一个乐于助人的助手,回答控制在20字以内。
    如果用户询问IP地址,调用get_machine_ip工具。
    拿到工具返回的IP后直接输出,不要再调用任何工具。
    示例:
    用户:我的IP地址是什么?
    助手:127.0.0.1
    
  • 限制Agent迭代次数:在AgentExecutor中设置max_iterations参数,避免无限循环:

    agent_executor = AgentExecutor(
        agent=agent,
        tools=toolkit,
        verbose=True,
        max_iterations=2
    )
    
  • 调整提示词顺序:将agent_scratchpad移到用户输入之后,确保LLM先处理用户问题,再参考工具调用记录:

    prompt = ChatPromptTemplate.from_messages(
        [
            ("system", "上述修改后的系统提示词内容"),
            MessagesPlaceholder(variable_name="history"),
            ("human", "{user_input}"),
            MessagesPlaceholder(variable_name="agent_scratchpad"),
        ]
    )
    
  • 确保工具返回格式正确:如果get_caller_ip()返回的不是纯字符串,转换为字符串后返回:

    @tool
    def get_machine_ip():
        """Returns IPv4 address."""
        return str(get_caller_ip())
    

内容的提问来源于stack exchange,提问作者Gervasius Twinklewinkleson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 08:48:23