AI News HubLIVE
站内改写5 分钟阅读

构建和部署你的第一个自主AI代理的7个步骤

本文详细介绍了从零开始构建和部署一个自主研究AI代理的七个步骤。使用LangGraph框架和Claude模型,涵盖了从定义任务、选择工具、设置项目到实现核心循环、添加记忆和部署的完整流程。强调了在生产中运行代理的关键要素,如边界定义、错误处理和容器化。

来源KDnuggets作者: Shittu Olumide

本文提供了一个完整的、逐步的指南,帮助你构建和部署你的第一个自主研究代理。该指南基于LangGraph框架和Claude模型,涵盖从概念到生产的全过程。

引言

大多数人的第一个AI代理从未离开过他们的笔记本电脑。它在终端中运行一次,输出一个合理的答案,然后就闲置在那里,因为没有人编写必要的胶水代码来使脚本成为其他人或其他系统可以实际调用的服务。这种“它在运行时有效”与“它已上线,并且有人在使用它”之间的差距,正是大多数代理项目悄然消亡的地方。

数据支持这一点。根据一份涵盖Gartner、McKinsey和IDC数据的2026年统计数据综述,近79%的公司表示他们以某种形式采用了AI代理,但只有大约11%的公司有在生产中运行的项目。这个差距不是一个小问题。它是演示与产品之间的区别,而且几乎从来不是因为模型不够强大,而是因为没有人正确地界定工作范围、没有人处理故障、或者没有人费心将程序容器化并放在一个有URL的地方。

本文针对一个特定项目弥合了这一差距。到本文结束时,你将构建并部署一个研究代理:你给它一个主题,它搜索网络,提取来源,然后返回一份带有链接的简短书面简报。它足够复杂,需要实际的工具使用、记忆和防护措施,但又足够小,你可以在一次坐下来构建整个项目。下面的每个代码块都是完整并带有注释的,并且每个代码块之后都有对其作用和原因的解释。

步骤一:决定你的代理实际需要做什么(以及不该做什么)

在打开编辑器之前,写下三件事:代理唯一的任务是什么、成功的输出是什么样的、以及在没有人工检查之前它永远不允许做什么。

对于我们的研究代理,这看起来像这样:

  • 任务:接受一个主题作为输入,进行网络搜索,阅读结果,并生成一份包含摘要和来源列表的书面简报。
  • 成功的输出:一份连贯、事实有依据、不超过500字的简报,每个声称都可通过来源URL追溯。
  • 硬性边界:它可以自由搜索和阅读,但未经人员批准,它永远不会发布任何内容、发送任何内容或写入其工作区以外的文件。

第三步比听起来更重要。跳过这一步是Gartner预计到2027年底将有超过40%的自主AI项目被取消的重要原因之一,通常是因为没有人及早定义边界,导致项目要么做得太少而无法实用,要么做得太多而无法信任。

步骤二:选择你的模型和框架

你需要做两个决定:哪个模型负责推理,哪个框架管理思考、行动和检查结果的循环。

对于模型,任何具有良好工具使用能力的当前前沿模型都符合要求:Claude、GPT和Gemini都可以。我们在下面的代码中使用Claude,因为它的工具调用在多步骤任务中一直可靠,但更换为其他提供商只需更改一行代码。

对于框架,这是2026年下半年的情况:

  • LangGraph:将代理建模为图中的节点和边,内置检查点,使得崩溃的运行可以恢复而无需重新开始。每月PyPI下载量超过3800万次,Klarna、Uber和LinkedIn等公司在生产中使用它。代价是学习曲线较陡,通常需要一两周才能掌握。
  • CrewAI:将代理建模为具有角色和目标的“团队”,你可以在20行代码内让某物工作。这是验证想法的最快方法,在GitHub上获得了超过44,000颗星,但一旦工作流变得复杂,它提供的控制就较少,团队通常会迁移到LangGraph。
  • AutoGen:曾经是多代理对话模式的默认选择,但现在微软已将其置于维护模式,并转向统一的Microsoft Agent Framework,因此不建议在2026年用于新项目。
  • 供应商SDK:如OpenAI Agents SDK或Anthropic的Claude Agent SDK,如果你完全致力于一个供应商并希望最小的框架开销,值得考虑,但它们会将你锁定在该供应商的模型上。

我们在此构建中使用LangGraph,因为研究代理受益于检查点(超时的搜索不应意味着重新开始),并且因为这是最直接转移到实际生产工作的技能版本。

步骤三:设置项目

创建一个文件夹、一个虚拟环境,并安装所需的依赖。

mkdir research-agent && cd research-agent
python3 -m venv venv
source venv/bin/activate
pip install langgraph langchain-anthropic langchain-community python-dotenv tavily-python beautifulsoup4

虚拟环境使此项目的包与机器上的其他项目隔离,避免了项目间依赖更新的问题。安装的包涵盖了编排(langgraph)、模型连接(langchain-anthropic)、即用型网络搜索工具和页面加载器(langchain-community加上tavily-python和beautifulsoup4)以及安全密钥管理(python-dotenv)。

接下来,在项目根目录创建一个.env文件来存放你的密钥。你需要一个来自Anthropic Console的Anthropic API密钥和一个来自Tavily的搜索API密钥,Tavily提供足够本教程使用的免费层级。

# .env文件,切勿将其提交到版本控制
ANTHROPIC_API_KEY=your-anthropic-key-here
TAVILY_API_KEY=your-tavily-key-here

最后,设置文件夹结构:

research-agent/
├── venv/
├── .env
├── .gitignore
├── agent.py
├── app.py
├── requirements.txt
└── Dockerfile

将agent.py(代理逻辑)与app.py(公开代理的网络服务器)分离,使代码可读,并允许在包装成API之前直接测试代理。将.env和venv/添加到.gitignore中,防止密钥泄露。

步骤四:构建核心代理循环

这是项目的核心:代理读取任务、决定是否需要工具、调用工具、读取结果、并决定下一步做什么的循环。打开agent.py并逐步构建。

# agent.py
from dotenv import load_dotenv
from langchain_anthropic import ChatAnthropic
from langchain_community.tools.tavily_search import TavilySearchResults
from langgraph.prebuilt import create_react_agent

load_dotenv()

model = ChatAnthropic(model="claude-sonnet-4-6", temperature=0.2, max_tokens=1500)
search_tool = TavilySearchResults(max_results=5)
agent = create_react_agent(model, tools=[search_tool])

def run_research(topic: str) -> str:
    result = agent.invoke({
        "messages": [
            ("system", "You are a research assistant. When given a topic, search for current, credible information and write a brief under 500 words. Every factual claim must be followed by the source URL in parentheses. If sources disagree, say so."),
            ("user", topic),
        ]
    })
    return result["messages"][-1].content

if __name__ == "__main__":
    topic = input("What should I research? ")
    print(run_research(topic))

逐行说明:load_dotenv()从.env文件读取密钥;ChatAnthropic建立与模型的连接;低温度设置使得答案更注重准确性而非创造性;TavilySearchResults为代理提供访问实时互联网的能力;create_react_agent是LangGraph构建经典推理循环(ReAct,推理和行动)的快捷方式;system消息强制代理引用来源并指出分歧。

从终端中运行python agent.py,输入一个主题,你应该会收到一份带有链接的简短简报。如果挂起或出错,检查.env文件中的密钥是否正确以及是否处于激活的虚拟环境中。

步骤五:赋予记忆和第二个工具

目前,代理完成后会忘记一切。这对于单个问题没问题,但当用户询问后续问题(如“现在比较一下X”)时就不行了。我们将通过添加对话记忆来解决这个问题,并且添加第二个工具,以便当搜索摘要不够详细时,代理可以提取整个页面的内容。

# agent.py (updated)
from dotenv import load_dotenv
from langchain_anthropic import ChatAnthropic
from langchain_community.tools.tavily_search import TavilySearchResults
from langchain_community.document_loaders import WebBaseLoader
from langchain_core.tools import tool
from langgraph.prebuilt import create_react_agent
from langgraph.checkpoint.memory import MemorySaver

load_dotenv()

model = ChatAnthropic(model="claude-sonnet-4-6", temperature=0.2, max_tokens=1500)
search_tool = TavilySearchResults(max_results=5)

@tool
def read_page(url: str) -> str:
    """Fetches the readable text of a single web page."""
    try:
        loader = WebBaseLoader(url)
        docs = loader.load()
        return docs[0].page_content[:3000]
    except Exception as e:
        return f"Could not load that page: {e}"

SYSTEM_PROMPT = (
    "You are a research assistant with memory. Use the search and read_page tools "
    "to gather information. Keep track of the conversation history. Always cite sources."
)

memory = MemorySaver()
agent = create_react_agent(model, tools=[search_tool, read_page], checkpointer=memory)

config = {"configurable": {"thread_id": "research thread"}}

def run_research(topic: str) -> str:
    result = agent.invoke({"messages": [("user", topic)]}, config=config)
    return result["messages"][-1].content

if __name__ == "__main__":
    topic = input("What should I research? ")
    print(run_research(topic))

这里的关键变化:使用@tool装饰器定义了read_page函数;MemorySaver添加了检查点功能,使得对话历史得以保存;系统提示现在作为常量定义,检查点机制会自动处理消息历史;config中的thread_id标识会话,使得后续调用可以关联到同一个对话。

步骤六:使用FastAPI将代理暴露为API

现在,代理在终端中工作得很好,但我们需要通过Web API使其可调用。我们将使用FastAPI来创建端点,并异步处理请求以避免长时间运行任务阻塞服务器。

# app.py
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from agent import run_research

app = FastAPI()

class ResearchRequest(BaseModel):
    topic: str

@app.post("/research")
async def research(request: ResearchRequest):
    if not request.topic:
        raise HTTPException(status_code=400, detail="Topic cannot be empty")
    result = run_research(request.topic)
    return {"result": result}

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)

步骤七:通过Docker容器化部署

最后,我们将代理容器化,以便在任何支持Docker的环境(如云服务器或Kubernetes)中一致地运行。

# Dockerfile
FROM python:3.11-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

EXPOSE 8000

CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000"]

构建镜像并运行:

docker build -t research-agent .
docker run -d -p 8000:8000 --env-file .env research-agent

现在,你的代理可以通过http://localhost:8000/research调用,并带有对话记忆、工具使用和持久化状态。将容器部署到任何云服务(如AWS ECS、Google Cloud Run或Azure Container Instances)只需一次推送。

结论

本文带你从零到生产构建了一个自主研究代理。关键要点包括:精确定义任务边界、选择适合的工具框架、构建具有记忆和工具的核心循环、通过API暴露、以及容器化部署。这些技能直接适用于更复杂的生产级代理项目。