Woodle 知识图谱可视化 + AI 职业顾问的统一服务端 + 前端。 基于 FastAPI,对外暴露:
GET /health:健康检查GET /api/graph:知识图谱节点/边数据(供可视化页面渲染)POST /api/qa:AI 问答(具备工具调用能力的 Agent,可实时查询 Neo4j)GET /front/woodle_ai_home.html:单页前端入口GET /→ 自动重定向到上述前端页面
📌 自本版本起,原 JDGraphBuilder 内置的 HTTP server(
src.cli.serve)已被废弃删除。 图谱 API 与 AI 问答全部由本仓库承载;JDGraphBuilder 作为 库 + CLI 被本项目通过[tool.uv.sources]路径依赖直接引用。
JDGraphMono/
├── backend/ # FastAPI 后端
│ ├── app.py # create_app() 工厂 + 路由挂载
│ ├── main.py # uvicorn 启动入口
│ ├── config.py # 环境变量加载(自动 fallback 到 ../JDGraphBuilder/.env)
│ ├── deps.py # Neo4jClient 生命周期 & DI
│ ├── api/
│ │ ├── health.py # /health
│ │ ├── graph.py # /api/graph
│ │ └── qa.py # /api/qa
│ └── agent/
│ ├── prompts.py # Woodle Agent System Prompt
│ ├── tools.py # 16 个工具的注册表(对 JDGraphBuilder 查询函数的封装)
│ └── runner.py # OpenAI 兼容的 tool-use 循环(支持 DeepSeek thinking 模式)
├── front/
│ └── woodle_ai_home.html # 单页前端
├── .env.example
├── pyproject.toml # 通过 path-dep 引用 ../JDGraphBuilder
└── README.md
cd JDGraphMono
uv sync这一步会自动以 editable 方式安装同级目录的 jdgraphbuilder 包(见 pyproject.toml 的 [tool.uv.sources])。
Copy-Item .env.example .env编辑 .env,至少填好 Neo4j 连接与 LLM 密钥:
# Neo4j(如果 ../JDGraphBuilder/.env 已配好,本文件可省略 Neo4j 部分)
NEO4J_URI=neo4j+s://xxxxxx.databases.neo4j.io
NEO4J_USERNAME=xxxxxx
NEO4J_PASSWORD=xxxxxx
NEO4J_DATABASE=xxxxxx
# LLM(DeepSeek,OpenAI 兼容协议)
LLM_API_KEY=sk-xxxxxxxx
LLM_BASE_URL=https://api.deepseek.com
LLM_MODEL=deepseek-v4-pro # 已适配 thinking 模式;也可填 deepseek-chat
LLM_TEMPERATURE=0.3
LLM_MAX_TOOL_ROUNDS=6
LLM_REQUEST_TIMEOUT=60
# 服务端口
WOODLE_HOST=127.0.0.1
WOODLE_PORT=8000⚙️ 自动 fallback:
backend/config.py会先读取本项目.env,再读取../JDGraphBuilder/.env。 因此如果 Builder 那边已配好 Neo4j,可在 Mono 的.env中只配 LLM 相关变量。
uv run python -m backend.main --host 0.0.0.0 --port 8000
# 开发模式(热重载)
uv run python -m backend.main --reload访问:
- 前端页面:
http://127.0.0.1:8000/(会跳到/front/woodle_ai_home.html) - 健康检查:
http://127.0.0.1:8000/health - 图谱接口:
http://127.0.0.1:8000/api/graph?skill=Python&related_skill_limit=3&jobs_per_skill=2
参数:
| 参数 | 类型 | 默认 | 说明 |
|---|---|---|---|
skill |
string | 空 | 聚焦技能;若空则返回演示子图 |
related_skill_limit |
int (0–10) | 3 | 围绕聚焦技能展开的关联技能数量 |
jobs_per_skill |
int (1–10) | 2 | 每个技能展开的职位数量 |
返回(与原 serve.py 协议兼容,前端无需修改):
{
"nodes": [
{ "id": "skill:Python", "label": "Python", "type": "skill" },
{ "id": "job:ljx_02.txt", "label": "后台开发工程师", "type": "role", "matched": 1 }
],
"edges": [
{ "source": "job:ljx_02.txt", "target": "skill:Python", "label": "requires", "relation": "REQUIRES_SKILL" }
],
"meta": { "node_count": 2, "edge_count": 1 }
}无法连接 Neo4j 时返回 503。
请求体:
{
"question": "我会 Python 和 SQL,想转行做数据分析岗位,请基于图谱推荐 2 个合适的岗位",
"history": [
{ "role": "user", "content": "..." },
{ "role": "assistant", "content": "..." }
],
"debug": false
}| 字段 | 说明 |
|---|---|
question |
用户问题,1–4000 字符 |
history |
可选,最近若干轮对话(仅取 user / assistant 角色) |
debug |
为 true 时,响应附带 tool_trace(每次工具调用的名称/参数/结果预览) |
返回:
{
"answer": "## 推荐结果\n根据知识图谱数据……",
"tool_trace": [
{ "round": 0, "name": "find_jobs_by_skills", "args": {"skills":["Python","SQL"]}, "result_preview": "..." }
]
}未配置 LLM_API_KEY 时返回 503。
- 协议:原生 OpenAI Chat Completions
tools+tool_calls循环,不依赖 LangChain。 - 工具集(共 16 个,全部基于 JDGraphBuilder 的查询函数):
- 职位检索:
find_jobs_by_skills/find_jobs_by_location/find_jobs_by_education/get_job_detail - 技能分析:
get_top_skills/get_related_skills/get_skill_tree/get_skills_by_category - 个性化建议:
get_skill_gap/get_job_transition - 统计概览:
get_graph_overview/get_skill_distribution/get_location_distribution/get_education_distribution/get_category_distribution/get_skill_category_distribution
- 职位检索:
- 轮数上限:
LLM_MAX_TOOL_ROUNDS(默认 6),超出后强制总结。 - 结果截断:单次工具返回列表上限
MAX_TOOL_RESULT_ITEMS=20,防止 token 爆炸。 - DeepSeek thinking 模式:使用
deepseek-v4-pro时通过extra_body={"thinking": {"type": "enabled"}}+reasoning_effort="high"启用思考,并把响应中的reasoning_content在多轮调用之间正确回传;切换到deepseek-chat等非思考模型时这些参数会被服务端忽略。
| 现象 | 排查 |
|---|---|
/health 返回 llm_enabled: false |
.env 中没有设置 LLM_API_KEY |
/api/qa 返回 503 |
同上,或 LLM 服务商不可用 |
/api/graph 返回 503 |
Neo4j 连接失败,检查 .env 与远程 Neo4j 状态 |
启动日志 Neo4j 连接验证失败 |
URI / 用户名 / 密码错误,或 Aura 实例已暂停 |
QA 报 reasoning_content must be passed back |
使用了 DeepSeek thinking 模型但 SDK 版本过旧;升级 openai>=1.55 并使用最新版本的 runner.py |
┌──────────────────────┐ path-dep (editable) ┌────────────────────┐
│ JDGraphMono │ ──────────────────────────────────► │ JDGraphBuilder │
│ (本仓库) │ import src.query / src.loader … │ (库 + CLI) │
│ FastAPI + Agent │ │ 数据清洗 / 建模 / │
│ + 前端静态资源 │ │ 入库 / 查询函数 │
└──────────────────────┘ └────────────────────┘
│
▼
┌────────────┐
│ Neo4j │
└────────────┘
- 构建/导入图谱:去
JDGraphBuilder用uv run python -m src.cli.build --input data/input/_all.json --reset。 - 对外提供服务:在本仓库
uv run python -m backend.main。