Преглед изворни кода

Merge pull request #102 from fengju0213/st_11.2

Update 第七章 构建你的Agent框架.md
Tao Sun пре 7 месеци
родитељ
комит
d893744c9f
1 измењених фајлова са 117 додато и 0 уклоњено
  1. 117 0
      docs/chapter7/第七章 构建你的Agent框架.md

+ 117 - 0
docs/chapter7/第七章 构建你的Agent框架.md

@@ -1276,6 +1276,72 @@ print(f"数学专用Agent结果: {math_result}")
   <img src="https://raw.githubusercontent.com/datawhalechina/Hello-Agents/main/docs/images/7-figures/table-02.png" alt="" width="90%"/>
 </div>
 
+### 7.4.5 FunctionCallAgent
+
+FunctionCallAgent是hello-agents在0.2.8之后引入的Agent,它基于OpenAI原生函数调用机制的Agent,展示了如何使用OpenAI的函数调用机制来构建Agent。
+它支持以下功能:
+_build_tool_schemas:通过工具的description构建OpenAI的function calling schema
+_extract_message_content:从OpenAI的响应中提取文本
+_parse_function_call_arguments:解析模型返回的JSON字符串参数
+_convert_parameter_types:转换参数类型
+
+这些功能可以使其具备原生的OpenAI Functioncall的能力,对比使用prompt约束的方式,具备更强的鲁棒性。
+```python
+def _invoke_with_tools(self, messages: list[dict[str, Any]], tools: list[dict[str, Any]], tool_choice: Union[str, dict], **kwargs):
+        """调用底层OpenAI客户端执行函数调用"""
+        client = getattr(self.llm, "_client", None)
+        if client is None:
+            raise RuntimeError("HelloAgentsLLM 未正确初始化客户端,无法执行函数调用。")
+
+        client_kwargs = dict(kwargs)
+        client_kwargs.setdefault("temperature", self.llm.temperature)
+        if self.llm.max_tokens is not None:
+            client_kwargs.setdefault("max_tokens", self.llm.max_tokens)
+
+        return client.chat.completions.create(
+            model=self.llm.model,
+            messages=messages,
+            tools=tools,
+            tool_choice=tool_choice,
+            **client_kwargs,
+        )
+
+#内部逻辑是对Openai 原生的functioncall作再封装
+#OpenAI 原生functioncall示例
+from openai import OpenAI
+client = OpenAI()
+
+tools = [
+  {
+    "type": "function",
+    "function": {
+      "name": "get_current_weather",
+      "description": "Get the current weather in a given location",
+      "parameters": {
+        "type": "object",
+        "properties": {
+          "location": {
+            "type": "string",
+            "description": "The city and state, e.g. San Francisco, CA",
+          },
+          "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]},
+        },
+        "required": ["location"],
+      },
+    }
+  }
+]
+messages = [{"role": "user", "content": "What's the weather like in Boston today?"}]
+completion = client.chat.completions.create(
+  model="gpt-5",
+  messages=messages,
+  tools=tools,
+  tool_choice="auto"
+)
+
+print(completion)
+```
+
 ## 7.5 工具系统
 
 本节内容将在前面构建的Agent基础架构上,深入探讨工具系统的设计与实现。我们将从基础设施建设开始,逐步深入到自定义开发设计。本节的学习目标围绕以下三个核心方面展开:
@@ -1392,6 +1458,57 @@ def get_tools_description(self) -> str:
 ````
 这个方法生成的描述字符串可以直接用于构建Agent的提示词,让Agent了解可用的工具。
 
+````python
+def to_openai_schema(self) -> Dict[str, Any]:
+        """转换为 OpenAI function calling schema 格式
+
+        用于 FunctionCallAgent,使工具能够被 OpenAI 原生 function calling 使用
+
+        Returns:
+            符合 OpenAI function calling 标准的 schema
+        """
+        parameters = self.get_parameters()
+
+        # 构建 properties
+        properties = {}
+        required = []
+
+        for param in parameters:
+            # 基础属性定义
+            prop = {
+                "type": param.type,
+                "description": param.description
+            }
+
+            # 如果有默认值,添加到描述中(OpenAI schema 不支持 default 字段)
+            if param.default is not None:
+                prop["description"] = f"{param.description} (默认: {param.default})"
+
+            # 如果是数组类型,添加 items 定义
+            if param.type == "array":
+                prop["items"] = {"type": "string"}  # 默认字符串数组
+
+            properties[param.name] = prop
+
+            # 收集必需参数
+            if param.required:
+                required.append(param.name)
+
+        return {
+            "type": "function",
+            "function": {
+                "name": self.name,
+                "description": self.description,
+                "parameters": {
+                    "type": "object",
+                    "properties": properties,
+                    "required": required
+                }
+            }
+        }
+````
+这个方法生成的schema可以直接用于原生的OpenAI SDK的工具调用。
+
 ### 7.5.2 自定义工具开发
 
 有了基础设施后,我们来看看如何开发一个完整的自定义工具。数学计算工具是一个很好的例子,因为它简单直观,最直接的方式是使用ToolRegistry的函数注册功能。