Skip to content

Commit 7b2943f

Browse files
authored
Merge pull request #78 from chatchat-space/feature/supportChatBotPrompt
LLM 聊天机器人 支持在配置文件(prompt_settings.yaml)中自定义 prompt.
2 parents e666336 + 21f4a0e commit 7b2943f

File tree

3 files changed

+168
-151
lines changed

3 files changed

+168
-151
lines changed

chatchat-server/chatchat/server/agent/graphs_factory/base_graph.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from langchain_core.prompts import ChatPromptTemplate
12
from langchain_openai.chat_models import ChatOpenAI
23
from langchain_core.tools import BaseTool
34
from langchain_core.messages import BaseMessage, ToolMessage
@@ -7,6 +8,7 @@
78
from langgraph.prebuilt import ToolNode, tools_condition
89

910
from chatchat.server.utils import build_logger
11+
from chatchat.settings import Settings
1012
from .graphs_registry import State, register_graph, Graph
1113

1214
logger = build_logger()
@@ -24,7 +26,16 @@ def __init__(self,
2426
history_len: int,
2527
checkpoint: BaseCheckpointSaver):
2628
super().__init__(llm, tools, history_len, checkpoint)
27-
self.llm_with_tools = self.llm.bind_tools(self.tools)
29+
prompt = ChatPromptTemplate.from_messages(
30+
[
31+
(
32+
"system",
33+
Settings.prompt_settings.chatbot["default"],
34+
),
35+
("placeholder", "{history}"),
36+
]
37+
)
38+
self.llm_with_tools = prompt | self.llm.bind_tools(self.tools)
2839

2940
async def chatbot(self, state: State) -> State:
3041
# ToolNode 默认只将结果追加到 messages 队列中, 所以需要手动在 history 中追加 ToolMessage 结果, 否则报错如下:
@@ -40,7 +51,7 @@ async def chatbot(self, state: State) -> State:
4051
if isinstance(state["messages"][-1], ToolMessage):
4152
state["history"].append(state["messages"][-1])
4253

43-
messages = self.llm_with_tools.invoke(state["history"])
54+
messages = self.llm_with_tools.invoke(state)
4455
state["messages"] = [messages]
4556
# 因为 chatbot 执行依赖于 state["history"], 所以在同一次 workflow 没有执行结束前, 需要将每一次输出内容都追加到 state["history"] 队列中缓存起来
4657
state["history"].append(messages)

chatchat-server/chatchat/settings.py

Lines changed: 154 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -344,9 +344,9 @@ class ApiModelSettings(BaseFileSettings):
344344
DEFAULT_EMBEDDING_MODEL: str = "bge-large-zh-v1.5"
345345
"""默认选用的 Embedding 名称"""
346346

347-
HISTORY_LEN: int = 10
347+
HISTORY_LEN: int = 20
348348
"""默认历史对话轮数"""
349-
"""LangGraph Agent 单轮对话可能包含多个 Node, 故默认设置为 10"""
349+
"""LangGraph Agent 单轮对话可能包含多个 Node, 故默认设置为 20"""
350350

351351
MAX_TOKENS: t.Optional[int] = None # TODO: 似乎与 LLM_MODEL_CONFIG 重复了
352352
"""大模型最长支持的长度,如果不填写,则使用模型默认的最大长度,如果填写,则为用户设定的最大长度"""
@@ -683,159 +683,165 @@ class ToolSettings(BaseFileSettings):
683683

684684

685685
class PromptSettings(BaseFileSettings):
686-
"""Prompt 模板.除 Agent 模板使用 f-string 外,其它均使用 jinja2 格式"""
686+
"""Prompt 模板. {} 中内容均为 graph 调用时需传变量, 请不要随意增删改."""
687687

688688
model_config = SettingsConfigDict(yaml_file=CHATCHAT_ROOT / "prompt_settings.yaml",
689689
json_file=CHATCHAT_ROOT / "prompt_settings.json",
690690
extra="allow")
691691

692-
preprocess_model: dict = {
693-
"default": (
694-
"你只要回复0 和 1 ,代表不需要使用工具。以下几种问题不需要使用工具:\n"
695-
"1. 需要联网查询的内容\n"
696-
"2. 需要计算的内容\n"
697-
"3. 需要查询实时性的内容\n"
698-
"如果我的输入满足这几种情况,返回1。其他输入,请你回复0,你只要返回一个数字\n"
699-
"这是我的问题:"
700-
),
701-
}
702-
"""意图识别用模板"""
703-
704-
llm_model: dict = {
705-
"default": "{{input}}",
706-
"with_history": (
707-
"The following is a friendly conversation between a human and an AI.\n"
708-
"The AI is talkative and provides lots of specific details from its context.\n"
709-
"If the AI does not know the answer to a question, it truthfully says it does not know.\n\n"
710-
"Current conversation:\n"
711-
"{{history}}\n"
712-
"Human: {{input}}\n"
713-
"AI:"
714-
),
715-
}
716-
'''普通 LLM 用模板'''
717-
718-
rag: dict = {
719-
"default": (
720-
"【指令】根据已知信息,简洁和专业的来回答问题。"
721-
"如果无法从中得到答案,请说 “根据已知信息无法回答该问题”,不允许在答案中添加编造成分,答案请使用中文。\n\n"
722-
"【已知信息】{{context}}\n\n"
723-
"【问题】{{question}}\n"
724-
),
725-
"empty": (
726-
"请你回答我的问题:\n"
727-
"{{question}}"
728-
),
729-
}
730-
'''RAG 用模板,可用于知识库问答、文件对话、搜索引擎对话'''
731-
732-
action_model: dict = {
733-
"GPT-4": (
734-
"Answer the following questions as best you can. You have access to the following tools:\n"
735-
"The way you use the tools is by specifying a json blob.\n"
736-
"Specifically, this json should have a `action` key (with the name of the tool to use) and a `action_input` key (with the input to the tool going here).\n"
737-
'The only values that should be in the "action" field are: {tool_names}\n'
738-
"The $JSON_BLOB should only contain a SINGLE action, do NOT return a list of multiple actions. Here is an example of a valid $JSON_BLOB:\n"
739-
"```\n\n"
740-
"{{{{\n"
741-
' "action": $TOOL_NAME,\n'
742-
' "action_input": $INPUT\n'
743-
"}}}}\n"
744-
"```\n\n"
745-
"ALWAYS use the following format:\n"
746-
"Question: the input question you must answer\n"
747-
"Thought: you should always think about what to do\n"
748-
"Action:\n"
749-
"```\n\n"
750-
"$JSON_BLOB"
751-
"```\n\n"
752-
"Observation: the result of the action\n"
753-
"... (this Thought/Action/Observation can repeat N times)\n"
754-
"Thought: I now know the final answer\n"
755-
"Final Answer: the final answer to the original input question\n"
756-
"Begin! Reminder to always use the exact characters `Final Answer` when responding.\n"
757-
"Question:{input}\n"
758-
"Thought:{agent_scratchpad}\n"
759-
),
760-
"ChatGLM3": (
761-
"You can answer using the tools.Respond to the human as helpfully and accurately as possible.\n"
762-
"You have access to the following tools:\n"
763-
"{tools}\n"
764-
"Use a json blob to specify a tool by providing an action key (tool name)\n"
765-
"and an action_input key (tool input).\n"
766-
'Valid "action" values: "Final Answer" or [{tool_names}]\n'
767-
"Provide only ONE action per $JSON_BLOB, as shown:\n\n"
768-
"```\n"
769-
"{{{{\n"
770-
' "action": $TOOL_NAME,\n'
771-
' "action_input": $INPUT\n'
772-
"}}}}\n"
773-
"```\n\n"
774-
"Follow this format:\n\n"
775-
"Question: input question to answer\n"
776-
"Thought: consider previous and subsequent steps\n"
777-
"Action:\n"
778-
"```\n"
779-
"$JSON_BLOB\n"
780-
"```\n"
781-
"Observation: action result\n"
782-
"... (repeat Thought/Action/Observation N times)\n"
783-
"Thought: I know what to respond\n"
784-
"Action:\n"
785-
"```\n"
786-
"{{{{\n"
787-
' "action": "Final Answer",\n'
788-
' "action_input": "Final response to human"\n'
789-
"}}}}\n"
790-
"Begin! Reminder to ALWAYS respond with a valid json blob of a single action. Use tools if necessary.\n"
791-
"Respond directly if appropriate. Format is Action:```$JSON_BLOB```then Observation:.\n"
792-
"Question: {input}\n\n"
793-
"{agent_scratchpad}\n"
794-
),
795-
"qwen": (
796-
"Answer the following questions as best you can. You have access to the following APIs:\n\n"
797-
"{tools}\n\n"
798-
"Use the following format:\n\n"
799-
"Question: the input question you must answer\n"
800-
"Thought: you should always think about what to do\n"
801-
"Action: the action to take, should be one of [{tool_names}]\n"
802-
"Action Input: the input to the action\n"
803-
"Observation: the result of the action\n"
804-
"... (this Thought/Action/Action Input/Observation can be repeated zero or more times)\n"
805-
"Thought: I now know the final answer\n"
806-
"Final Answer: the final answer to the original input question\n\n"
807-
"Format the Action Input as a JSON object.\n\n"
808-
"Begin!\n\n"
809-
"Question: {input}\n\n"
810-
"{agent_scratchpad}\n\n"
811-
),
812-
"structured-chat-agent": (
813-
"Respond to the human as helpfully and accurately as possible. You have access to the following tools:\n\n"
814-
"{tools}\n\n"
815-
"Use a json blob to specify a tool by providing an action key (tool name) and an action_input key (tool input).\n\n"
816-
'Valid "action" values: "Final Answer" or {tool_names}\n\n'
817-
"Provide only ONE action per $JSON_BLOB, as shown:\n\n"
818-
'```\n{{\n "action": $TOOL_NAME,\n "action_input": $INPUT\n}}\n```\n\n'
819-
"Follow this format:\n\n"
820-
"Question: input question to answer\n"
821-
"Thought: consider previous and subsequent steps\n"
822-
"Action:\n```\n$JSON_BLOB\n```\n"
823-
"Observation: action result\n"
824-
"... (repeat Thought/Action/Observation N times)\n"
825-
"Thought: I know what to respond\n"
826-
'Action:\n```\n{{\n "action": "Final Answer",\n "action_input": "Final response to human"\n}}\n\n'
827-
"Begin! Reminder to ALWAYS respond with a valid json blob of a single action. Use tools if necessary. Respond directly if appropriate. Format is Action:```$JSON_BLOB```then Observation\n"
828-
"{input}\n\n"
829-
"{agent_scratchpad}\n\n"
830-
# '(reminder to respond in a JSON blob no matter what)')
831-
),
692+
# llm_model: dict = {
693+
# "default": "{{input}}",
694+
# "with_history": (
695+
# "The following is a friendly conversation between a human and an AI.\n"
696+
# "The AI is talkative and provides lots of specific details from its context.\n"
697+
# "If the AI does not know the answer to a question, it truthfully says it does not know.\n\n"
698+
# "Current conversation:\n"
699+
# "{{history}}\n"
700+
# "Human: {{input}}\n"
701+
# "AI:"
702+
# ),
703+
# }
704+
chatbot: t.Dict[str, str] = {
705+
"default": ("You're a helpful assistant.\n\n"
706+
"The chat history and user questions are as follows:\n"
707+
"{{history}}.")
832708
}
833-
"""Agent 模板"""
834709

835-
postprocess_model: dict = {
836-
"default": "{{input}}",
837-
}
838-
"""后处理模板"""
710+
'''聊天机器人用指令模板'''
711+
712+
# preprocess_model: dict = {
713+
# "default": (
714+
# "你只要回复0 和 1 ,代表不需要使用工具。以下几种问题不需要使用工具:\n"
715+
# "1. 需要联网查询的内容\n"
716+
# "2. 需要计算的内容\n"
717+
# "3. 需要查询实时性的内容\n"
718+
# "如果我的输入满足这几种情况,返回1。其他输入,请你回复0,你只要返回一个数字\n"
719+
# "这是我的问题:"
720+
# ),
721+
# }
722+
# """意图识别用模板"""
723+
724+
# rag: dict = {
725+
# "default": (
726+
# "【指令】根据已知信息,简洁和专业的来回答问题。"
727+
# "如果无法从中得到答案,请说 “根据已知信息无法回答该问题”,不允许在答案中添加编造成分,答案请使用中文。\n\n"
728+
# "【已知信息】{{context}}\n\n"
729+
# "【问题】{{question}}\n"
730+
# ),
731+
# "empty": (
732+
# "请你回答我的问题:\n"
733+
# "{{question}}"
734+
# ),
735+
# }
736+
# '''RAG 用模板,可用于知识库问答、文件对话、搜索引擎对话'''
737+
738+
# action_model: dict = {
739+
# "GPT-4": (
740+
# "Answer the following questions as best you can. You have access to the following tools:\n"
741+
# "The way you use the tools is by specifying a json blob.\n"
742+
# "Specifically, this json should have a `action` key (with the name of the tool to use) and a `action_input` key (with the input to the tool going here).\n"
743+
# 'The only values that should be in the "action" field are: {tool_names}\n'
744+
# "The $JSON_BLOB should only contain a SINGLE action, do NOT return a list of multiple actions. Here is an example of a valid $JSON_BLOB:\n"
745+
# "```\n\n"
746+
# "{{{{\n"
747+
# ' "action": $TOOL_NAME,\n'
748+
# ' "action_input": $INPUT\n'
749+
# "}}}}\n"
750+
# "```\n\n"
751+
# "ALWAYS use the following format:\n"
752+
# "Question: the input question you must answer\n"
753+
# "Thought: you should always think about what to do\n"
754+
# "Action:\n"
755+
# "```\n\n"
756+
# "$JSON_BLOB"
757+
# "```\n\n"
758+
# "Observation: the result of the action\n"
759+
# "... (this Thought/Action/Observation can repeat N times)\n"
760+
# "Thought: I now know the final answer\n"
761+
# "Final Answer: the final answer to the original input question\n"
762+
# "Begin! Reminder to always use the exact characters `Final Answer` when responding.\n"
763+
# "Question:{input}\n"
764+
# "Thought:{agent_scratchpad}\n"
765+
# ),
766+
# "ChatGLM3": (
767+
# "You can answer using the tools.Respond to the human as helpfully and accurately as possible.\n"
768+
# "You have access to the following tools:\n"
769+
# "{tools}\n"
770+
# "Use a json blob to specify a tool by providing an action key (tool name)\n"
771+
# "and an action_input key (tool input).\n"
772+
# 'Valid "action" values: "Final Answer" or [{tool_names}]\n'
773+
# "Provide only ONE action per $JSON_BLOB, as shown:\n\n"
774+
# "```\n"
775+
# "{{{{\n"
776+
# ' "action": $TOOL_NAME,\n'
777+
# ' "action_input": $INPUT\n'
778+
# "}}}}\n"
779+
# "```\n\n"
780+
# "Follow this format:\n\n"
781+
# "Question: input question to answer\n"
782+
# "Thought: consider previous and subsequent steps\n"
783+
# "Action:\n"
784+
# "```\n"
785+
# "$JSON_BLOB\n"
786+
# "```\n"
787+
# "Observation: action result\n"
788+
# "... (repeat Thought/Action/Observation N times)\n"
789+
# "Thought: I know what to respond\n"
790+
# "Action:\n"
791+
# "```\n"
792+
# "{{{{\n"
793+
# ' "action": "Final Answer",\n'
794+
# ' "action_input": "Final response to human"\n'
795+
# "}}}}\n"
796+
# "Begin! Reminder to ALWAYS respond with a valid json blob of a single action. Use tools if necessary.\n"
797+
# "Respond directly if appropriate. Format is Action:```$JSON_BLOB```then Observation:.\n"
798+
# "Question: {input}\n\n"
799+
# "{agent_scratchpad}\n"
800+
# ),
801+
# "qwen": (
802+
# "Answer the following questions as best you can. You have access to the following APIs:\n\n"
803+
# "{tools}\n\n"
804+
# "Use the following format:\n\n"
805+
# "Question: the input question you must answer\n"
806+
# "Thought: you should always think about what to do\n"
807+
# "Action: the action to take, should be one of [{tool_names}]\n"
808+
# "Action Input: the input to the action\n"
809+
# "Observation: the result of the action\n"
810+
# "... (this Thought/Action/Action Input/Observation can be repeated zero or more times)\n"
811+
# "Thought: I now know the final answer\n"
812+
# "Final Answer: the final answer to the original input question\n\n"
813+
# "Format the Action Input as a JSON object.\n\n"
814+
# "Begin!\n\n"
815+
# "Question: {input}\n\n"
816+
# "{agent_scratchpad}\n\n"
817+
# ),
818+
# "structured-chat-agent": (
819+
# "Respond to the human as helpfully and accurately as possible. You have access to the following tools:\n\n"
820+
# "{tools}\n\n"
821+
# "Use a json blob to specify a tool by providing an action key (tool name) and an action_input key (tool input).\n\n"
822+
# 'Valid "action" values: "Final Answer" or {tool_names}\n\n'
823+
# "Provide only ONE action per $JSON_BLOB, as shown:\n\n"
824+
# '```\n{{\n "action": $TOOL_NAME,\n "action_input": $INPUT\n}}\n```\n\n'
825+
# "Follow this format:\n\n"
826+
# "Question: input question to answer\n"
827+
# "Thought: consider previous and subsequent steps\n"
828+
# "Action:\n```\n$JSON_BLOB\n```\n"
829+
# "Observation: action result\n"
830+
# "... (repeat Thought/Action/Observation N times)\n"
831+
# "Thought: I know what to respond\n"
832+
# 'Action:\n```\n{{\n "action": "Final Answer",\n "action_input": "Final response to human"\n}}\n\n'
833+
# "Begin! Reminder to ALWAYS respond with a valid json blob of a single action. Use tools if necessary. Respond directly if appropriate. Format is Action:```$JSON_BLOB```then Observation\n"
834+
# "{input}\n\n"
835+
# "{agent_scratchpad}\n\n"
836+
# # '(reminder to respond in a JSON blob no matter what)')
837+
# ),
838+
# }
839+
# """Agent 模板"""
840+
841+
# postprocess_model: dict = {
842+
# "default": "{{input}}",
843+
# }
844+
# """后处理模板"""
839845

840846

841847
class SettingsContainer:

chatchat-server/chatchat/webui_pages/graph_rag/rag.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ def on_kb_change():
147147

148148
selected_tools_configs = list(selected_tool_configs)
149149

150-
st.title("知识库聊天")
150+
st.title("📖 知识库聊天")
151151
with st.chat_message(name="assistant", avatar=st.session_state["assistant_avatar"]):
152152
st.write("Hello 👋😊,我是智能知识库问答机器人,试着输入任何内容和我聊天呦~(ps: 可尝试切换不同知识库)")
153153

0 commit comments

Comments
 (0)