趋近智
一个实践练习将指导您构建一个具有特定角色和功能的初始LLM代理,过程中将涉及定义代理的特点、专业职能以及集成基本工具的使用。目标是构建一个能够从给定URL获取信息、进行总结并提取主要主题的“网页内容摘要器”代理。
在编写任何代码之前,让我们明确定义我们的代理:
requests和BeautifulSoup4等库)。这个代理虽然简单,但它展示了核心思想,即赋予LLM驱动实体一个特定的工作描述以及完成任务的途径。
请确保您已安装以下Python库:
pip install openai requests beautifulsoup4
您还需要一个OpenAI API密钥。将其设置为环境变量是良好的实践:
export OPENAI_API_KEY='your_api_key_here'
请记住,本次实践练习假设您的开发环境已按照第1章中的说明进行配置。
让我们一步步构建WebSummarizerAgent。
首先,我们将导入必要的模块并设置我们的OpenAI客户端。
import os
import requests
from bs4 import BeautifulSoup
from openai import OpenAI
# 初始化OpenAI客户端
# 它将自动获取OPENAI_API_KEY环境变量
try:
client = OpenAI()
except Exception as e:
print(f"Error initializing OpenAI client: {e}")
print("Please ensure your OPENAI_API_KEY environment variable is set correctly.")
exit()
# LLM的配置
LLM_MODEL = "gpt-3.5-turbo"
对于这项任务,使用gpt-3.5-turbo能在能力和成本之间提供良好的平衡。您可以根据需要替换其他模型。
我们的代理需要从URL检索内容。我们将为此创建一个函数。
def fetch_web_content(url: str) -> str:
"""
从给定URL获取并提取文本内容。
返回文本内容或错误消息。
"""
try:
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
}
response = requests.get(url, headers=headers, timeout=10)
response.raise_for_status() # 对于不良响应(4XX或5XX)引发HTTPError
soup = BeautifulSoup(response.content, 'html.parser')
# 从常见的文本标签中提取文本,尝试获取主要内容
paragraphs = soup.find_all(['p', 'article', 'main'])
if not paragraphs: # 针对简单页面的备用方案
paragraphs = soup.find_all('body')
text_content = ""
for p_tag in paragraphs:
text_content += p_tag.get_text(separator=' ', strip=True) + "\n"
# 基本清理:减少多余的换行和空格
text_content = '\n'.join([line.strip() for line in text_content.splitlines() if line.strip()])
text_content = ' '.join(text_content.split())
# 限制内容长度以避免过多的token使用
# 这是一个简单的截断;对于非常长的文章,可能需要更复杂的块处理方法
max_length = 15000 # 大约4k token,具体取决于文本
return text_content[:max_length]
except requests.exceptions.RequestException as e:
return f"Error fetching URL {url}: {e}"
except Exception as e:
return f"Error processing content from {url}: {e}"
这个fetch_web_content函数尝试获取网页的主要文本部分。网页抓取可能复杂得多,通常需要针对特定网站的解析器,但这提供了一种通用方法。内容被截断以防止LLM输入过长。
现在,我们将定义代理的主要处理函数。这个函数将协调内容获取,然后使用LLM进行摘要和主题提取。
def process_url_with_agent(url: str) -> dict:
"""
协调网页内容获取、摘要和主题提取。
"""
print(f"Processing URL: {url}...")
content = fetch_web_content(url)
if content.startswith("Error"):
return {"error": content}
if not content.strip():
return {"error": "No text content found at the URL."}
# LLM的角色设定和指令
system_prompt = (
"You are a diligent Research Assistant. "
"Your purpose is to process the provided web article text, "
"generate a concise summary, and identify 3-5 main topics. "
"Format your response as a JSON object with two keys: 'summary' and 'main_topics' (a list of strings)."
)
user_prompt = f"Please process the following web article content:\n\n{content}"
try:
response = client.chat.completions.create(
model=LLM_MODEL,
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_prompt}
],
temperature=0.3, # 降低温度以获得更真实、更少创造性的输出
response_format={"type": "json_object"} # 请求JSON输出
)
# 响应内容应为JSON字符串。
# 我们将直接解析它。
assistant_reply = response.choices[0].message.content
# 如果需要在解析前进行基本验证,或者依赖OpenAI的JSON模式
import json
result = json.loads(assistant_reply)
return result
except Exception as e:
return {"error": f"LLM processing error: {e}"}
在process_url_with_agent中,我们首先获取内容。然后,我们构建一个系统提示,明确定义代理的特点和任务,并重要地指示它返回一个JSON对象。这种结构化输出更容易在更大的系统中解析和使用。用户提示提供了实际内容。我们使用OpenAI的JSON模式以获得可靠的结构化输出。
一个简单的图表说明了我们代理的流程:
该代理接收一个URL,获取其内容,使用LLM处理,并生成摘要和主题列表。
让我们用一个示例URL测试我们的代理。
if __name__ == "__main__":
# 示例用法:
# 替换为您选择的URL,最好是文章链接。
# 请注意网站关于抓取的服务条款。
test_url = "https://www.nature.com/articles/d41586-023-03913-3" # 示例:一篇《自然》杂志新闻文章
print(f"Constructing agent to process: {test_url}")
agent_output = process_url_with_agent(test_url)
if "error" in agent_output:
print(f"\nAgent Error: {agent_output['error']}")
else:
print("\nAgent Output:")
print(f" Summary: {agent_output.get('summary', 'Not available')}")
topics = agent_output.get('main_topics', [])
if topics:
print(" Main Topics:")
for i, topic in enumerate(topics):
print(f" {i+1}. {topic}")
else:
print(" Main Topics: Not available")
当您运行此脚本时,将test_url替换为当前的`新闻文章或博客帖子。代理将获取内容,将其发送给LLM,并附带指定的特点和指令,然后打印生成的摘要和主题。
示例输出(将根据URL和LLM的响应而有所不同):
正在处理URL: https://www.nature.com/articles/d41586-023-03913-3...
代理输出:
摘要:文章讨论了探测超大质量黑洞合并产生的引力波所面临的挑战和取得的进展。尽管单独探测这些波很困难,但像NANOGrav这样的项目正在利用脉冲星计时阵列来寻找这些波的背景嗡嗡声。最近的发现表明一个与该背景一致的信号,尽管需要更多数据来证实。探测这些波将为了解星系演化和宇宙中巨大结构的形成提供见解。
主要主题:
1. 引力波探测
2. 超大质量黑洞合并
3. 脉冲星计时阵列(例如,NANOGrav)
4. 星系演化
5. 宇宙背景辐射
本次实践练习展示了如何构建一个简单的LLM代理,它具有明确的角色、功能和一个基本工具(网页获取)。我们看到系统提示如何确立代理的特点并引导其输出格式。
与章节内容的关联:
fetch_web_content函数是一个简单的集成工具。更复杂的代理可能会使用正式的工具注册和调用机制,如“为代理集成外部工具和函数”中所讨论的。可能的改进:
这个初步的代理可作为构建模块。随着您的进步,您将学会组合多个此类专业代理,协调它们之间的交互,并管理复杂的工作流程以解决更具挑战性的问题。本次练习应能让您具体理解单个代理架构如何提升大型多代理系统的能力。
这部分内容有帮助吗?
© 2026 ApX Machine Learning用心打造