feat: 项目完成

This commit is contained in:
liangfangxing
2026-03-20 22:56:24 +08:00
parent 0b087df55e
commit c2a515ec2c
33 changed files with 1234 additions and 2 deletions

View File

@@ -0,0 +1,69 @@
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage, ToolMessage
from langchain_core.tools import tool
from conf import settings
# todo: 第一步:定义工具函数
@tool
def add(a: int, b: int) -> int:
"""
将数字a与数字b相加
Args:
a: 第一个数字
b: 第二个数字
"""
return a + b
@tool
def multiply(a: int, b: int) -> int:
"""
将数字a与数字b相乘
Args:
a: 第一个数字
b: 第二个数字
"""
return a * b
# 定义 JSON 格式的工具 schema
tools = [add, multiply]
# todo: 第二步:初始化模型
llm = ChatOpenAI(
base_url=settings.base_url,
api_key=settings.api_key,
model=settings.model_name,
temperature=0.1
)
# 绑定工具,允许模型自动选择工具
llm_with_tools = llm.bind_tools(tools, tool_choice="auto")
# todo: 第三步:调用回复
query = "2+1等于多少"
messages = [HumanMessage(query)]
try:
# todo: 第一次调用
ai_msg = llm_with_tools.invoke(messages)
messages.append(ai_msg)
print(f"\n第一轮调用后结果:\n{messages}")
# 处理工具调用
# 判断消息中是否有tool_calls以判断工具是否被调用
if hasattr(ai_msg, 'tool_calls') and ai_msg.tool_calls:
for tool_call in ai_msg.tool_calls:
# todo: 处理工具调用
selected_tool = {"add": add, "multiply": multiply}[tool_call["name"].lower()]
tool_output = selected_tool.invoke(tool_call["args"]) # 需要使用invoke进行调用
messages.append(ToolMessage(content=tool_output, tool_call_id=tool_call["id"]))
print(f"\n第二轮 message中增加tool_output 之后:\n{messages}")
# todo: 第二次调用,将工具结果传回模型以生成最终回答
final_response = llm_with_tools.invoke(messages)
print(f"\n最终模型响应:\n{final_response.content}")
else:
print("模型未生成工具调用,直接返回文本:")
print(ai_msg.content)
except Exception as e:
print(f"模型调用失败: {str(e)}")

View File

@@ -0,0 +1,83 @@
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage, ToolMessage
"""
Pydantic 是一个 Python 库,用于数据验证和序列化。
它通过使用 Python 类型注解type hints来定义数据模型
并提供强大的数据验证功能。Pydantic 基于 Python 的 dataclasses 和 typing 模块,
允许开发者定义结构化的数据模型,并自动验证输入数据是否符合指定的类型和约束。
"""
from pydantic.v1 import BaseModel, Field
from conf import settings
# todo: 第一步:定义工具函数
class Add(BaseModel):
"""
将两个数字相加
"""
a: int = Field(..., description="第一个数字")
b: int = Field(..., description="第二个数字")
def invoke(self, args):
# 验证参数
tool_instance = self.__class__(**args) # 自动验证 a 和 b
return tool_instance.a + tool_instance.b
class Multiply(BaseModel):
"""
将两个数字相乘
"""
a: int = Field(..., description="第一个数字")
b: int = Field(..., description="第二个数字")
def invoke(self, args):
# 验证参数
tool_instance = self.__class__(**args) # 自动验证 a 和 b
return tool_instance.a * tool_instance.b
# 定义 JSON 格式的工具 schema
tools = [Add, Multiply]
# todo: 第二步:初始化模型
llm = ChatOpenAI(
base_url=settings.base_url,
api_key=settings.api_key,
model=settings.model_name,
temperature=0.1
)
# 绑定工具,允许模型自动选择工具
llm_with_tools = llm.bind_tools(tools, tool_choice="auto")
# todo: 第三步:调用回复
query = "2+1等于多少"
messages = [HumanMessage(query)]
try:
# todo: 第一次调用
ai_msg = llm_with_tools.invoke(messages)
messages.append(ai_msg)
print(f"\n第一轮调用后结果:\n{messages}")
# 处理工具调用
# 判断消息中是否有tool_calls以判断工具是否被调用
if hasattr(ai_msg, 'tool_calls') and ai_msg.tool_calls:
for tool_call in ai_msg.tool_calls:
# todo: 处理工具调用
selected_tool = {"add": Add, "multiply": Multiply}[tool_call["name"].lower()]
# 实例化工具类并调用 invoke
tool_instance = selected_tool(**tool_call["args"])
tool_output = tool_instance.invoke(tool_call["args"])
messages.append(ToolMessage(content=tool_output, tool_call_id=tool_call["id"]))
print(f"\n第二轮 message中增加tool_output 之后:\n{messages}")
# todo: 第二次调用,将工具结果传回模型以生成最终回答
final_response = llm_with_tools.invoke(messages)
print(f"\n最终模型响应:\n{final_response.content}")
else:
print("模型未生成工具调用,直接返回文本:")
print(ai_msg.content)
except Exception as e:
print(f"模型调用失败: {str(e)}")

View File

@@ -0,0 +1,51 @@
from langchain.agents import initialize_agent, AgentType
from langchain_openai import ChatOpenAI
from langchain_core.tools import tool
from conf import settings
# todo: 第一步:定义工具函数
@tool
def add(a: int, b: int) -> int:
"""
将数字a与数字b相加
Args:
a: 第一个数字
b: 第二个数字
"""
return a + b
@tool
def multiply(a: int, b: int) -> int:
"""
将数字a与数字b相乘
Args:
a: 第一个数字
b: 第二个数字
"""
return a * b
# 加载工具
tools = [add, multiply]
# todo: 第二步:初始化模型
llm = ChatOpenAI(
base_url=settings.base_url,
api_key=settings.api_key,
model=settings.model_name,
temperature=0.1
)
# todo: 第三步创建Agent
agent = initialize_agent(
tools,
llm,
AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION,
verbose=True
)
# todo: 第四步调用Agent
query = "2+1等于多少"
result = agent.invoke(query)
print(f'result: {result["output"]}')

View File

@@ -0,0 +1,115 @@
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage, ToolMessage
from conf import settings
# todo: 第一步:定义工具函数
def add(a: int, b: int) -> int:
"""
将数字a与数字b相加
Args:
a: 第一个数字
b: 第二个数字
"""
return a + b
def multiply(a: int, b: int) -> int:
"""
将数字a与数字b相乘
Args:
a: 第一个数字
b: 第二个数字
"""
return a * b
tools = [
{
"type": "function",
"function": {
"name": "add",
"description": "将数字a与数字b相加",
"parameters": {
"type": "object",
"properties": {
"a": {
"type": "integer",
"description": "第一个数字"
},
"b": {
"type": "integer",
"description": "第二个数字"
}
},
"required": ["a", "b"]
}
}
},
{
"type": "function",
"function": {
"name": "multiply",
"description": "将数字a与数字b相乘",
"parameters": {
"type": "object",
"properties": {
"a": {
"type": "integer",
"description": "第一个数字"
},
"b": {
"type": "integer",
"description": "第二个数字"
}
},
"required": ["a", "b"]
}
}
}
]
# todo: 第二步:初始化模型
llm = ChatOpenAI(
base_url=settings.base_url,
api_key=settings.api_key,
model=settings.model_name,
temperature=0.1
)
llm_with_tools = llm.bind(tools=tools, tool_choice="auto")
# todo: 第三步:调用回复
query = "2*10+1"
messages = [HumanMessage(query)]
try:
# todo: 第一次调用
ai_msg = llm_with_tools.invoke(messages)
messages.append(ai_msg)
print(f"\n第一轮调用后结果:\n{messages}")
# 处理工具调用
# 判断消息中是否有tool_calls以判断工具是否被调用
if hasattr(ai_msg, "tool_calls") and ai_msg.tool_calls:
for tool_call in ai_msg.tool_calls:
# todo: 处理工具调用
selected_tool = {"add": add, "multiply": multiply}[tool_call["name"].lower()]
tool_output = selected_tool(**tool_call["args"])
messages.append(ToolMessage(content=tool_output, tool_call_id=tool_call["id"]))
print(f"\n第二轮 message中增加tool_output 之后:\n{messages}")
# todo: 第二次调用,将工具结果传回模型以生成最终回答
final_response = llm_with_tools.invoke(messages)
print(f"\n最终模型响应:\n{final_response.content}")
else:
print("模型未生成工具调用,直接返回文本:")
print(ai_msg.content)
except Exception as e:
print(f"模型调用失败: {str(e)}")
# llm.invoke(messages, tools=tools, ...):
# 绑定方式: 直接在 .invoke() 调用中传入 tools 参数。这是一种临时、一次性的绑定方式,仅对本次调用有效。
# 调用方式: 如果你想再次调用模型并使用工具,你必须在下一次 .invoke() 调用中再次传递 tools 参数。
# 适用场景: 适用于简单、单次的工具调用需求,