README.md
ShopAgent
基于 LangGraph 与 ReAct 模式 的自主多模态时尚购物智能体,支持文本与图片输入、商品搜索、风格分析与多轮对话。
Demo
概述
ShopAgent 根据用户意图自主决定是否调用工具、调用哪些工具,维护对话状态,并在适当时机给出回复。核心能力包括:
- 自主工具选择与执行:按需调用
search_products、analyze_image_style、web_search - 商品搜索:通过外部 Search API 检索,结果经 LLM 质量评估后写入会话级结果库,回复中通过
[SEARCH_RESULTS_REF:ref_id]引用,前端自动渲染为商品卡片 - 多轮对话与上下文:LangGraph + MemorySaver 按
thread_id持久化消息 - 图片理解:上传图片时可调用
analyze_image_style做风格/属性分析,再结合搜索 - 流式输出:思考过程、工具调用与结果、正式回复以前端可感知的事件流实时展示,调试面板默认展开
技术栈
| 组件 | 技术 |
|---|---|
| Agent 框架 | LangGraph(StateGraph + ReAct) |
| LLM | LangChain OpenAI 兼容(默认 gpt-4o-mini,可配 base_url 如 DashScope) |
| 推理/思考 | 可选:OpenAI Responses API reasoning / DashScope enable_thinking |
| 搜索 | 外部 Search API(HTTP),会话内结果登记到 SearchResultRegistry |
| 前端 | Streamlit |
架构要点
Agent 流程(LangGraph)
START → Agent → [有 tool_calls?] → Tools → Agent → … → END
- Agent 节点:注入 system prompt,调用
llm_with_tools.invoke(messages),产出 AIMessage(含 content 和/或 tool_calls)。 - 条件边:若最后一条消息含
tool_calls则进入 Tools 节点,否则结束。 - Tools 节点:执行本轮工具调用,将 ToolMessage 追加到 state,再次回到 Agent。
- 状态:
AgentState = { messages, current_image_path },messages使用add_messages累加。
搜索结果与引用
- SearchResultRegistry:按会话存储每次
search_products的结构化结果(query、质量统计、商品列表),并为每次搜索分配会话内唯一ref_id(如sr_1,sr_2)。 - search_products 工具:请求 Search API → 用 LLM 对每条结果打标(Relevant / Partially Relevant / Irrelevant)→ 将结果写入 registry,返回包含
[SEARCH_RESULTS_REF:ref_id]的文本及质量摘要。 - 最终回复:Agent 在正文中写入
[SEARCH_RESULTS_REF:ref_id],前端用正则解析并在对应位置渲染商品卡片(见app.py中SEARCH_RESULTS_REF_PATTERN与render_message_with_refs)。
工具列表
| 工具 | 说明 |
|---|---|
search_products(query) |
文本商品搜索,会话绑定,结果写入 Registry 并返回 ref 引用 |
analyze_image_style(image_path) |
VLM 分析图片风格/属性,供后续搜索或回复使用 |
web_search(query) |
联网检索(如时效、天气、事件等) |
流式与调试
- chat_stream:
ShoppingAgent.chat_stream(query, image_path)迭代产出事件:debug_update(思考步骤、工具调用/结果)、response_delta/response_replace(正式回复增量)、done(最终结果)。 - 前端:发送消息后消费
chat_stream,在占位区实时更新工具链、调试步骤和回复;调试面板「思考 & 工具调用详细过程」默认展开,可展示 thinking 与工具结果。 - chat:仍保留
chat(),内部改为消费chat_stream直至done,保证兼容。
示例
文本搜索:
用户:「有没有适合通勤的女式大衣」
Agent:search_products("通勤 女式 大衣") → 返回 [SEARCH_RESULTS_REF:sr_1],页面展示商品卡片
图片 + 搜索:
用户:[上传一张外套图] 「这件是什么风格?找类似款」
Agent:analyze_image_style(path) → 得到风格描述 → search_products("…") → 引用 sr_1 等
多轮与引用:
第1轮:「红色连衣裙」→ search_products → 展示结果
第2轮:「要正式一点的」→ 结合上下文 search_products("红色 正式 连衣裙")
时效类(web_search):
用户:「最近有什么流行元素」
Agent:web_search("时尚 流行 2025") → 结合结果回复
安装与运行
环境要求
- Python 3.10+(LangChain/LangGraph 推荐 3.12+)
- 配置
.env:至少OPENAI_API_KEY;若用自建或第三方 LLM,可设OPENAI_API_BASE_URL(如 DashScope 兼容地址)
步骤
git clone <repository-url>
cd shop_agent
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txt
# 配置
cp .env.example .env
# 编辑 .env:OPENAI_API_KEY、可选 OPENAI_API_BASE_URL、SEARCH_API_BASE_URL、SEARCH_API_TENANT_ID 等
可选:本地图片数据
若需本地商品图(如侧边栏「Similar」用本地图),可准备 data/images/ 下的图片资源;图像风格分析不依赖该目录。
启动与日志
# 推荐:使用服务脚本(含 Conda 环境激活与日志管理)
./scripts/service.sh start # 后台启动
./scripts/service.sh status # 查看状态
./scripts/service.sh stop # 停止
# 本地调试:前台运行(Ctrl+C 停止)
./scripts/service.sh run
# 也可直接运行 Streamlit(需自行激活虚拟环境)
streamlit run app.py
- 端口优先级:
STREAMLIT_PORT环境变量 >app.config.settings.app_port> 默认6008。 - Host 默认为
0.0.0.0,可通过STREAMLIT_HOST覆盖。 - 日志目录:
logs/streamlit.log(标准输出)、logs/streamlit_error.log(错误输出,由scripts/service.sh统一管理)。
默认访问 http://<HOST>:<PORT>(本地通常是 http://localhost:6008)。商品搜索依赖外部 Search API,请在 .env 中配置 SEARCH_API_BASE_URL 与 SEARCH_API_TENANT_ID。
部署
CentOS 8 等部署说明见 docs/DEPLOY_CENTOS8.md(若存在)。
配置说明(.env 摘要)
| 变量 | 说明 | 默认 |
|---|---|---|
OPENAI_API_KEY |
必填,LLM/视觉调用 | - |
OPENAI_API_BASE_URL |
可选,兼容接口 base URL(如 DashScope) | - |
OPENAI_MODEL |
对话模型 | gpt-4o-mini |
OPENAI_USE_REASONING |
是否开启思考(OpenAI/DashScope 等) | true |
OPENAI_REASONING_EFFORT |
reasoning 力度(如 medium) | medium |
SEARCH_API_BASE_URL |
搜索服务地址 | 见 config.py |
SEARCH_API_TENANT_ID |
租户 ID | 见 config.py |
SEARCH_PRODUCTS_LIMIT |
单次搜索返回条数上限 | 20 |
更多配置项见 app/config.py 中的 Settings,包括:
- OpenAI 相关:
openai_model、openai_vision_model、openai_use_reasoning、openai_reasoning_effort、openai_api_base_url等。 - 应用运行:
app_host、app_port、debug、log_level。 - 数据路径:
raw_data_path、processed_data_path、image_data_path等。
配置加载优先级(高 → 低):代码初始化参数 > 项目根目录下 .env > 系统环境变量 > 默认值,其中 .env 会覆盖同名系统环境变量(见 Settings.settings_customise_sources)。
项目结构(概览)
shop_agent/
├── app/
│ ├── agents/
│ │ └── shopping_agent.py # LangGraph 图、chat/chat_stream、thinking 支持
│ ├── config.py # 配置与环境变量
│ ├── search_registry.py # SearchResultRegistry、ProductItem、SearchResult
│ ├── tools/
│ │ ├── search_tools.py # search_products、analyze_image_style、web_search
│ │ └── __init__.py
│ └── ...
├── app.py # Streamlit UI、流式渲染、引用解析与商品卡片
├── docs/
│ └── 技术实现报告.md # 详细设计、Prompt 与架构说明
├── scripts/
│ └── service.sh # 统一的启停脚本(start/stop/status/run)
├── .env.example
├── requirements.txt
└── README.md