Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 工作流ai对话节点添加节点上下文 #1791

Merged
merged 1 commit into from
Dec 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ class ChatNodeSerializer(serializers.Serializer):

model_params_setting = serializers.DictField(required=False, error_messages=ErrMessage.integer("模型参数相关设置"))

dialogue_type = serializers.CharField(required=True, error_messages=ErrMessage.char("上下文类型"))


class IChatNode(INode):
type = 'ai-chat-node'
Expand All @@ -39,5 +41,6 @@ def _run(self):
def execute(self, model_id, system, prompt, dialogue_number, history_chat_record, stream, chat_id,
chat_record_id,
model_params_setting=None,
dialogue_type=None,
**kwargs) -> NodeResult:
pass
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

from django.db.models import QuerySet
from langchain.schema import HumanMessage, SystemMessage
from langchain_core.messages import BaseMessage
from langchain_core.messages import BaseMessage, AIMessage

from application.flow.i_step_node import NodeResult, INode
from application.flow.step_node.ai_chat_step_node.i_chat_node import IChatNode
Expand Down Expand Up @@ -72,6 +72,22 @@ def get_default_model_params_setting(model_id):
return model_params_setting


def get_node_message(chat_record, runtime_node_id):
node_details = chat_record.get_node_details_runtime_node_id(runtime_node_id)
if node_details is None:
return []
return [HumanMessage(node_details.get('question')), AIMessage(node_details.get('answer'))]


def get_workflow_message(chat_record):
return [chat_record.get_human_message(), chat_record.get_ai_message()]


def get_message(chat_record, dialogue_type, runtime_node_id):
return get_node_message(chat_record, runtime_node_id) if dialogue_type == 'NODE' else get_workflow_message(
chat_record)


class BaseChatNode(IChatNode):
def save_context(self, details, workflow_manage):
self.context['answer'] = details.get('answer')
Expand All @@ -80,12 +96,17 @@ def save_context(self, details, workflow_manage):

def execute(self, model_id, system, prompt, dialogue_number, history_chat_record, stream, chat_id, chat_record_id,
model_params_setting=None,
dialogue_type=None,
**kwargs) -> NodeResult:
if dialogue_type is None:
dialogue_type = 'WORKFLOW'

if model_params_setting is None:
model_params_setting = get_default_model_params_setting(model_id)
chat_model = get_model_instance_by_model_user_id(model_id, self.flow_params_serializer.data.get('user_id'),
**model_params_setting)
history_message = self.get_history_message(history_chat_record, dialogue_number)
history_message = self.get_history_message(history_chat_record, dialogue_number, dialogue_type,
self.runtime_node_id)
self.context['history_message'] = history_message
question = self.generate_prompt_question(prompt)
self.context['question'] = question.content
Expand All @@ -103,10 +124,10 @@ def execute(self, model_id, system, prompt, dialogue_number, history_chat_record
_write_context=write_context)

@staticmethod
def get_history_message(history_chat_record, dialogue_number):
def get_history_message(history_chat_record, dialogue_number, dialogue_type, runtime_node_id):
start_index = len(history_chat_record) - dialogue_number
history_message = reduce(lambda x, y: [*x, *y], [
[history_chat_record[index].get_human_message(), history_chat_record[index].get_ai_message()]
get_message(history_chat_record[index], dialogue_type, runtime_node_id)
for index in
range(start_index if start_index > 0 else 0, len(history_chat_record))], [])
return history_message
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个代码是针对聊天机器人模型进行的消息管理和对话状态管理。在分析过程中发现一些问题和可能需要关注的部分。下面是关于这个问题的答案:

  1. 错误的导入语句from django.db.models import QuerySet:这行应该被替换为 from langchain_core.messages import BaseMessage, AIMessage.

  2. 类继承部分

    • BaseChatNode 类中没有明确提及从哪个子类别继承(例如,它是否继承自任何其他模块或类)。
    • 如果是使用 Python 的面向对象设计,则建议实现一个统一的状态管理接口。
  3. 变量命名一致性的问题:函数内部有多个地方的变量名与外部文件中的定义不符合。

  4. 逻辑混乱

    • 消息队列处理的“stream”参数未正确引用到实际的数据源(如流式消息服务、数据库等),且调用模式不清晰。
  5. 流程简化

    • 在创建新的聊天节点时,在执行之前并未考虑是否应先生成必要的历史数据记录。
  6. 全局配置设置缺失/未使用的警告

    • 由于文档未能涵盖全局相关设置如何用于项目环境,请确保对全局配置选项的适当应用及监控是有意识地开展的,并及时修改以防止潜在影响项目的运行情况。

为了进一步改进这段代码,我建议采取以下措施来修复这些问题并提高整体质量和效率:

  • 完整地引入正确的导入语法和类型声明。
  • 强化类间的继承关系描述,使继承树更加清楚简洁。
  • 减少不必要的中间层级抽象,避免产生理解瓶颈。
  • 确保API出入保持一致和易于解析。
  • 应对不同的输入情况进行更详细的注释说明。
  • 尽量将相关的系统参数固定在一个单独的配置模块或其他集中存储区域。

最后还请注意测试不同场景下代码的行为,因为这些方面可能存在未知的需求和意外行为。

Expand Down
3 changes: 3 additions & 0 deletions apps/application/models/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,5 +167,8 @@ def get_human_message(self):
def get_ai_message(self):
return AIMessage(content=self.answer_text)

def get_node_details_runtime_node_id(self, runtime_node_id):
return self.details.get(runtime_node_id, None)

class Meta:
db_table = "application_chat_record"
9 changes: 7 additions & 2 deletions ui/src/workflow/common/NodeContainer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,8 @@
v-if="showAnchor"
@mousemove.stop
@mousedown.stop
@keydown.stop
@click.stop
@wheel.stop
@wheel="handleWheel"
:show="showAnchor"
:id="id"
style="left: 100%; top: 50%; transform: translate(0, -50%)"
Expand Down Expand Up @@ -142,6 +141,12 @@ const showNode = computed({
return true
}
})
const handleWheel = (event: any) => {
const isCombinationKeyPressed = event.ctrlKey || event.metaKey
if (!isCombinationKeyPressed) {
event.stopPropagation()
}
}
const node_status = computed(() => {
if (props.nodeModel.properties.status) {
return props.nodeModel.properties.status
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个代码片段可能有以下问题:

  1. 调整了鼠标事件处理的方法名称(从keydown.stop调整为handleWheel),这是一个较好的建议。
  2. 函数参数中的引号使用错误。应该使用双引号而不是单引号来定义函数参数,因为这样可以防止变量被误写成字符串。

其他方面没有发现明显的不规范或缺陷。但是如果有进一步的需求,比如希望更准确地实现某个特性或者添加新的功能,我可以在现有基础上提供详细的修改建议和说明。

Expand Down
12 changes: 11 additions & 1 deletion ui/src/workflow/nodes/ai-chat-node/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,15 @@
/>
</el-form-item>
<el-form-item label="历史聊天记录">
<template #label>
<div class="flex-between">
<div>历史聊天记录</div>
<el-select v-model="chat_data.dialogue_type" type="small" style="width: 100px">
<el-option label="节点" value="NODE" />
<el-option label="工作流" value="WORKFLOW" />
</el-select>
</div>
</template>
<el-input-number
v-model="chat_data.dialogue_number"
:min="0"
Expand Down Expand Up @@ -246,7 +255,8 @@ const form = {
dialogue_number: 1,
is_result: false,
temperature: null,
max_tokens: null
max_tokens: null,
dialogue_type: 'WORKFLOW'
}

const chat_data = computed({
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

以下是针对给定代码的反馈:

  1. @@符号在JavaScript中是占位符,用于表示行号。它们不应该出现在实际代码中。
  2. 在HTML模板标签内不应设置额外属性或值(如:<div class="my-class">) 来自定义元素的样式或行为。

对于优化与改进:

  • 标签名 (# label 类似) 需要放在正确的位置,并且需要遵循 HTML命名空间规则以确保正确的语法。
  • 良好的编码习惯和一致性应该被保持。例如,在字符串中的引号应该始终为双引号 ("").
  • 只有当必要时才使用保留字或其他关键字。通常不需要重复声明变量。

此外,为了简化代码结构并提高可读性和组织性,请考虑将两个组件合并到一个更简化的ChatMessageForm.vue,以便更容易地进行修改和维护。这样的重构可以包括将输入控件移到单独的新层中:如果想进一步减少复杂度,则还可以通过增加子组件来实现这一步骤。

最后,对所有类型的错误进行调试有助于发现可能存在的问题并及时修正。希望以上改进建议能帮助你提升编程效率和质量!

Expand Down
Loading