5步构建智能研究助手:Gemini+LangGraph全栈架构深度解析
你是否曾为构建一个能自主思考、搜索和总结的AI助手而苦恼?本文将带你深入剖析gemini-fullstack-langgraph-quickstart项目的后端架构,揭示如何利用FastAPI和LangGraph构建一个功能完备的智能研究助手。读完本文,你将掌握:
- 全栈AI助手的核心架构设计
- FastAPI服务与前端路由的无缝集成
- LangGraph状态管理与节点通信机制
- Gemini 2.5 API的高效调用策略
- 智能研究流程的自动化实现
项目架构概览
gemini-fullstack-langgraph-quickstart是一个基于Gemini 2.5和LangGraph构建全栈AI助手的快速启动项目。该项目采用前后端分离架构,后端使用Python的FastAPI框架提供API服务,并通过LangGraph实现复杂的AI代理逻辑;前端则使用React框架构建用户界面。
项目的核心文件结构如下:
- 后端服务:backend/src/agent/app.py
- LangGraph定义:backend/src/agent/graph.py
- 状态管理:backend/src/agent/state.py
- 配置文件:backend/src/agent/configuration.py
- 工具与模式:backend/src/agent/tools_and_schemas.py
FastAPI服务与路由设计
FastAPI是项目后端的核心框架,负责处理HTTP请求、路由管理和前后端集成。在backend/src/agent/app.py中,我们可以看到FastAPI应用的初始化和路由配置。
应用初始化
# Define the FastAPI app
app = FastAPI()
这行简单的代码创建了一个FastAPI应用实例,作为整个后端服务的入口点。FastAPI的优势在于其高性能、自动生成的API文档和类型提示支持,非常适合构建API服务。
前端路由集成
项目采用了一种巧妙的方式将前端React应用与后端API无缝集成:
def create_frontend_router(build_dir="../frontend/dist"):
"""Creates a router to serve the React frontend."""
build_path = pathlib.Path(__file__).parent.parent.parent / build_dir
if not build_path.is_dir() or not (build_path / "index.html").is_file():
# 返回一个临时路由,提示前端未构建
return Route("/{path:path}", endpoint=dummy_frontend)
return StaticFiles(directory=build_path, html=True)
# 将前端挂载到/app路径下
app.mount(
"/app",
create_frontend_router(),
name="frontend",
)
这种设计使得前端应用可以直接通过后端服务访问,避免了跨域问题,同时简化了部署流程。当访问/app路径时,FastAPI会自动提供前端React应用的静态文件。
LangGraph状态管理系统
LangGraph是构建AI代理的关键框架,它提供了一种声明式的方式来定义代理的状态和行为。在backend/src/agent/state.py中,我们可以看到精心设计的状态管理系统。
核心状态类型
项目定义了多种状态类型来支持复杂的研究流程:
class OverallState(TypedDict):
messages: Annotated[list, add_messages]
search_query: Annotated[list, operator.add]
web_research_result: Annotated[list, operator.add]
sources_gathered: Annotated[list, operator.add]
initial_search_query_count: int
max_research_loops: int
research_loop_count: int
reasoning_model: str
OverallState作为全局状态容器,使用Annotated类型和operator.add来指示状态合并策略,确保在并行执行节点时状态能够正确合并。
专用状态类型
除了全局状态,项目还定义了多种专用状态类型,用于不同阶段的信息传递:
- QueryGenerationState:用于搜索查询生成阶段
- WebSearchState:用于网络搜索阶段
- ReflectionState:用于反思和评估阶段
这种细分的状态设计使得每个节点只需关注自己需要的信息,降低了系统复杂度,提高了可维护性。
智能研究代理的工作流程
项目的核心是一个能够自动进行研究的AI代理,其工作流程在backend/src/agent/graph.py中定义。这个代理能够生成搜索查询、执行网络搜索、反思结果并生成最终答案。
代理图构建
# Create our Agent Graph
builder = StateGraph(OverallState, config_schema=Configuration)
# Define the nodes we will cycle between
builder.add_node("generate_query", generate_query)
builder.add_node("web_research", web_research)
builder.add_node("reflection", reflection)
builder.add_node("finalize_answer", finalize_answer)
# Set the entrypoint as `generate_query`
builder.add_edge(START, "generate_query")
# Add conditional edges for parallel processing
builder.add_conditional_edges(
"generate_query", continue_to_web_research, ["web_research"]
)
builder.add_edge("web_research", "reflection")
builder.add_conditional_edges(
"reflection", evaluate_research, ["web_research", "finalize_answer"]
)
builder.add_edge("finalize_answer", END)
graph = builder.compile(name="pro-search-agent")
这段代码定义了代理的完整工作流程,包括四个主要节点:查询生成、网络研究、反思评估和最终回答。
关键节点解析
1. 查询生成节点
def generate_query(state: OverallState, config: RunnableConfig) -> QueryGenerationState:
"""生成基于用户问题的搜索查询"""
configurable = Configuration.from_runnable_config(config)
# 初始化Gemini 2.0 Flash模型
llm = ChatGoogleGenerativeAI(
model=configurable.query_generator_model,
temperature=1.0,
max_retries=2,
api_key=os.getenv("GEMINI_API_KEY"),
)
structured_llm = llm.with_structured_output(SearchQueryList)
# 格式化提示并生成搜索查询
current_date = get_current_date()
formatted_prompt = query_writer_instructions.format(
current_date=current_date,
research_topic=get_research_topic(state["messages"]),
number_queries=state["initial_search_query_count"],
)
result = structured_llm.invoke(formatted_prompt)
return {"search_query": result.query}
该节点使用Gemini模型根据用户问题生成优化的搜索查询,为后续的网络研究做准备。
2. 网络研究节点
def web_research(state: WebSearchState, config: RunnableConfig) -> OverallState:
"""执行网络研究并获取相关信息"""
configurable = Configuration.from_runnable_config(config)
formatted_prompt = web_searcher_instructions.format(
current_date=get_current_date(),
research_topic=state["search_query"],
)
# 使用Google Generative AI客户端执行搜索
response = genai_client.models.generate_content(
model=configurable.query_generator_model,
contents=formatted_prompt,
config={
"tools": [{"google_search": {}}],
"temperature": 0,
},
)
# 处理搜索结果并返回
resolved_urls = resolve_urls(
response.candidates[0].grounding_metadata.grounding_chunks, state["id"]
)
citations = get_citations(response, resolved_urls)
modified_text = insert_citation_markers(response.text, citations)
sources_gathered = [item for citation in citations for item in citation["segments"]]
return {
"sources_gathered": sources_gathered,
"search_query": [state["search_query"]],
"web_research_result": [modified_text],
}
该节点利用Google的搜索API执行实际的网络搜索,并处理返回的结果,包括提取关键信息和添加引用标记。
3. 反思评估节点
def reflection(state: OverallState, config: RunnableConfig) -> ReflectionState:
"""分析当前研究结果,识别知识差距并生成后续查询"""
configurable = Configuration.from_runnable_config(config)
state["research_loop_count"] = state.get("research_loop_count", 0) + 1
# 使用Gemini模型分析研究结果
llm = ChatGoogleGenerativeAI(
model=configurable.reflection_model,
temperature=1.0,
max_retries=2,
api_key=os.getenv("GEMINI_API_KEY"),
)
result = llm.with_structured_output(Reflection).invoke(formatted_prompt)
return {
"is_sufficient": result.is_sufficient,
"knowledge_gap": result.knowledge_gap,
"follow_up_queries": result.follow_up_queries,
"research_loop_count": state["research_loop_count"],
"number_of_ran_queries": len(state["search_query"]),
}
反思节点是体现AI助手智能的关键部分,它分析现有研究结果,判断是否需要进一步搜索,并生成后续查询。
4. 最终回答节点
def finalize_answer(state: OverallState, config: RunnableConfig):
"""整合研究结果,生成最终回答"""
configurable = Configuration.from_runnable_config(config)
reasoning_model = state.get("reasoning_model") or configurable.answer_model
# 格式化提示并生成最终回答
formatted_prompt = answer_instructions.format(
current_date=current_date,
research_topic=get_research_topic(state["messages"]),
summaries="\n---\n\n".join(state["web_research_result"]),
)
llm = ChatGoogleGenerativeAI(
model=reasoning_model,
temperature=0,
max_retries=2,
api_key=os.getenv("GEMINI_API_KEY"),
)
result = llm.invoke(formatted_prompt)
# 处理来源并返回最终结果
unique_sources = []
for source in state["sources_gathered"]:
if source["short_url"] in result.content:
result.content = result.content.replace(
source["short_url"], source["value"]
)
unique_sources.append(source)
return {
"messages": [AIMessage(content=result.content)],
"sources_gathered": unique_sources,
}
该节点负责整合所有研究结果,生成最终的回答,并确保所有引用来源都被正确标记和包含。
研究流程控制
项目实现了一个智能的研究流程控制机制,能够根据反思结果决定是继续搜索还是生成最终回答:
def evaluate_research(
state: ReflectionState,
config: RunnableConfig,
) -> OverallState:
"""决定下一步行动:继续研究或生成最终回答"""
configurable = Configuration.from_runnable_config(config)
max_research_loops = (
state.get("max_research_loops")
if state.get("max_research_loops") is not None
else configurable.max_research_loops
)
if state["is_sufficient"] or state["research_loop_count"] >= max_research_loops:
return "finalize_answer"
else:
return [
Send(
"web_research",
{
"search_query": follow_up_query,
"id": state["number_of_ran_queries"] + int(idx),
},
)
for idx, follow_up_query in enumerate(state["follow_up_queries"])
]
这个控制机制确保AI助手不会无限循环搜索,同时保证研究的充分性,体现了项目在AI代理设计上的专业性。
代理执行流程可视化
为了更直观地理解AI代理的工作流程,我们可以参考项目中的代理流程图:
该图展示了AI代理从接收用户查询到生成最终回答的完整流程,包括查询生成、并行网络搜索、结果反思和回答生成等关键步骤。通过这种可视化,我们可以清晰地看到各个节点之间的交互和数据流向。
总结与扩展
gemini-fullstack-langgraph-quickstart项目展示了如何利用FastAPI和LangGraph构建一个功能强大的全栈AI助手。其核心优势在于:
-
模块化设计:将复杂的AI代理逻辑分解为独立的节点,提高了代码的可维护性和可扩展性。
-
高效状态管理:通过精心设计的状态类型和合并策略,实现了复杂工作流中的数据一致性。
-
智能流程控制:基于反思的动态流程调整,使AI助手能够自主决定下一步行动。
-
Gemini API集成:充分利用Gemini 2.5的强大能力,实现高质量的查询生成和结果分析。
-
前后端无缝集成:通过FastAPI的路由设计,实现了前后端的无缝通信和部署。
对于希望构建类似AI助手的开发者,这个项目提供了一个优秀的起点。你可以根据自己的需求扩展功能,例如添加更多工具集成、优化提示工程或增强用户界面等。
要开始使用这个项目,只需克隆仓库并按照README.md中的说明进行设置:
git clone https://gitcode.com/gh_mirrors/ge/gemini-fullstack-langgraph-quickstart
cd gemini-fullstack-langgraph-quickstart
# 按照README中的说明安装依赖和配置环境变量
通过深入理解和定制这个项目,你可以构建出满足特定需求的AI助手,为用户提供更智能、更高效的服务。
希望本文对你理解全栈AI助手的构建有所帮助!如果你有任何问题或建议,欢迎在评论区留言讨论。别忘了点赞和收藏,以便日后参考。敬请关注更多关于AI代理开发的精彩内容!
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考





