Skip to content

Commit a8491c5

Browse files
committed
feat: 使用 create_agent 接口替换老版本的 create_react_agent
1 parent fdc4f17 commit a8491c5

File tree

6 files changed

+54
-42
lines changed

6 files changed

+54
-42
lines changed

docs/changelog/roadmap.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,13 @@
1111

1212
## Next
1313

14-
- [ ] 修改现有的智能体Demo,并尽量将默认助手的特性兼容到 LangGraph 的 [`create_agent`](https://docs.langchain.com/oss/python/langchain/agents)
14+
- [x] 修改现有的智能体Demo,并尽量将默认助手的特性兼容到 LangGraph 的 [`create_agent`](https://docs.langchain.com/oss/python/langchain/agents)
1515
- [ ] 基于 create_agent 创建 SQL Viewer 智能体 <Badge type="info" text="0.3.5" />
1616
- [ ] 优化 MCP 逻辑,支持 common + special 创建方式 <Badge type="info" text="0.3.5" />
1717
- [ ] 添加对于上传文件的支持
1818
- [ ] 统一图谱数据结构,优化可视化方式 [#298](https://github.com/xerrors/Yuxi-Know/issues/298) <Badge type="info" text="0.4" />
1919
- [ ] 集成智能体评估,首先使用命令行来实现,然后考虑放在 UI 里面展示
2020
- [ ] 开发与生产环境隔离,构建生产镜像 <Badge type="info" text="0.4" />
21-
- [x] 支持 MinerU 2.5 的解析方法 <Badge type="info" text="0.3.5" />
22-
- [x] 文件管理:(1)文件选择的时候会跨数据库;(2)文件校验会算上失败的文件;
23-
- [x] Tasker 中获取历史任务的时候,仅获取 top100 个 task。
2421

2522

2623
## Later
@@ -37,3 +34,6 @@
3734
- [x] 优化对文档信息的检索展示(检索结果页、详情页)
3835
- [x] 当前 ReAct 智能体有消息顺序错乱的 bug,且不会默认调用工具
3936
- [x] 优化全局配置的管理模型,优化配置管理
37+
- [x] 支持 MinerU 2.5 的解析方法 <Badge type="info" text="0.3.5" />
38+
- [x] 文件管理:(1)文件选择的时候会跨数据库;(2)文件校验会算上失败的文件;
39+
- [x] Tasker 中获取历史任务的时候,仅获取 top100 个 task。

src/agents/chatbot/context.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,6 @@
1010

1111
@dataclass(kw_only=True)
1212
class Context(BaseContext):
13-
model: Annotated[str, {"__template_metadata__": {"kind": "llm"}}] = field(
14-
default="siliconflow/Qwen/Qwen3-235B-A22B-Instruct-2507",
15-
metadata={"name": "智能体模型", "options": [], "description": "智能体的驱动模型"},
16-
)
17-
1813
tools: Annotated[list[dict], {"__template_metadata__": {"kind": "tools"}}] = field(
1914
default_factory=list,
2015
metadata={

src/agents/common/context.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
"""Define the configurable parameters for the agent."""
22

3-
from __future__ import annotations
4-
53
import os
64
import uuid
75
from dataclasses import MISSING, dataclass, field, fields
86
from pathlib import Path
9-
from typing import get_args, get_origin
7+
from typing import Annotated, get_args, get_origin
108

119
import yaml
1210

@@ -46,8 +44,13 @@ def update(self, data: dict):
4644
metadata={"name": "系统提示词", "description": "用来描述智能体的角色和行为"},
4745
)
4846

47+
model: Annotated[str, {"__template_metadata__": {"kind": "llm"}}] = field(
48+
default="siliconflow/Qwen/Qwen3-235B-A22B-Instruct-2507",
49+
metadata={"name": "智能体模型", "options": [], "description": "智能体的驱动模型"},
50+
)
51+
4952
@classmethod
50-
def from_file(cls, module_name: str, input_context: dict = None) -> BaseContext:
53+
def from_file(cls, module_name: str, input_context: dict = None) -> "BaseContext":
5154
"""Load configuration from a YAML file. 用于持久化配置"""
5255

5356
# 从文件加载配置

src/agents/react/graph.py

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,35 @@
11
from pathlib import Path
22

3-
from langchain.messages import AnyMessage, SystemMessage
4-
from langgraph.prebuilt import create_react_agent
5-
from langgraph.runtime import get_runtime
3+
from langchain.agents import create_agent
4+
from langchain.agents.middleware import ModelRequest, ModelResponse, dynamic_prompt, wrap_model_call
65

76
from src import config as sys_config
87
from src.agents.common.base import BaseAgent
9-
from src.agents.common.context import BaseContext
108
from src.agents.common.models import load_chat_model
119
from src.agents.common.tools import get_buildin_tools
1210
from src.utils import logger
1311

1412
model = load_chat_model("siliconflow/Qwen/Qwen3-235B-A22B-Instruct-2507")
1513

1614

17-
def prompt(state) -> list[AnyMessage]:
18-
runtime = get_runtime(BaseContext)
19-
system_msg = SystemMessage(content=runtime.context.system_prompt)
20-
return [system_msg] + state["messages"]
15+
@dynamic_prompt
16+
def context_aware_prompt(request: ModelRequest) -> str:
17+
runtime = request.runtime
18+
return runtime.context.system_prompt
19+
20+
21+
@wrap_model_call
22+
async def context_based_model(request: ModelRequest, handler) -> ModelResponse:
23+
# 从 runtime context 读取配置
24+
model_spec = request.runtime.context.model
25+
model = load_chat_model(model_spec)
26+
27+
request = request.override(model=model)
28+
return await handler(request)
2129

2230

2331
class ReActAgent(BaseAgent):
24-
name = "ReAct (all tools)"
32+
name = "智能体 Demo"
2533
description = "A react agent that can answer questions and help with tasks."
2634

2735
def __init__(self, **kwargs):
@@ -30,15 +38,21 @@ def __init__(self, **kwargs):
3038
self.workdir = Path(sys_config.save_dir) / "agents" / self.module_name
3139
self.workdir.mkdir(parents=True, exist_ok=True)
3240

41+
def get_tools(self):
42+
return get_buildin_tools()
43+
3344
async def get_graph(self, **kwargs):
3445
if self.graph:
3546
return self.graph
3647

37-
available_tools = get_buildin_tools()
38-
self.checkpointer = await self._get_checkpointer()
39-
4048
# 创建 ReActAgent
41-
graph = create_react_agent(model, tools=available_tools, prompt=prompt, checkpointer=self.checkpointer)
49+
graph = create_agent(
50+
model=model,
51+
tools=self.get_tools(),
52+
middleware=[context_aware_prompt, context_based_model],
53+
checkpointer=await self._get_checkpointer(),
54+
)
55+
4256
self.graph = graph
4357
logger.info("ReActAgent 使用内存 checkpointer 构建成功")
4458
return graph

src/knowledge/manager.py

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -46,21 +46,21 @@ def __init__(self, work_dir: str):
4646
logger.info("KnowledgeBaseManager initialized")
4747

4848
# 在后台运行数据一致性检测(不阻塞初始化)
49-
try:
50-
# 尝试获取当前事件循环,如果没有则创建新的
51-
try:
52-
loop = asyncio.get_event_loop()
53-
if loop.is_running():
54-
# 如果已经在事件循环中,创建任务
55-
asyncio.create_task(self.detect_data_inconsistencies())
56-
else:
57-
# 如果事件循环未运行,直接运行
58-
loop.run_until_complete(self.detect_data_inconsistencies())
59-
except RuntimeError:
60-
# 没有事件循环,创建一个来运行检测
61-
asyncio.run(self.detect_data_inconsistencies())
62-
except Exception as e:
63-
logger.warning(f"初始化时运行数据一致性检测失败: {e}")
49+
# try:
50+
# # 尝试获取当前事件循环,如果没有则创建新的
51+
# try:
52+
# loop = asyncio.get_event_loop()
53+
# if loop.is_running():
54+
# # 如果已经在事件循环中,创建任务
55+
# asyncio.create_task(self.detect_data_inconsistencies())
56+
# else:
57+
# # 如果事件循环未运行,直接运行
58+
# loop.run_until_complete(self.detect_data_inconsistencies())
59+
# except RuntimeError:
60+
# # 没有事件循环,创建一个来运行检测
61+
# asyncio.run(self.detect_data_inconsistencies())
62+
# except Exception as e:
63+
# logger.warning(f"初始化时运行数据一致性检测失败: {e}")
6464

6565
def _load_global_metadata(self):
6666
"""加载全局元数据"""

web/src/components/AgentConfigSidebar.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
<!-- 侧边栏内容 -->
1919
<div class="sidebar-content">
2020
<div class="agent-info" v-if="selectedAgent">
21-
<div class="agent-basic-info">
21+
<div class="agent-basic-info" @click="console.log(configurableItems)">
2222
<p class="agent-description">{{ selectedAgent.description }}</p>
2323
</div>
2424

0 commit comments

Comments
 (0)