Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
L
LAE
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
文靖昊
LAE
Commits
47159811
Commit
47159811
authored
Jul 11, 2024
by
文靖昊
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin/geo' into geo
parents
2f91a0b0
742a99a2
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
282 additions
and
7 deletions
+282
-7
tool_divisions.py
src/agent/tool_divisions.py
+154
-0
prompts.py
src/config/prompts.py
+4
-6
agent.py
src/server/agent.py
+30
-0
agent_test.py
test/agent_test.py
+93
-0
rag_test.py
test/rag_test.py
+1
-1
No files found.
src/agent/tool_divisions.py
0 → 100644
View file @
47159811
divisions
=
[
{
"province"
:
"青海省"
,
"cities"
:
[
{
"name"
:
"西宁市"
,
"counties"
:
[
"城东区"
,
"城中区"
,
"城西区"
,
"城北区"
,
"大通回族土族自治县"
,
"湟中区"
,
"湟源县"
]
},
{
"name"
:
"海东市"
,
"counties"
:
[
"乐都区"
,
"平安区"
,
"民和回族土族自治县"
,
"互助土族自治县"
,
"化隆回族自治县"
,
"循化撒拉族自治县"
]
},
{
"name"
:
"海北藏族自治州"
,
"counties"
:
[
"门源回族自治县"
,
"祁连县"
,
"海晏县"
,
"刚察县"
]
},
{
"name"
:
"黄南藏族自治州"
,
"counties"
:
[
"同仁市"
,
"尖扎县"
,
"泽库县"
,
"河南蒙古族自治县"
]
},
{
"name"
:
"海南藏族自治州"
,
"counties"
:
[
"共和县"
,
"同德县"
,
"贵德县"
,
"兴海县"
,
"贵南县"
]
},
{
"name"
:
"果洛藏族自治州"
,
"counties"
:
[
"玛沁县"
,
"班玛县"
,
"甘德县"
,
"达日县"
,
"久治县"
,
"玛多县"
]
},
{
"name"
:
"玉树藏族自治州"
,
"counties"
:
[
"玉树市"
,
"杂多县"
,
"称多县"
,
"治多县"
,
"囊谦县"
,
"曲麻莱县"
]
},
{
"name"
:
"海西蒙古族藏族自治州"
,
"counties"
:
[
"格尔木市"
,
"德令哈市"
,
"茫崖市"
,
"乌兰县"
,
"都兰县"
,
"天峻县"
]
}
]
},
{
"province"
:
"甘肃省"
,
"cities"
:
[
{
"name"
:
"兰州市"
,
"counties"
:
[
"城关区"
,
"七里河区"
,
"西固区"
,
"安宁区"
,
"红古区"
,
"永登县"
,
"皋兰县"
,
"榆中县"
]
},
{
"name"
:
"嘉峪关市"
,
"counties"
:
[
"嘉峪关市"
]
},
{
"name"
:
"金昌市"
,
"counties"
:
[
"金川区"
,
"永昌县"
]
},
{
"name"
:
"白银市"
,
"counties"
:
[
"白银区"
,
"平川区"
,
"靖远县"
,
"会宁县"
,
"景泰县"
]
},
{
"name"
:
"天水市"
,
"counties"
:
[
"秦州区"
,
"麦积区"
,
"清水县"
,
"秦安县"
,
"甘谷县"
,
"武山县"
,
"张家川回族自治县"
]
},
{
"name"
:
"武威市"
,
"counties"
:
[
"凉州区"
,
"民勤县"
,
"古浪县"
,
"天祝藏族自治县"
]
},
{
"name"
:
"张掖市"
,
"counties"
:
[
"甘州区"
,
"肃南裕固族自治县"
,
"民乐县"
,
"临泽县"
,
"高台县"
,
"山丹县"
]
},
{
"name"
:
"平凉市"
,
"counties"
:
[
"崆峒区"
,
"泾川县"
,
"灵台县"
,
"崇信县"
,
"华亭市"
,
"庄浪县"
,
"静宁县"
]
},
{
"name"
:
"酒泉市"
,
"counties"
:
[
"肃州区"
,
"金塔县"
,
"瓜州县"
,
"肃北蒙古族自治县"
,
"阿克塞哈萨克族自治县"
,
"玉门市"
,
"敦煌市"
]
},
{
"name"
:
"庆阳市"
,
"counties"
:
[
"西峰区"
,
"庆城县"
,
"环县"
,
"华池县"
,
"合水县"
,
"正宁县"
,
"宁县"
,
"镇原县"
]
},
{
"name"
:
"定西市"
,
"counties"
:
[
"安定区"
,
"通渭县"
,
"陇西县"
,
"渭源县"
,
"临洮县"
,
"漳县"
,
"岷县"
]
},
{
"name"
:
"陇南市"
,
"counties"
:
[
"武都区"
,
"成县"
,
"文县"
,
"宕昌县"
,
"康县"
,
"西和县"
,
"礼县"
,
"徽县"
,
"两当县"
]
},
{
"name"
:
"临夏回族自治州"
,
"counties"
:
[
"临夏市"
,
"临夏县"
,
"康乐县"
,
"永靖县"
,
"广河县"
,
"和政县"
,
"东乡族自治县"
,
"积石山保安族东乡族撒拉族自治县"
]
},
{
"name"
:
"甘南藏族自治州"
,
"counties"
:
[
"合作市"
,
"临潭县"
,
"卓尼县"
,
"舟曲县"
,
"迭部县"
,
"玛曲县"
,
"碌曲县"
,
"夏河县"
]
}
]
}
]
from
typing
import
Type
from
pydantic
import
BaseModel
,
Field
from
langchain_core.tools
import
BaseTool
# 根据输入补全行政区划信息
def
complete_administrative_division
(
input_text
,
data
):
for
province
in
data
:
if
input_text
in
province
[
'province'
]:
return
{
'province'
:
province
[
'province'
],
'cities'
:
[
city
[
'name'
]
for
city
in
province
[
'cities'
]]}
for
city
in
province
[
'cities'
]:
if
input_text
in
city
[
'name'
]:
return
{
'省'
:
province
[
'province'
],
'市'
:
city
[
'name'
],
'县(区)'
:
city
[
'counties'
]
}
for
county
in
city
[
'counties'
]:
if
input_text
in
county
:
return
{
'省'
:
province
[
'province'
],
'市'
:
city
[
'name'
],
'县(区)'
:
county
}
return
None
class
AdministrativeDivisionArgs
(
BaseModel
):
input_text
:
str
=
Field
(
...
,
description
=
"输入的行政区划信息,可以是省、市、县(区)三级中的最低一级的行政区划名称,例如用户输入'广东省广州市',则此参数只需要取'广州市',用户输入'武汉市洪山区',则次参数为'洪山区'"
)
class
AdministrativeDivision
(
BaseTool
):
name
=
"administrative_division"
description
=
"根据输入补全行政区划信息,明确具体的省、市、县信息。比如输入县,补全所属省市,输入市则补全省级以及下辖所有县区"
args_schema
:
Type
[
BaseModel
]
=
AdministrativeDivisionArgs
def
_run
(
self
,
input_text
:
str
)
->
str
:
result
=
complete_administrative_division
(
input_text
,
divisions
)
return
result
class
CountryInfoArgs
(
BaseModel
):
country
:
str
=
Field
(
...
,
description
=
"县(区)这个级别的行政区划名称"
)
# fake tool for testing
class
CountryInfo
(
BaseTool
):
name
=
"country_info"
description
=
"查询特定县(区)相关的地质情况"
args_schema
:
Type
[
BaseModel
]
=
CountryInfoArgs
def
_run
(
self
,
country
:
str
)
->
str
:
return
f
"{country} 的地质情况是:xxxxxx"
\ No newline at end of file
src/config/prompts.py
View file @
47159811
...
...
@@ -45,7 +45,7 @@ PROMPT_AGENT_HUMAN = """{input}\n\n{agent_scratchpad}\n (请注意,无论如
##################################################################################################################
# 结合历史对话信息,对用户提问进行扩展,生成不同角度的多个提问。用于 RAG 场景中
PROMPT_QUERY_EXTEND
=
"""作为一个向量检索助手,你的任务是结合历史记录,从不同角度,为“原问题”生成三个不同版本的“检索词”,从而提高向量检索的语义丰富度,提高向量检索的精度。生成的问题要求指向对象清晰明确,并与“原问题语言相同”。例如:
PROMPT_QUERY_EXTEND
=
"""作为一个向量检索助手,你的任务是结合历史记录,从不同角度,为“原问题”生成三个不同版本的“检索词”,从而提高向量检索的语义丰富度,提高向量检索的精度。生成的问题要求指向对象清晰明确,并与“原问题语言相同”。
如果问题中包含多个问询对象,可以将其拆分为多个问题。
例如:
历史记录:
'''
'''
...
...
@@ -67,7 +67,7 @@ A: 当前对话是关于 Nginx 的介绍和使用等。
Q: 报错 "no connection"
A: 报错"no connection"可能是因为……
'''
原问题: 怎么解决
原问题:
这是什么原因要
怎么解决
检索词: ["Nginx报错"no connection"如何解决?","造成'no connection'报错的原因。","Nginx提示'no connection',要怎么办?"]
----------------
历史记录:
...
...
@@ -96,11 +96,9 @@ A: 关于 FatGPT 的介绍和使用等问题。
----------------
历史记录:
'''
Q: FastGPT 如何收费?
A: FastGPT 收费可以参考……
'''
原问题:
你知道 laf 么
?
检索词: ["
laf 的官网地址是多少?","laf 的使用教程。","laf 有什么特点和优势。
"]
原问题:
北京和上海那个天气好
?
检索词: ["
北京的天气情况如何","上海的天气情况如何","北京和上海的天气那个更舒适
"]
----------------
历史记录:
'''
...
...
src/server/agent.py
0 → 100644
View file @
47159811
from
typing
import
Any
,
List
from
langchain_core.prompts
import
PromptTemplate
from
langchain.agents
import
AgentExecutor
,
create_tool_calling_agent
,
create_structured_chat_agent
from
langchain.tools
import
BaseTool
from
langgraph.prebuilt
import
create_react_agent
class
Agent
:
def
__init__
(
self
,
llm
,
tools
:
List
[
BaseTool
],
prompt
:
PromptTemplate
=
None
,
verbose
:
bool
=
False
):
self
.
llm
=
llm
self
.
tools
=
tools
self
.
prompt
=
prompt
if
not
prompt
:
agent
=
create_react_agent
(
llm
,
tools
,
debug
=
verbose
)
self
.
agent_executor
=
agent
else
:
agent
=
create_structured_chat_agent
(
llm
,
tools
,
prompt
)
self
.
agent_executor
=
AgentExecutor
(
agent
=
agent
,
tools
=
tools
,
verbose
=
verbose
)
def
exec
(
self
,
prompt_args
:
dict
=
{},
stream
:
bool
=
False
):
# if stream:
# for step in self.agent_executor.stream(prompt_args):
# yield step
return
self
.
agent_executor
.
invoke
(
input
=
prompt_args
)
def
stream
(
self
,
prompt_args
:
dict
=
{}):
for
step
in
self
.
agent_executor
.
stream
(
prompt_args
):
yield
step
\ No newline at end of file
test/agent_test.py
0 → 100644
View file @
47159811
import
sys
,
os
sys
.
path
.
append
(
"../"
)
from
typing
import
List
,
Union
,
Type
,
Optional
from
langchain
import
hub
import
langchain_core
from
langchain_core.tools
import
tool
,
BaseTool
from
langchain_core.prompts
import
ChatPromptTemplate
,
PromptTemplate
from
langchain_core.prompts.chat
import
ChatPromptTemplate
,
HumanMessagePromptTemplate
,
SystemMessagePromptTemplate
,
MessagesPlaceholder
from
langchain_core.callbacks
import
CallbackManagerForToolRun
from
langchain_openai
import
ChatOpenAI
from
langchain_openai.embeddings
import
OpenAIEmbeddings
from
langchain.agents
import
AgentExecutor
,
create_tool_calling_agent
,
create_structured_chat_agent
from
pydantic
import
BaseModel
,
Field
from
src.server.agent
import
Agent
from
src.config.prompts
import
PROMPT_AGENT_SYS
,
PROMPT_AGENT_HUMAN
from
src.agent.tool_divisions
import
AdministrativeDivision
,
CountryInfo
class
CalcInput
(
BaseModel
):
a
:
int
=
Field
(
...
,
description
=
"第一个数"
)
b
:
int
=
Field
(
...
,
description
=
"第二个数"
)
class
Calc
(
BaseTool
):
name
=
"calc"
description
=
"一个简单的计算工具,可以计算两个数的和"
args_schema
:
Type
[
BaseModel
]
=
CalcInput
def
_run
(
self
,
a
:
int
,
b
:
int
,
run_manager
:
Optional
[
CallbackManagerForToolRun
]
=
None
)
->
str
:
"""Use the tool."""
print
(
f
"Calculating {a} + {b}"
)
return
a
+
b
tools
=
[
AdministrativeDivision
()]
llm
=
ChatOpenAI
(
openai_api_key
=
'xxxxxxxxxxxxx'
,
openai_api_base
=
'http://192.168.10.14:8000/v1'
,
# openai_api_base='https://127.0.0.1:8000/v1',
model_name
=
'Qwen2-7B'
,
verbose
=
True
,
temperature
=
0
,
)
# prompt = hub.pull("hwchase17/openai-functions-agent")
input_variables
=
[
'agent_scratchpad'
,
'input'
,
'tool_names'
,
'tools'
]
input_types
=
{
'chat_history'
:
List
[
Union
[
langchain_core
.
messages
.
ai
.
AIMessage
,
langchain_core
.
messages
.
human
.
HumanMessage
,
langchain_core
.
messages
.
chat
.
ChatMessage
,
langchain_core
.
messages
.
system
.
SystemMessage
,
langchain_core
.
messages
.
function
.
FunctionMessage
,
langchain_core
.
messages
.
tool
.
ToolMessage
]]}
messages
=
[
SystemMessagePromptTemplate
(
prompt
=
PromptTemplate
(
input_variables
=
[
'tool_names'
,
'tools'
],
template
=
PROMPT_AGENT_SYS
)),
MessagesPlaceholder
(
variable_name
=
'chat_history'
,
optional
=
True
),
HumanMessagePromptTemplate
(
prompt
=
PromptTemplate
(
input_variables
=
[
'agent_scratchpad'
,
'input'
],
template
=
PROMPT_AGENT_HUMAN
))
]
prompt
=
ChatPromptTemplate
(
input_variables
=
input_variables
,
input_types
=
input_types
,
messages
=
messages
)
def
test_add
():
tools
=
[
Calc
()]
agent
=
Agent
(
llm
=
llm
,
tools
=
tools
,
prompt
=
prompt
,
verbose
=
True
)
res
=
agent
.
exec
(
prompt_args
=
{
"input"
:
"what is 1 + 1?"
})
# agent = create_structured_chat_agent(llm, tools, prompt)
# agent_executor = AgentExecutor(agent=agent,tools=tools,verbose=True,handle_parsing_errors=True)
# res = agent_executor.invoke(input={"input": "what is 1 + 1?"})
# print(res)
# for step in agent.stream(prompt_args={"input": "what is 1 + 1?"}):
# print("== step ==")
# print(step)
def
test_agent_division
():
tools
=
[
AdministrativeDivision
(),
CountryInfo
()]
agent
=
Agent
(
llm
=
llm
,
tools
=
tools
,
prompt
=
prompt
,
verbose
=
True
)
res
=
agent
.
exec
(
prompt_args
=
{
"input"
:
"我想知道陇南市西和县和文县的降雨量谁的多"
})
print
(
res
)
if
__name__
==
"__main__"
:
test_agent_division
()
\ No newline at end of file
test/rag_test.py
View file @
47159811
...
...
@@ -29,7 +29,7 @@ def test_qaext():
def
test_chatextend
():
ext
=
ChatExtend
(
base_llm
)
message
=
[
(
"
我们明天去爬山吧"
,
"好呀
"
),
(
"
明天去爬山怎么样"
,
"好主意
"
),
(
"天气怎么样"
,
"天气晴朗"
),
]
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment