趋近智
构建一个简单的文件操作工具,能够让大型语言模型(LLM)代理与环境进行交互。这个练习将展示LLM代理如何读写文本文件,这是许多任务所需的主要功能。我们将重点创建两个Python函数:一个用于读取文件内容,另一个用于写入内容到文件。尽管这些工具很基础,但它们构成了更复杂文件管理操作的组成部分。
我们的目标是创建两个不同的函数:
read_file(filepath: str): 这个函数将接受文件路径作为输入,并以字符串形式返回文件内容。write_file(filepath: str, content: str): 这个函数将接受文件路径和字符串内容作为输入,将内容写入指定文件,并确认操作成功。对于这两个函数,错误处理很重要,因为文件操作可能因多种原因失败(例如,文件未找到、权限问题)。在出现错误时,提供给大型语言模型的反馈应该清晰且提供足够信息。
read_file 工具让我们开始实现 read_file 函数。这个函数需要以读取模式打开文件,获取其内容,并处理文件不存在等潜在错误。
import os
def read_file(filepath: str) -> str:
"""
读取指定文本文件的内容。
参数:
filepath: 要读取文件的路径。
返回:
文件内容(字符串形式),如果发生问题则返回错误信息。
"""
try:
# 基本安全措施:在此简单示例中阻止目录遍历
# 在实际系统中,应使用目录白名单或更严格的路径验证。
if ".." in filepath:
return "Error: Relative paths with '..' are not allowed."
# 为简化起见,我们假设文件位于特定的 'agent_files' 子目录中。
# 在生产环境中,此路径应可配置并有安全防护。
base_directory = "agent_files"
safe_filepath = os.path.join(base_directory, os.path.basename(filepath))
# 如果此示例的基目录不存在,则创建它
if not os.path.exists(base_directory):
os.makedirs(base_directory)
with open(safe_filepath, 'r', encoding='utf-8') as f:
content = f.read()
return content
except FileNotFoundError:
return f"Error: File not found at '{filepath}' (resolved to '{safe_filepath}')."
except Exception as e:
return f"Error reading file '{filepath}': {str(e)}"
在这个函数中:
filepath 中使用 ".." 来阻止简单的目录遍历攻击。生产系统将需要更复杂的路径验证和沙箱机制。base_directory(例如 agent_files),代理被允许从该目录读取文件。这有助于限制文件操作。使用 os.path.basename(filepath) 是为了确保只考虑文件名部分,从而防止代理指定意图目录之外的路径。try-except 块来专门捕获 FileNotFoundError,并提供定制化的消息。except Exception 捕获其他潜在的 I/O 错误,返回包含原始异常的通用错误消息。utf-8 编码打开,这是文本文件的常见标准。当大型语言模型调用此工具时,如果文件 agent_files/example.txt 存在且包含“Hello World”,则调用 read_file("example.txt") 将返回 "Hello World"。如果文件不存在,它将返回 "Error: File not found at 'example.txt' (resolved to 'agent_files/example.txt')."
write_file 工具接下来,我们来实现 write_file 函数。这个工具将允许代理将文本保存到文件中。写入文件比读取文件带来更大的风险,因此在实际应用中,对权限和目标位置的仔细考量更为重要。
import os
def write_file(filepath: str, content: str) -> str:
"""
将给定内容写入指定的文本文件。
如果文件存在,将被覆盖。
参数:
filepath: 要写入文件的路径。
content: 要写入文件的文本内容。
返回:
成功消息,如果发生问题则返回错误信息。
"""
try:
# 基本安全措施:阻止目录遍历
if ".." in filepath:
return "Error: Relative paths with '..' are not allowed for writing."
# 将写入操作限制在特定子目录中
base_directory = "agent_files"
safe_filepath = os.path.join(base_directory, os.path.basename(filepath))
# 如果基目录不存在,则创建它
if not os.path.exists(base_directory):
os.makedirs(base_directory)
with open(safe_filepath, 'w', encoding='utf-8') as f:
f.write(content)
return f"Successfully wrote content to '{filepath}' (resolved to '{safe_filepath}')."
except Exception as e:
return f"Error writing file '{filepath}': {str(e)}"
write_file 的要点:
read_file,它通过使用 os.path.basename 和 base_directory 包含了基本的路径安全性。'w')打开,这意味着如果文件已存在,它将被覆盖。对于一个更高级的工具,你可能需要考虑添加一个 append 模式或一个参数来控制覆盖行为。try-except 块处理写入操作期间可能出现的 IOError 或其他异常。如果一个代理决定使用此工具,其中 filepath="report.txt" 且 content="This is the agent's report.", 该工具将尝试使用给定内容创建或覆盖 agent_files/report.txt。
大型语言模型代理要使用这些Python函数,需要清楚的说明每个工具的功能、预期的参数以及返回的内容。以下是你可能为一个代理框架定义这些信息的方式:
工具 1: 读取文件
read_filefilepath (字符串,必需): "要读取的文件名(例如,'notes.txt')。不要包含 '../' 或 '/' 等目录路径;所有文件都相对于预配置的 'agent_files' 目录。"工具 2: 写入文件
write_filefilepath (字符串,必需): "要写入的文件名(例如,'summary.txt')。不要包含 '../' 或 '/' 等目录路径;所有文件都相对于预配置的 'agent_files' 目录。如果文件存在,它将被覆盖。"content (字符串,必需): "要写入文件的文本内容。"这些说明旨在指导大型语言模型正确使用这些工具,其中包括有关文件系统结构(agent_files 目录)和潜在结果(如覆盖文件)的提示。
要测试这些工具:
直接Python测试: 直接从Python脚本调用这些函数。
agent_files 子目录中创建一个示例文件(例如 agent_files/my_test_file.txt),并包含一些内容。read_file("my_test_file.txt") 并验证输出。read_file 以检查错误处理。write_file("new_test_file.txt", "Hello from the agent!")。检查 agent_files/new_test_file.txt 是否以正确内容创建。write_file(尽管在不修改实际文件权限的情况下,这更难进行单元测试)。代理集成测试: 尽管完整的代理集成将在后面介绍,但你可以设想代理如何使用这些工具。
read_file("project_update.txt"),然后处理内容,最后调用 write_file("summary_v1.txt", "...")。read_file 的错误消息(例如,如果 project_update.txt 不存在)。我们构建的文件工具仅作示例。对于任何应用,特别是当大型语言模型可以确定文件名或内容时,安全是头等大事:
os.path.basename 和 base_directory 的方法只是一个非常基础的第一步。生产系统必须对可读/可写目录以及可能的文件名或文件扩展名使用严格的白名单。绝不允许在未经过净化和验证的情况下,从大型语言模型输出构建任意路径。这些简单的文件操作工具,如果得到适当的安全保护和说明,将显著增强代理与持久存储交互和管理信息的能力。在构建更复杂的代理时,你可能会扩展这些工具以处理目录、列出文件、检查文件是否存在或向文件追加内容,同时始终将安全性放在设计的首位。
这部分内容有帮助吗?
© 2026 ApX Machine Learning用心打造