工业级大模型学习之路026:LangGraph 入门与基础 Agent 开发

一、Agent 与 LangGraph 概述

1.1 为什么需要 Agent?RAG 的能力边界

1.1.1 RAG 系统的本质局限

经过前边的学习,我们已经搭建了工业级 RAG 系统,但它本质上是一个被动的信息检索与生成系统,存在三个无法突破的边界:

  1. 知识边界:只能回答知识库中存在的静态信息,无法处理需要计算、推理、实时数据或外部操作的任务
  2. 能力边界:只能生成文本,无法执行任何实际操作(如调用 API、操作数据库、发送邮件)
  3. 逻辑边界:只能进行单步推理,无法处理需要多步骤规划、迭代优化的复杂任务

工业级场景对比

任务类型 RAG 能否完成 Agent 能否完成
"公司的出差补贴标准是什么?"
"我出差 3 天,每天补贴 150 元,能报销多少钱?" ❌(需要计算)
"帮我生成这趟出差的报销单并提交审批" ❌(需要执行操作)
"分析上季度的销售数据,找出增长最快的产品线" ❌(需要数据处理 + 分析)
1.1.2 Agent 的核心定义与价值

Agent(智能体)是一种能够自主感知环境、制定计划、执行行动、迭代优化以完成特定目标的智能系统。它的核心价值在于:

  • 工具使用能力:通过调用外部工具突破大模型自身的能力边界
  • 自主规划能力:将复杂任务分解为可执行的子任务
  • 迭代反思能力:根据执行结果调整策略,纠正错误
  • 长期记忆能力:记住历史交互和学习经验,实现个性化服务

1.2 Agent 四大核心组件与工作原理

一个工业级 Agent 系统由四个不可缺少的核心组件组成:

组件 作用 工业级要求
规划器(Planner) 分解任务、制定执行计划、动态调整策略 支持多步骤规划、错误修正、任务优先级排序
工具集(Tools) Agent 可以调用的外部能力集合 标准化接口、权限控制、错误处理、重试机制
记忆系统(Memory) 存储对话历史、执行过程、长期知识 短期记忆(会话内)、长期记忆(跨会话)、状态持久化
执行器(Executor) 执行工具调用、生成最终回答 支持并行执行、流式输出、异常处理

Agent 标准工作流程

1.3 为什么选择 LangGraph?从 Legacy Agent 到工业级框架

1.3.1 Legacy Agent 的致命缺陷

LangChain 早期的 Agent 实现(如ZeroShotAgentReActAgent)在 2024 年已被完全废弃,因为它们存在以下无法解决的问题:

  1. 黑盒化:执行过程完全不透明,无法调试和定制
  2. 灵活性差:只能使用预设的工作流,无法实现循环、分支、并行等复杂逻辑
  3. 状态管理混乱:没有统一的状态存储机制,无法实现断点续跑和长对话
  4. 可靠性低:工具调用格式错误率高,容易陷入无限循环
1.3.2 LangGraph 的工业级优势

LangGraph 是 LangChain 团队专为构建生产级 Agent 和复杂工作流设计的声明式框架,解决了 Legacy Agent 的所有问题:

  • 声明式设计:用图的方式清晰定义工作流,代码即文档
  • 完全可观测:与 LangSmith 深度集成,可追踪每一步执行过程
  • 强大的状态管理:原生支持状态持久化、多会话隔离、断点续跑
  • 灵活的控制流:支持循环、分支、并行、中断、人类介入等所有控制流
  • 原生工具调用:与 LangChain 工具生态无缝集成,支持并行工具调用
  • 高性能:原生支持异步和流式输出,满足生产环境性能要求
1.3.3 LangGraph 与传统工作流工具的对比
特性 LangGraph Airflow/Prefect 普通编程
设计目标 大模型 Agent 与动态工作流 定时任务与静态工作流 通用编程
状态管理 原生支持,自动持久化 有限支持 需要手动实现
动态性 支持运行时动态调整流程 流程固定,编译后无法修改 完全灵活
大模型集成 原生深度集成 需要手动集成 需要手动集成
可观测性 专为大模型设计的追踪 通用任务追踪 需要手动实现
适用场景 Agent、智能工作流、多轮对话 数据管道、定时任务 所有场景

1.4 LangGraph 四大核心概念深度解析

LangGraph 的核心思想是将智能体的执行过程表示为一个有向图,所有逻辑都围绕以下四个概念展开:

1.4.1 State(状态)
  • 定义:智能体的全局共享内存,存储所有上下文信息、执行过程、中间结果和最终输出
  • 工业级要求:类型安全、可序列化、支持增量更新、可持久化
  • 实现方式
    • 简单场景:TypedDict(轻量,无验证)
    • 生产场景:Pydantic BaseModel(推荐,提供类型安全和数据验证)
  • 关键特性 :支持增量更新(使用Annotated[Type, operator.add]),避免覆盖历史数据
1.4.2 Node(节点)
  • 定义:图中的可执行单元,对应一个具体的操作(思考、调用工具、生成回答等)
  • 输入:当前的 State
  • 输出:State 的更新部分(不需要返回完整 State,LangGraph 会自动合并)
  • 类型
    • 普通节点:自定义 Python 函数
    • 工具节点:ToolNode(LangGraph 内置,专门处理工具调用)
    • 条件节点:根据 State 值决定下一个执行节点
1.4.3 Edge(边)
  • 定义:连接节点的有向边,定义执行流程和控制逻辑
  • 类型
    • 普通边:顺序执行,从一个节点直接跳转到下一个节点
    • 条件边:根据 State 中的值动态决定下一个执行节点(实现分支和循环)
    • 入口边:定义图的起始节点
    • 结束边 :指向END,表示图执行结束
1.4.4 Graph(图)
  • 定义:由节点和边组成的有向图,是 LangGraph 的最高层抽象
  • 编译:将图定义编译为可执行对象,同时可以配置检查点、中断等高级功能
  • 运行方式
    • invoke():同步运行,返回最终结果
    • stream():流式运行,返回中间结果和最终结果
    • ainvoke()/astream():异步运行,适合生产环境

1.5 ReAct 框架原理解析

ReAct(Reasoning + Acting)是目前工业界应用最广泛的 Agent 框架,由 Google Research 在 2022 年提出。它的核心思想是让大模型交替进行思考和行动,通过工具调用获取外部信息,然后基于新的信息继续思考,直到完成任务。

ReAct 标准提示词模板

bash 复制代码
你是一个有用的AI助手,能够使用工具来完成任务。

你可以使用以下工具:
{tools}

使用工具时,请按照以下格式:
Thought: 我需要使用工具来解决这个问题
Action: 工具名称
Action Input: 工具参数
Observation: 工具返回的结果

当你获得足够的信息后,直接回答用户的问题。
不要编造信息,所有回答必须基于观察结果。

二、LangGraph 工业级 API 详解

2.1 环境准备

首先更新requirements.txt,添加 LangGraph 1.2 + 和相关依赖:

python 复制代码
langgraph>=1.2.0
pydantic>=2.0.0

2.2 状态定义:Pydantic vs TypedDict

工业级推荐使用 Pydantic BaseModel 定义状态,提供更强的类型安全和数据验证:

python 复制代码
from typing import List, Annotated
from pydantic import BaseModel, Field
from langchain_core.messages import BaseMessage
import operator

class AgentState(BaseModel):
    """Agent状态定义(工业级标准)"""
    # 对话历史:使用operator.add实现增量更新,不会覆盖历史消息
    messages: Annotated[List[BaseMessage], operator.add] = Field(default_factory=list, description="对话历史")
    # 迭代次数:用于防止无限循环
    iteration_count: int = Field(default=0, description="当前迭代次数")
    # 最大迭代次数:安全限制
    max_iterations: int = Field(default=5, description="最大迭代次数")

2.3 原生工具调用:bind_tools + ToolNode

LangGraph 1.2 + 原生支持 LangChain 工具调用,完全不需要手动解析 JSON,这是工业级开发的标准方式:

python 复制代码
from langgraph.graph import StateGraph, END
from langgraph.prebuilt import ToolNode
from core.llm_factory import LLMFactory

# 1. 定义工具
@tool
def add(a: int, b: int) -> int:
    """加法工具,计算两个数的和"""
    return a + b

tools = [add]

# 2. 将工具绑定到LLM
llm = LLMFactory.get_llm()
llm_with_tools = llm.bind_tools(tools)

# 3. 定义思考节点
def agent_node(state: AgentState) -> dict:
    """思考节点:调用LLM生成回答或工具调用"""
    response = llm_with_tools.invoke(state.messages)
    # 增加迭代次数
    return {"messages": [response], "iteration_count": state.iteration_count + 1}

# 4. 使用内置ToolNode处理工具调用
tool_node = ToolNode(tools)

# 5. 定义路由函数
def router(state: AgentState) -> str:
    """路由函数:决定下一步是调用工具还是结束"""
    last_message = state.messages[-1]
    # 检查是否有工具调用
    if last_message.tool_calls:
        # 检查是否超过最大迭代次数
        if state.iteration_count >= state.max_iterations:
            return END
        return "tools"
    return END

# 6. 构建图(使用StateGraph,这是唯一正确的方式)
builder = StateGraph(AgentState)
builder.add_node("agent", agent_node)
builder.add_node("tools", tool_node)

builder.add_edge("tools", "agent")
builder.add_conditional_edges("agent", router)
builder.set_entry_point("agent")

graph = builder.compile()

2.4 Checkpoint 机制:状态持久化与断点续跑

Checkpoint 是 LangGraph 最重要的生产级特性,它可以自动保存 Agent 的执行状态,实现:

  • 断点续跑:程序中断后可以从上次中断的地方继续执行
  • 多会话隔离:不同用户的会话状态互不干扰
  • 历史回溯:查看 Agent 的完整执行历史
  • 人类介入:在执行过程中暂停,等待人类确认后继续
python 复制代码
from langgraph.checkpoint.sqlite import SqliteSaver

# 使用SQLite作为Checkpoint存储(生产环境可替换为PostgreSQL)
checkpointer = SqliteSaver.from_conn_string("./data/agent_checkpoints.db")

# 编译图时添加checkpointer
graph = builder.compile(checkpointer=checkpointer)

# 运行时指定thread_id,实现多会话隔离
config = {"configurable": {"thread_id": "user_123"}}

# 第一次运行
result = graph.invoke(
    {"messages": [HumanMessage(content="计算2+3*4")]},
    config=config
)
print(result["messages"][-1].content)

# 同一个thread_id可以继续对话
result = graph.invoke(
    {"messages": [HumanMessage(content="再乘以5等于多少?")]},
    config=config
)
print(result["messages"][-1].content)

三、核心实战:工业级 ReAct Agent 实现

3.1 第一步:工具定义与工业级最佳实践

工具是 Agent 能力的延伸,定义良好的工具是 Agent 成功的关键。

代码位置core/tools.py(完全重写,符合工业级标准)

python 复制代码
from typing import Optional, Type
from langchain.tools import tool
from pydantic import BaseModel, Field
from core.rag_retriever import RAGRetriever
from core.llm_factory import LLMFactory
from utils.logger import logger
import datetime

# ===================== 工具输入参数定义 =====================
class CalculatorInput(BaseModel):
    expression: str = Field(description="要计算的数学表达式,仅支持加减乘除和括号,例如:'2 + 3 * (4 - 1)'")

class RAGInput(BaseModel):
    query: str = Field(description="要检索的问题,必须是清晰、具体的问题")

class CurrentTimeInput(BaseModel):
    format: str = Field(default="%Y-%m-%d %H:%M:%S", description="时间格式,默认为'YYYY-MM-DD HH:MM:SS'")

# ===================== 工具实现 =====================
@tool(args_schema=CalculatorInput, handle_tool_error=True)
def calculator(expression: str) -> str:
    """
    数学计算器工具,用于执行基本的数学计算。
    仅支持加减乘除(+、-、*、/)和括号运算。
    所有数学问题都必须使用此工具,不要自己计算。
    """
    try:
        # 安全计算:只允许基本数学运算,禁止执行任意代码
        allowed_chars = set("0123456789+-*/(). ")
        if not all(c in allowed_chars for c in expression):
            return "错误:表达式包含非法字符,仅支持数字和加减乘除括号"
        
        # 使用eval但限制命名空间,防止代码注入
        result = eval(expression, {"__builtins__": None}, {})
        return f"计算结果:{expression} = {result}"
    except Exception as e:
        logger.error(f"计算器工具执行失败:{e}")
        return f"计算错误:{str(e)},请检查表达式是否正确"

@tool(args_schema=RAGInput, handle_tool_error=True)
def enterprise_knowledge_base(query: str) -> str:
    """
    企业知识库检索工具,用于获取企业内部的规章制度、产品信息、流程规范等知识。
    当用户的问题与企业内部信息相关时,必须使用此工具。
    """
    try:
        retriever = RAGRetriever()
        docs = retriever.retrieve(query, top_k=3)
        if not docs:
            return "知识库中没有找到相关信息,请尝试换一种问法"
        
        # 格式化检索结果
        result = "从知识库中检索到以下信息:\n"
        for i, doc in enumerate(docs):
            result += f"[{i+1}] {doc.page_content}\n\n"
        return result.strip()
    except Exception as e:
        logger.error(f"知识库检索失败:{e}")
        return f"知识库检索失败:{str(e)}"

@tool(args_schema=CurrentTimeInput, handle_tool_error=True)
def get_current_time(format: str = "%Y-%m-%d %H:%M:%S") -> str:
    """
    获取当前时间的工具。
    当用户询问当前时间、日期或需要时间相关的信息时使用此工具。
    """
    try:
        current_time = datetime.datetime.now().strftime(format)
        return f"当前时间:{current_time}"
    except Exception as e:
        logger.error(f"获取当前时间失败:{e}")
        return f"获取时间失败:{str(e)}"

# ===================== 工具集合 =====================
# 生产环境工具集合,只包含经过安全审核的工具
PRODUCTION_TOOLS = [calculator, enterprise_knowledge_base, get_current_time]

# 工具名称到工具对象的映射
TOOL_MAP = {tool.name: tool for tool in PRODUCTION_TOOLS}

工业级工具定义最佳实践

  1. 强制使用 Pydantic 定义输入参数:提供类型安全和自动验证,减少工具调用错误
  2. 编写详细的工具描述:明确告诉大模型工具的作用、使用场景和参数要求
  3. 开启 handle_tool_error:工具内部异常会被自动捕获并返回给大模型,让它尝试修正
  4. 严格的安全限制:禁止工具执行任意代码、访问敏感资源
  5. 完善的日志记录:记录所有工具调用和结果,便于调试和审计
  6. 输入输出过滤:过滤敏感信息,防止数据泄露

3.2 第二步:Agent 状态与系统提示词

代码位置core/react_agent.py(新建文件)

python 复制代码
from typing import List, Annotated
from pydantic import BaseModel, Field
from langchain_core.messages import BaseMessage
from langgraph.graph import MessageGraph, END
from langgraph.prebuilt import ToolNode
from langgraph.checkpoint.sqlite import SqliteSaver
from core.llm_factory import LLMFactory
from core.tools import PRODUCTION_TOOLS
from utils.logger import logger
import operator

class AgentState(BaseModel):
    """ReAct Agent状态"""
    messages: Annotated[List[BaseMessage], operator.add] = Field(default_factory=list)
    iteration_count: int = Field(default=0)
    max_iterations: int = Field(default=5)

# 系统提示词(工业级优化版)
SYSTEM_PROMPT = """
你是企业内部智能助手,只能使用提供的工具来回答问题。

你必须严格遵守以下规则:
1. 所有回答必须基于工具返回的结果,绝对不能编造信息
2. 当需要计算、获取企业内部信息或当前时间时,必须使用对应的工具
3. 每次只能调用一个工具,不要同时调用多个工具
4. 如果工具返回的信息不足以回答问题,可以尝试换一种方式调用工具
5. 如果多次调用工具仍然无法获得答案,直接告诉用户无法回答
6. 回答要简洁、准确、专业,符合企业内部沟通规范

你可以使用以下工具:
{tools_description}
"""

# 生成工具描述
tools_description = "\n".join([f"- {tool.name}: {tool.description}" for tool in PRODUCTION_TOOLS])
system_message = SystemMessage(content=SYSTEM_PROMPT.format(tools_description=tools_description))

3.3 第三步:思考节点与路由函数

python 复制代码
# 初始化LLM并绑定工具
llm = LLMFactory.get_llm()
llm_with_tools = llm.bind_tools(PRODUCTION_TOOLS)

def agent_think(state: AgentState) -> dict:
    """思考节点:分析问题,决定下一步行动"""
    logger.info(f"Agent思考中,迭代次数:{state.iteration_count}/{state.max_iterations}")
    
    # 构建消息列表:系统提示词 + 对话历史
    messages = [system_message] + state.messages
    
    # 调用LLM
    response = llm_with_tools.invoke(messages)
    
    # 检查是否超过最大迭代次数
    if state.iteration_count >= state.max_iterations:
        logger.warning("Agent超过最大迭代次数,强制结束")
        return {
            "messages": [AIMessage(content="抱歉,我无法在有限步骤内完成你的请求,请尝试简化问题。")],
            "iteration_count": state.iteration_count + 1
        }
    
    return {
        "messages": [response],
        "iteration_count": state.iteration_count + 1
    }

def router(state: AgentState) -> str:
    """路由函数:决定下一步是调用工具还是结束"""
    last_message = state.messages[-1]
    
    # 如果有工具调用,跳转到工具节点
    if last_message.tool_calls:
        logger.info(f"Agent决定调用工具:{[tc['name'] for tc in last_message.tool_calls]}")
        return "tools"
    
    # 否则直接结束
    logger.info("Agent决定直接回答")
    return END

3.4 第四步:构建与编译 Agent 图

python 复制代码
def build_react_agent() -> StateGraph:
    """构建工业级ReAct Agent(使用StateGraph标准API)"""
    builder = StateGraph(AgentState)
    
    # 添加节点
    builder.add_node("agent", agent_think)
    builder.add_node("tools", ToolNode(PRODUCTION_TOOLS))
    
    # 添加边
    builder.add_edge("tools", "agent")
    builder.add_conditional_edges("agent", router)
    
    # 设置入口点
    builder.set_entry_point("agent")
    
    # 配置Checkpoint持久化
    checkpointer = SqliteSaver.from_conn_string("./data/agent_checkpoints.db")
    
    # 编译图
    graph = builder.compile(checkpointer=checkpointer)
    
    logger.info("✅ ReAct Agent构建完成(LangGraph 1.0+ 标准API)")
    return graph

# 全局单例Agent实例
react_agent = build_react_agent()

3.5 第五步:LangSmith 集成调试

Agent 的调试难度远高于普通程序,LangSmith 是目前最好的 Agent 调试工具。在你的.env文件中添加以下配置:

bash 复制代码
LANGCHAIN_TRACING_V2=true
LANGCHAIN_API_KEY=你的LangSmith API密钥
LANGCHAIN_PROJECT=langchain-2026-agent

现在所有 Agent 的执行过程都会自动追踪到 LangSmith,你可以:

  • 查看每一步的输入输出
  • 查看工具调用的详细信息
  • 查看状态的变化过程
  • 调试错误和异常

3.6 第六步:测试 Agent

python 复制代码
def test_react_agent():
    """测试工业级ReAct Agent"""
    print("🚀 测试工业级ReAct Agent\n")
    
    # 配置:每个用户一个独立的thread_id
    config = {"configurable": {"thread_id": "test_user_001"}}
    
    # 测试用例1:需要计算
    print("测试1:数学计算")
    result = react_agent.invoke(
        {"messages": [HumanMessage(content="计算(123 + 456) * 789")]},
        config=config
    )
    print(f"回答:{result['messages'][-1].content}\n")
    
    # 测试用例2:需要检索知识库
    print("测试2:企业知识库检索")
    result = react_agent.invoke(
        {"messages": [HumanMessage(content="公司的出差补贴标准是什么?")]},
        config=config
    )
    print(f"回答:{result['messages'][-1].content}\n")
    
    # 测试用例3:需要获取当前时间
    print("测试3:获取当前时间")
    result = react_agent.invoke(
        {"messages": [HumanMessage(content="现在几点了?")]},
        config=config
    )
    print(f"回答:{result['messages'][-1].content}\n")
    
    # 测试用例4:多轮对话
    print("测试4:多轮对话")
    result = react_agent.invoke(
        {"messages": [HumanMessage(content="我刚才问了你什么问题?")]},
        config=config
    )
    print(f"回答:{result['messages'][-1].content}\n")

if __name__ == "__main__":
    test_react_agent()

四、项目整合:Agent 与 RAG 系统无缝集成

4.1 升级 RAGService,支持双模式切换

代码位置core/rag_service.py

python 复制代码
from typing import Iterator
from core.rag_retriever import RAGRetriever
from core.prompt_service import PromptService
from core.react_agent import react_agent
from langchain_core.messages import HumanMessage
from config.settings import settings
from utils.logger import logger

class RAGService:
    """完整的RAG+Agent问答服务(第7天工业级版)"""
    def __init__(self):
        self.retriever = RAGRetriever()
        self.prompt = PromptService()
        logger.info("✅ RAG+Agent问答服务初始化完成")

    def query(
        self,
        question: str,
        user_id: str = "default_user",
        top_k: int = None,
        similarity_threshold: float = None,
        use_anti_hallucination: bool = True,
        use_agent: bool = False
    ) -> str:
        """
        同步问答
        :param user_id: 用户ID,用于隔离不同用户的会话状态
        :param use_agent: 是否使用Agent模式(支持工具调用)
        """
        try:
            if use_agent:
                logger.info(f"用户[{user_id}]使用Agent模式提问:{question}")
                config = {"configurable": {"thread_id": user_id}}
                result = react_agent.invoke(
                    {"messages": [HumanMessage(content=question)]},
                    config=config
                )
                return result["messages"][-1].content
            
            # 原RAG逻辑完全保留,不做任何修改
            logger.info(f"用户[{user_id}]使用RAG模式提问:{question}")
            docs = self.retriever.retrieve(question, top_k, similarity_threshold)
            if not docs:
                return "抱歉,知识库中没有找到相关信息,无法回答您的问题。"

            context = "\n\n".join([f"[{i+1}] {doc.page_content}" for i, doc in enumerate(docs)])
            template_version = "v2.0" if use_anti_hallucination else "v1.0"
            answer = self.prompt.generate(
                template_name="rag_answer",
                version=template_version,
                inputs={"context": context, "question": question}
            )

            logger.info(f"生成回答完成:{answer[:200]}...")
            return answer

        except Exception as e:
            logger.error(f"问答失败:{str(e)}", exc_info=True)
            return "抱歉,回答生成时发生错误,请稍后重试。"

    def stream_query(
        self,
        question: str,
        user_id: str = "default_user",
        top_k: int = None,
        similarity_threshold: float = None,
        use_anti_hallucination: bool = True,
        use_agent: bool = False
    ) -> Iterator[str]:
        """流式问答(增强版,支持Agent流式输出)"""
        try:
            if use_agent:
                logger.info(f"用户[{user_id}]使用Agent模式流式提问:{question}")
                config = {"configurable": {"thread_id": user_id}}
                
                # 流式输出Agent执行过程
                for step in react_agent.stream(
                    {"messages": [HumanMessage(content=question)]},
                    config=config
                ):
                    if "agent" in step:
                        yield "🤔 思考中...\n"
                        # 流式输出思考内容
                        if hasattr(step["agent"]["messages"][-1], "content"):
                            yield step["agent"]["messages"][-1].content + "\n"
                    elif "tools" in step:
                        yield "🔧 正在执行工具...\n"
                        # 流式输出工具结果
                        for tool_result in step["tools"]["messages"]:
                            yield f"工具返回:{tool_result.content[:200]}...\n"
                    elif "__end__" in step:
                        yield "\n✅ 最终回答:\n"
                        yield step["__end__"]["messages"][-1].content
                return
            
            # 原RAG流式逻辑完全保留
            logger.info(f"用户[{user_id}]使用RAG模式流式提问:{question}")
            docs = self.retriever.retrieve(question, top_k, similarity_threshold)
            if not docs:
                yield "抱歉,知识库中没有找到相关信息,无法回答您的问题。"
                return

            context = "\n\n".join([f"[{i+1}] {doc.page_content}" for i, doc in enumerate(docs)])
            template_version = "v2.0" if use_anti_hallucination else "v1.0"
            yield from self.prompt.stream_generate(
                template_name="rag_answer",
                version=template_version,
                inputs={"context": context, "question": question}
            )

        except Exception as e:
            logger.error(f"流式问答失败:{str(e)}", exc_info=True)
            yield "抱歉,回答生成时发生错误,请稍后重试。"

4.2 新增 Agent API 接口

代码位置main7.py

python 复制代码
from dotenv import load_dotenv
load_dotenv()

from core.rag_service import RAGService
from fastapi import FastAPI, HTTPException, Depends
from pydantic import BaseModel
import uvicorn

app = FastAPI(title="企业级RAG+Agent API", version="1.0.0")
rag_service = RAGService()

class QueryRequest(BaseModel):
    question: str
    user_id: str = "default_user"
    use_agent: bool = False

class QueryResponse(BaseModel):
    answer: str
    mode: str

@app.post("/api/query", response_model=QueryResponse)
async def query(request: QueryRequest):
    """通用问答接口,支持RAG和Agent两种模式"""
    try:
        answer = rag_service.query(
            question=request.question,
            user_id=request.user_id,
            use_agent=request.use_agent
        )
        return QueryResponse(
            answer=answer,
            mode="agent" if request.use_agent else "rag"
        )
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

@app.post("/api/agent/stream")
async def agent_stream_query(request: QueryRequest):
    """Agent流式问答接口"""
    try:
        return rag_service.stream_query(
            question=request.question,
            user_id=request.user_id,
            use_agent=True
        )
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

@app.get("/api/health")
async def health_check():
    """健康检查接口"""
    return {"status": "healthy", "service": "rag-agent-api"}

if __name__ == "__main__":
    print("🚀 第7天:工业级ReAct Agent开发")
    print("📡 API服务启动中,访问 http://localhost:8000/docs 查看接口文档")
    uvicorn.run(app, host="0.0.0.0", port=8000)

4.3工业级 Agent 开发最佳实践

  1. 工具最小权限原则:只给 Agent 必要的工具权限,禁止给 Agent 执行任意代码、修改系统配置等高风险权限
  2. 输入输出过滤:在调用工具前过滤用户输入中的敏感信息,在返回结果前过滤工具输出中的敏感信息
  3. 最大迭代次数限制:必须设置最大迭代次数,防止 Agent 陷入无限循环
  4. 完善的日志记录:记录所有用户请求、Agent 思考过程、工具调用和结果,便于审计和调试
  5. 异常处理与降级:当工具调用失败或 LLM 出错时,要有优雅的降级策略,不要直接抛出异常
  6. 安全审核:所有工具必须经过安全审核,确保没有安全漏洞
  7. 监控与告警:监控 Agent 的调用量、错误率、平均响应时间等指标,设置告警阈值
相关推荐
鸿乃江边鸟13 小时前
Prompt Engineering 和 Context Engineering 和 Harness Engineering 区别和联系
人工智能·ai
nashane13 小时前
HarmonyOS 6学习:水平仪气泡移动方向错误的完整分析与修复方案
人工智能·华为·harmonyos
小t说说14 小时前
录音文件存储指南:轻松整理与快速查找
人工智能
AI医影跨模态组学14 小时前
如何将多参数MRI影像组学特征与CMS4相关TGF-β/EMT/CAF机制建立关联,并进一步解释其与患者预后及治疗响应的机制联系
人工智能·深度学习·论文·医学影像·影像组学
阿聪谈架构14 小时前
第12章:高级 RAG 技术 —— 让检索更精准、更全面
人工智能·后端
liu****14 小时前
1.Vibe Coding 介绍
人工智能·ai·辅助编程·vibe coding
AIFQuant14 小时前
量化交易系统:历史行情 API 批量拉取与回测数据清洗
开发语言·python·金融·restful·量化交易
零壹AI实验室14 小时前
GPT-5.5 vs 国产大模型:2026年5月AI编程工具横评实测
人工智能·gpt·ai编程