1
resposta

Erros na resposta.

Estou testando com uma base própria de uma eleição, quando faço a pergunta a resposta vem correta no "tool_output" porem a "response" vem sempre errada, algumas vezes diz até que não encontrou os dados.

system = f"""Você tem acesso a um dataframe pandas `df`. \
Aqui está a saida de `df.head().to_markdown()`:

{df.head().to_markdown()}

Dada uma pergunta do usuário, escreva o código Python para respondê-la. \
Não presuma que você tem acesso a nenhuma biblioteca além das bibliotecas Python integradas e pandas. \
Responda em português à pergunta quando tiver infomações suficientes para respondê-la."""

prompt = ChatPromptTemplate.from_messages([("system", system), 
                                           ("human", "{question}"),
                                            MessagesPlaceholder("chat_history", optional=True)])

def get_chat_history(x: dict) -> list:
    """Analise a saída da cadeia até este ponto em uma lista de mensagens do histórico de bate-papo 
    para inserir no prompt"""
    ai_msg = x["ai_msg"]
    tool_call_id = x ["ai_msg"].additional_kwargs["tool_calls"][0]["id"]
    print(f"Tool call ID: {tool_call_id}")
    tool_msg = ToolMessage(content=str(x["tool_output"]), tool_call_id=tool_call_id )
    return [ai_msg, tool_msg]

cadeia = (
    RunnablePassthrough.assign(ai_msg=prompt | llm_com_ferramenta)
    .assign(tool_output=itemgetter("ai_msg") | parser | ferramenta_python)
    .assign(chat_history=get_chat_history)
    .assign(response=prompt | llm | StrOutputParser())
    .pick(["tool_output", "response"])
)
1 resposta

Olá, Filipe!

Obrigado por sua pergunta e por compartilhar o seu código. O problema que você está enfrentando é um excelente exemplo de como a lógica da cadeia de execução no LangChain pode influenciar o resultado final.

A sua análise está correta: o tool_output está vindo com a resposta correta, mas a response está vindo errada. O motivo para isso é a forma como a sua cadeia está construída.

No trecho response=prompt | llm | StrOutputParser(), você está usando o prompt original para gerar a resposta final. O prompt original, no momento da criação da response, não tem acesso ao resultado da ferramenta (tool_output).

Para resolver isso, você precisa garantir que a response seja gerada após a execução da ferramenta, e que ela tenha acesso ao histórico de conversas que inclui o resultado da ferramenta.

A sua função get_chat_history já está fazendo a parte mais importante, que é construir esse histórico. O que falta é usar esse histórico para gerar a response.

Uma forma de corrigir a sua cadeia seria:

cadeia = (
    RunnablePassthrough.assign(ai_msg=prompt | llm_com_ferramenta)
    .assign(tool_output=itemgetter("ai_msg") | parser | ferramenta_python)
    .assign(chat_history=get_chat_history)
    .assign(response=prompt_com_historico | llm | StrOutputParser()) # Aqui você usaria um novo prompt
    .pick(["tool_output", "response"])
)

E você precisaria de um prompt_com_historico que inclua o histórico de conversas.

Uma abordagem mais simples, e que eu recomendo, é usar a própria função invoke do agente, que já cuida dessa lógica de forma transparente. O agente vai decidir se precisa usar uma ferramenta, e depois vai gerar a resposta final com base no resultado.

Se o seu objetivo é que a response contenha a resposta final em português com base no tool_output, o agente (llm_com_ferramenta) já deveria fazer isso por você.

Espero que essa explicação te ajude a reestruturar a sua cadeia para obter o resultado desejado!