# LangChain Record
## Custom functions with OpenAI Functions Agent
https://python.langchain.com/docs/modules/agents/how_to/custom-functions-with-openai-functions-agent
OpenAi version problems
<AttributeError: module ‘openai’ has no attribute ‘error’>
Because LangChain didn't update to fix it
(2023/11/24)
https://community.openai.com/t/attributeerror-module-openai-has-no-attribute-error/486676
```
pip install openai==0.28.1
```
## Pydantic + LangChain Tools
Abstract :
1. 先想好你要做什麼樣的功能,把這個功能寫成一個 function ,同時定義好參數
2. 之後透過 pydantic 來建立參數限制與定義 Input Class
3. LangChain 的 BaseTool 建立你要的工具方法與描述,並且引用上述的限制跟變數定義放在 args_schema , 而你已經完成實作的 function 則是包在 _run() 裏面讓 Agent 去執行。
```
from langchain.tools import BaseTool
from pydantic import BaseModel, Field
from typing import Optional
from typing import Type
# Pydantic
class YourClassNameInput(BaseModel):
# variable : type = Field(Qequired ? , description='')
# "variable" : Is your variable name
# "type" : Variable data type , if the data is optional you can use "Optional[type]"
# "Field" : The Field function is used to customize and add metadata to fields of models.
# "None" in the Field() also mean "Not Qequired Variable"
# "..." in the Field() mean "Qequired Variable"
# Examples
city_county : Optional[str] = Field( None , description = """
City name input by user For example, 台中->臺中市、台北->臺北市、雲林->雲林縣、
Note: In Chinese, "台" and "臺" have the same meaning. Therefore, we uniformly use "臺".
If a different input is provided, it will automatically be corrected to the standard county/city name.
採用繁體中文輸入
""" )
```
Pydantic : https://docs.pydantic.dev/2.5/
Fields : https://docs.pydantic.dev/latest/concepts/fields/
```
# LangChain
class YourClassNameInput(BaseTool):
name = 'search_real_estate_by_criteria'
description : ''
args_schema: Type[BaseModel] = YourClassNameInput
def _run(self , variables ):
# here you can excute your function
result = YourFunctionName(var)
return result
# It will return to langchain to generate response
def _arun(self , variables ):
raise NotImplementedError("This tool does not support async")
# We don't use that in this case
```
## Set your Agent
Agent : https://python.langchain.com/docs/modules/agents/
1. Import modules
1. Set tools
1. Create Model (ChatOpenAI)
```
from langchain.agents import AgentType, initialize_agent
from langchain.chat_models import ChatOpenAI
# Note this is my tool name. You should import yourself
from functions.RealEstate_Recommendation import RealEstateRecommendationTool
model = ChatOpenAI(
model="gpt-4-1106-preview" ,
temperature= 0.9,
openai_api_key ="Your API key or you can set in env"
)
tools = [RealEstateRecommendationTool()]
# If you have more than one tools you can set at this List
agent = initialize_agent(tools, model, agent=AgentType.OPENAI_FUNCTIONS, verbose=False)
ans = agent.run("What you want to ask to your chatbot")
print(ans)
```
## Chat Messages
這邊 Agent 無法使用要使用其他方法,但 ChatModel 可以用
https://python.langchain.com/docs/modules/memory/chat_messages/
```
from langchain.memory import ChatMessageHistory
history = ChatMessageHistory()
history.add_user_message("hi!")
history.add_ai_message("whats up?")
```
## Verbose
這邊會顯示 LangChain 執行的步驟(在 CMD 內顯示過程)
https://stackoverflow.com/questions/76405986/in-langchain-how-to-save-the-verbose-output-to-a-variable
## Callback
https://python.langchain.com/docs/modules/callbacks/
## Agent Memoery (chat history)
https://python.langchain.com/docs/modules/agents/how_to/add_memory_openai_functions