python3 -m venv .venv
source .venv/bin/activatepip install langchain_community
pip install langchain_core
pip install langchain#!/usr/bin/env python3
from typing import List, Tuple
from langchain.chains import ConversationChain
#https://python.langchain.com/docs/integrations/toolkits/sql_database
from langchain_community.agent_toolkits import create_sql_agent
from langchain_community.agent_toolkits import SQLDatabaseToolkit
from langchain.agents.agent_types import AgentType
from langchain.sql_database import SQLDatabase
# LangChain supports many other chat models. Here, we're using Ollama
from langchain_community.chat_models import ChatOllama
ollama_llm = ChatOllama(model="gemma:7b")
# sqlite> PRAGMA table_info(notes);
# 0|created_on|DATETIME|1||0
# 1|changed_on|DATETIME|1||0
# 2|id|INTEGER|1||1
# 3|title|VARCHAR(256)|0||0
# 4|content|TEXT|0||0
# 5|created_by_fk|INTEGER|1||0
# 6|changed_by_fk|INTEGER|1||0
# sqlite>
db = SQLDatabase.from_uri("sqlite:///app.db")
#toolkit = SQLDatabaseToolkit(db=db)
agent_executor = create_sql_agent(
llm=ollama_llm,
db=db,
verbose=True,
agent_type=AgentType.ZERO_SHOT_REACT_DESCRIPTION
)
# agent_executor.invoke("请列出notes表里从标题来分类,你觉得有可能是菜谱的记录")
agent_executor.invoke("""取出notes表100个记录的title字段""")嗯,100%都是会报错的
需要一点一点的去排查错误,就很烦的,就给你说现在的LLM工具简直就是处于不可用状态居多
都需要针对模型去调教
import re
from typing import Union
from langchain_core.agents import AgentAction, AgentFinish
from langchain_core.exceptions import OutputParserException
from langchain.agents.agent import AgentOutputParser
from langchain.agents.mrkl.prompt import FORMAT_INSTRUCTIONS
FINAL_ANSWER_ACTION = "Final Answer:"
FINAL_SUMMARY = "## Summary"
MISSING_ACTION_AFTER_THOUGHT_ERROR_MESSAGE = (
"Invalid Format: Missing 'Action:' after 'Thought:"
)
MISSING_ACTION_INPUT_AFTER_ACTION_ERROR_MESSAGE = (
"Invalid Format: Missing 'Action Input:' after 'Action:'"
)
FINAL_ANSWER_AND_PARSABLE_ACTION_ERROR_MESSAGE = (
"Parsing LLM output produced both a final answer and a parse-able action:"
)
class ReActSingleInputOutputParser(AgentOutputParser):
"""Parses ReAct-style LLM calls that have a single tool input.
Expects output to be in one of two formats.
If the output signals that an action should be taken,
should be in the below format. This will result in an AgentAction
being returned.
```
Thought: agent thought here
Action: search
Action Input: what is the temperature in SF?
```
If the output signals that a final answer should be given,
should be in the below format. This will result in an AgentFinish
being returned.
```
Thought: agent thought here
Final Answer: The temperature is 100 degrees
```
"""
def get_format_instructions(self) -> str:
return FORMAT_INSTRUCTIONS
def parse(self, text: str) -> Union[AgentAction, AgentFinish]:
includes_answer = FINAL_ANSWER_ACTION in text
includes_summary =FINAL_SUMMARY in text
regex = (
r"\*\*Action\s*\d*\s*:\*\*[\s]*(.*?)[\s]*\*\*Action\s*\d*\s*Input\s*\d*\s*:\*\*\s*(.*?)\*\*Observation"
)
action_match = re.search(regex, text, re.DOTALL)
if action_match:
if False:
raise OutputParserException(
f"{FINAL_ANSWER_AND_PARSABLE_ACTION_ERROR_MESSAGE}: {text}"
)
action = action_match.group(1).strip()
action_input = action_match.group(2)
action_input = action_input.strip("\n")
tool_input = action_input.strip(" ")
tool_input = tool_input.strip('"')
return AgentAction(action, tool_input, text)
elif includes_summary:
return AgentFinish(
{"output": text.split(FINAL_ANSWER_ACTION)[-1].strip()}, text
)
print("\n================啥?76行到底发生了啥事情?==================")
print(text)
rrr1 = re.search(r"\*\*Action\s*\d*\s*:\*\*[\s]*(.*?)", text, re.DOTALL)
print("================rrr1==================")
print(rrr1)
print("================END OF 啥?76行到底发生了啥事情?==================")
if not re.search(r"\*\*Action\s*\d*\s*:\*\*[\s]*(.*?)", text, re.DOTALL):
raise OutputParserException(
f"Could not parse LLM output: `{text}`",
observation=MISSING_ACTION_AFTER_THOUGHT_ERROR_MESSAGE,
llm_output=text,
send_to_llm=True,
)
elif not re.search(
r"\*\*Action\s*\d*\s*Input\s*\d*\s*:\*\*\s*(.*?)", text, re.DOTALL
):
raise OutputParserException(
f"Could not parse LLM output: `{text}`",
observation=MISSING_ACTION_INPUT_AFTER_ACTION_ERROR_MESSAGE,
llm_output=text,
send_to_llm=True,
)
else:
raise OutputParserException(f"Could not parse LLM output: `{text}`")
@property
def _type(self) -> str:
return "react-single-input"
这是转为gemma准备好的outputParser.py
哎,真烦人