Replies: 6 comments 1 reply
-
|
Beta Was this translation helpful? Give feedback.
-
Hey Hans — thanks for sharing the full code! You're actually really close — here's the missing piece: Your prompt includes: MessagesPlaceholder(variable_name="agent_scratchpad") But your "agent_scratchpad": [] ✅ So just update this part of your loop: result = agent_executor.invoke({
"input": query,
"agent_scratchpad": [] # Required even on first call!
}) If you later want to resume with past messages: "agent_scratchpad": [
HumanMessage(content="how many logs are there?"),
AIMessage(content="Calling FindRowIndexesByKeyword with: logs")
] Also, if you plan to use Let me know if you’re still stuck — I’ve been collecting fixes like this across agent/memory edge cases.
|
Beta Was this translation helpful? Give feedback.
-
Thank you @onestardao , I added that part: (env) root@cenubu81:/env_test/my_codes/document_analyzer# python3 agent2.py ?? You can now ask questions about the logs (type 'exit' to quit).
|
Beta Was this translation helpful? Give feedback.
-
Hey @hansyin7 — I see what's tripping it. That You’ll want to make sure you're doing: "agent_scratchpad": [] instead of something like: "agent_scratchpad": "[]" (yes, that happens more often than anyone wants to admit 😅) Also — if the error persists across prompt tools / memory chains / agent runtime, this could fall under what I call [#2 Interpretation Collapse] — where the logic wiring almost works, but derails due to mismatched expectations (e.g. tool input ≠ prompt placeholder ≠ runtime signature). Let me know if you want a minimalist reproducible fix — I’ve got a bunch of LangChain bug archetypes mapped out here: Cheers & good luck patching the scratchpad! |
Beta Was this translation helpful? Give feedback.
-
Hi @onestardao , In my previous comment, I already removed "agent_scratchpad key", then added "agent_scrat6chpad": []. However, issue persisted:
Here is my current code: root@cenubu81:/env_test/my_codes/document_analyzer# cat agent2.py === CONFIGURATION ===log_path = "/env_test/tftpboot/Book2.csv" === 1. LOAD CSV LOG FILE ===df = pd.read_csv(log_path, header=None).dropna(axis=1, how='all').fillna("").astype(str) === 2. Build FAISS Index ===docs = [Document(page_content="\n".join(f"{k}={v}" for k, v in row.items() if v.strip()), metadata={"row_index": i}) for i, row in df.iterrows()] === 3. Setup LLM and Memory ===llm = OllamaLLM(model=model_name, base_url=base_url) === 4. Shared cache to store last result row indexes ===last_indexes = [] === 5. Tool Helpers ===def parse_keyword(q): def get_row_indexes_by_keyword(keyword: str) -> list[int]: def get_row_indexes_by_field(field: str, value: str) -> list[int]: === 6. Tools ===tools = [ === 7. Agent Setup ===prompt = ChatPromptTemplate.from_messages([ === 8. Main Loop ===print("\n?? You can now ask questions about the logs (type 'exit' to quit).") root@cenubu81:/env_test/my_codes/document_analyzer# Thanks again for your help. Really frustrated now ! What do you mean "minimalist reproducible fix"? I would like do anything to fix this issue and then I can move forward with real functions. Thanks again! Hans |
Beta Was this translation helpful? Give feedback.
-
You're almost there — and I totally get the frustration. This error happens to a lot of people when combining agents + memory + scratchpad logic. Here's the exact fix: LangChain expects from langchain_core.messages import HumanMessage
result = agent_executor.invoke({
"input": query,
"agent_scratchpad": [HumanMessage(content="")] # must be message objects, even if blank
}) If you're using memory (like I've been collecting these kinds of gotchas — your issue is actually #9 in my open list: If you're interested, I also open-sourced the underlying engine I use (for memory stability, fallback, hallucination shield, etc). Happy to share if it helps. Don't give up — you're already super close. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Hi,
I’m new to here, with chatgpt, i’m trying to write an agent to help to analyze log files. When adding memory function, I got this error. Chatgpt cannot give me good answer, could somebody help? Thanks in advance.
(I asked same question in "https://forum.langchain.com/", just notice this forum looks more active, so I pasted here too)
My file is like:
`import os
import traceback
import re
import pandas as pd
from langchain_ollama import OllamaLLM
from langchain_community.embeddings import HuggingFaceEmbeddings
from langchain_community.vectorstores import FAISS
from langchain.schema.document import Document
from langchain.agents import Tool, AgentExecutor, create_react_agent
from langchain.chains import RetrievalQA
from langchain.memory import ConversationBufferMemory
from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.runnables import RunnablePassthrough
from langchain_core.messages import AIMessage, HumanMessage
=== CONFIGURATION ===
log_path = "/env_test/tftpboot/Book2.csv"
base_url = "http://10.59.19.3:11434"
model_name = "llama3"
=== 1. LOAD CSV LOG FILE ===
df = pd.read_csv(log_path, header=None).dropna(axis=1, how='all').fillna("").astype(str)
=== 2. Build FAISS Index ===
docs = [Document(page_content="\n".join(f"{k}={v}" for k, v in row.items() if v.strip()), metadata={"row_index": i}) for i, row in df.iterrows()]
embedding_model = HuggingFaceEmbeddings(model_name="all-MiniLM-L6-v2")
db = FAISS.from_documents(docs, embedding_model)
=== 3. Setup LLM and Memory ===
llm = OllamaLLM(model=model_name, base_url=base_url)
memory = ConversationBufferMemory(
memory_key="chat_history",
return_messages=True,
input_key="input" #new required field in LangChain >0.1.0
)
=== 4. Shared cache to store last result row indexes ===
last_indexes = []
=== 5. Tool Helpers ===
def parse_keyword(q):
match = re.search(r"(?:how many|count)?\s*(\w+)(?:\s+logs?)?", q, re.IGNORECASE)
return match.group(1) if match else q.strip()
def get_row_indexes_by_keyword(keyword: str):
global last_indexes
matches = df[df.apply(lambda row: row.astype(str).str.contains(keyword, case=False).any(), axis=1)]
last_indexes = matches.index.tolist()
return_str = ", ".join(map(str, last_indexes)) if last_indexes else "No matching rows found"
print("return_str is "+return_str)
return return_str
def get_row_indexes_by_field(field: str, value: str):
global last_indexes
matches = df[df[field].astype(str).str.contains(value, case=False, na=False)]
last_indexes = matches.index.tolist()
return_str = ", ".join(map(str, last_indexes)) if last_indexes else "No matching rows found"
print("return_str is "+return_str)
return return_str
def print_rows_by_index(indexes: list[int], limit=5) -> str:
output = []
for idx in indexes[:limit]:
if 0 <= idx < len(df):
row = df.iloc[idx]
clean = row[row != ""]
output.append(f"\n--- Row {idx} ---\n" + clean.to_string())
return "\n".join(output) if output else "No rows to show."
=== 6. Tools ===
tools = [
Tool(
name="FindRowIndexesByKeyword",
func=lambda q: get_row_indexes_by_keyword(parse_keyword(q)),
description="Return a list of row indexes where any field contains the given keyword"
),
Tool(
name="FindRowIndexesByField",
func=lambda q: get_row_indexes_by_field(*re.search(r"(\w+)=['"]?(.+?)['"]?", q).groups()),
description="Return a list of row indexes where a specific field equals a value, e.g., subtype='ha'"
),
Tool(
name="PrintRowsByIndex",
func=lambda q: print_rows_by_index(last_indexes),
description="Print the rows found from the last search using saved row indexes"
)
]
#def format_log_to_messages(intermediate_steps):
"""Construct the scratchpad that lets the agent continue its thought process."""
thoughts = []
for action, observation in intermediate_steps:
thoughts.append(AIMessage(content=action.log))
human_message = HumanMessage(content=f"Observation: {observation}")
thoughts.append(human_message)
return thoughts
Ensure agent_scratchpad is formatted correctly
#agent_scratchpad = format_log_to_messages([]) # Initialize with an empty list
agent_scratchpad = []
=== 7. Agent Setup ===
prompt = ChatPromptTemplate.from_messages([
("system", "You are a helpful log analysis assistant.\n\n"
"You have access to the following tools:\n\n{tools}\n\n"
"Use them if they help answer the question.\n"
"Tools available: {tool_names}"),
("human", "{input}"),
MessagesPlaceholder(variable_name="agent_scratchpad"),
])
print("prompt is "+str(prompt))
agent = create_react_agent(llm=llm, tools=tools, prompt=prompt)
agent_executor = AgentExecutor(
agent=agent,
tools=tools,
memory=memory,
verbose=True,
handle_parsing_errors=True,
return_intermediate_steps=True,
agent_scratchpad_key="agent_scratchpad", # ? match placeholder
input_key="input", # ? match prompt
)
=== 8. Main Loop ===
print("\n?? You can now ask questions about the logs (type 'exit' to quit).")
while True:
query = input("\n?? Ask: ").strip()
if query.lower() == "exit":
break
if isinstance(agent_scratchpad, list):
print("agent_scratchpad is a list")
#result = agent_executor.invoke({"input": query})
try:
result = agent_executor.invoke({"input": query})
except Exception as e:
print(f"? Exception: {e}")
traceback.print_exc()
result = None
print("\n? Answer:\n", result["answer"])
root@cenubu81:/env_test/my_codes/document_analyzer#
`
When I run it, i got:
(env) root@cenubu81:/env_test/my_codes/document_analyzer# python3 agent2.py /env_test/my_codes/document_analyzer/agent2.py:26: LangChainDeprecationWarning: The class
HuggingFaceEmbeddingswas deprecated in LangChain 0.2.2 and will be removed in 1.0. An updated version of the class exists in the :class:
~langchain-huggingface package and should be used instead. To use it runpip install -U :class:
~langchain-huggingfaceand import as
from :class:`~langchain_huggingface import HuggingFaceEmbeddings``.embedding_model = HuggingFaceEmbeddings(model_name="all-MiniLM-L6-v2")
/env_test/my_codes/document_analyzer/agent2.py:31: LangChainDeprecationWarning: Please see the migration guide at: https://python.langchain.com/docs/versions/migrating_memory/
memory = ConversationBufferMemory(
prompt is input_variables=['agent_scratchpad', 'input', 'tool_names', 'tools'] input_types={'agent_scratchpad': list[typing.Annotated[typing.Union[typing.Annotated[langchain_core.messages.ai.AIMessage, Tag(tag='ai')], typing.Annotated[langchain_core.messages.human.HumanMessage, Tag(tag='human')], typing.Annotated[langchain_core.messages.chat.ChatMessage, Tag(tag='chat')], typing.Annotated[langchain_core.messages.system.SystemMessage, Tag(tag='system')], typing.Annotated[langchain_core.messages.function.FunctionMessage, Tag(tag='function')], typing.Annotated[langchain_core.messages.tool.ToolMessage, Tag(tag='tool')], typing.Annotated[langchain_core.messages.ai.AIMessageChunk, Tag(tag='AIMessageChunk')], typing.Annotated[langchain_core.messages.human.HumanMessageChunk, Tag(tag='HumanMessageChunk')], typing.Annotated[langchain_core.messages.chat.ChatMessageChunk, Tag(tag='ChatMessageChunk')], typing.Annotated[langchain_core.messages.system.SystemMessageChunk, Tag(tag='SystemMessageChunk')], typing.Annotated[langchain_core.messages.function.FunctionMessageChunk, Tag(tag='FunctionMessageChunk')], typing.Annotated[langchain_core.messages.tool.ToolMessageChunk, Tag(tag='ToolMessageChunk')]], FieldInfo(annotation=NoneType, required=True, discriminator=Discriminator(discriminator=<function _get_type at 0x79b96f3b6b60>, custom_error_type=None, custom_error_message=None, custom_error_context=None))]]} partial_variables={} messages=[SystemMessagePromptTemplate(prompt=PromptTemplate(input_variables=['tool_names', 'tools'], input_types={}, partial_variables={}, template='You are a helpful log analysis assistant.\n\nYou have access to the following tools:\n\n{tools}\n\nUse them if they help answer the question.\nTools available: {tool_names}'), additional_kwargs={}), HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['input'], input_types={}, partial_variables={}, template='{input}'), additional_kwargs={}), MessagesPlaceholder(variable_name='agent_scratchpad')]
?? You can now ask questions about the logs (type 'exit' to quit).
?? Ask: how many logs contain shutdown
agent_scratchpad is a list
Thank you very much!!!
Hans
Beta Was this translation helpful? Give feedback.
All reactions