1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
| from typing import get_type_hints
import inspect
class ToolRegistry:
"""工具注册表"""
def __init__(self):
self.tools: Dict[str, Tool] = {}
def register(self, tool: Tool):
"""注册工具"""
self.tools[tool.name] = tool
def get_tool_schema(self) -> List[dict]:
"""获取工具Schema(用于OpenAI Function Calling)"""
schemas = []
for tool in self.tools.values():
schema = {
"type": "function",
"function": {
"name": tool.name,
"description": tool.description,
"parameters": self._extract_parameters(tool)
}
}
schemas.append(schema)
return schemas
def _extract_parameters(self, tool: Tool) -> dict:
"""从工具中提取参数Schema"""
# 获取execute方法的签名
sig = inspect.signature(tool.execute)
parameters = {}
required = []
properties = {}
for name, param in sig.parameters.items():
if name == 'self':
continue
param_type = param.annotation
# 类型映射
type_map = {
str: "string",
int: "integer",
float: "number",
bool: "boolean",
list: "array",
dict: "object"
}
json_type = type_map.get(param_type, "string")
property_def = {"type": json_type}
if param.default == inspect.Parameter.empty:
required.append(name)
properties[name] = property_def
return {
"type": "object",
"properties": properties,
"required": required
}
class FunctionCallingAgent(BaseAgent):
"""函数调用Agent"""
def __init__(self, config: AgentConfig, registry: ToolRegistry):
super().__init__(config)
self.registry = registry
async def think(self, input: str) -> str:
"""使用函数调用思考"""
messages = [
Message(role="system", content=self.config.system_prompt),
Message(role="user", content=input)
]
while True:
# 调用LLM(带函数调用)
response = await self._call_llm_with_tools(
messages,
tools=self.registry.get_tool_schema()
)
# 处理响应
if response.get("tool_calls"):
messages.append(Message(
role="assistant",
content="",
tool_calls=response["tool_calls"]
))
# 执行工具调用
for tool_call in response["tool_calls"]:
tool_name = tool_call["function"]["name"]
tool_args = json.loads(tool_call["function"]["arguments"])
if tool_name in self.registry.tools:
result = await self.registry.tools[tool_name].execute(**tool_args)
messages.append(Message(
role="tool",
content=str(result),
tool_call_id=tool_call["id"]
))
else:
# 最终响应
return response.get("content", "")
async def _call_llm_with_tools(self, messages: List[Message], tools: List[dict]) -> dict:
"""调用LLM(带工具)"""
# 集成实际的LLM API
pass
|