我正在使用聊天机器人,我想将聊天机器人模型链接到Web UI(index.html)。我是烧瓶和python的新手。我需要从Web界面获取用户输入,并将其作为“ user_input”发送到模型。然后,我需要获取响应“ answer”,并将user_input和answer作为POST发送到新呈现的index.html中。由于答案是在while循环内生成的,因此我仍然无法在运行while循环的同时将其作为POST请求发送。在此while循环内使用user_input生成答案。
def chatbot(net, sess, chars, vocab, max_length, beam_width, relevance, temperature, topn):
states = initial_state_with_relevance_masking(net, sess, relevance)
user_input = ''
answer = ''
app = Flask(__name__)
@app.route('/home')
def index():
return render_template('index.html')
if __name__ == '__main__':
app.run(debug=True)
while True:
@app.route('/process',methods=['POST'])
def process():
user_input=request.form['user_input']
return user_input, render_template('index.html', user_input=user_input)
#return render_template('index.html', user_input=user_input)
if user_input == 'GoodBye':
break
user_command_entered, reset, states, relevance, temperature, topn, beam_width = process_user_command(
user_input, states, relevance, temperature, topn, beam_width)
if reset: states = initial_state_with_relevance_masking(net, sess, relevance)
if not user_command_entered:
states = forward_text(net, sess, states, relevance, vocab, sanitize_text(vocab, "> " + user_input + "\n>"))
computer_response_generator = beam_search_generator(sess=sess, net=net,
initial_state=copy.deepcopy(states), initial_sample=vocab[' '],
early_term_token=vocab['\n'], beam_width=beam_width, forward_model_fn=forward_with_mask,
forward_args={'relevance':relevance, 'mask_reset_token':vocab['\n'], 'forbidden_token':vocab['>'],
'temperature':temperature, 'topn':topn})
out_chars = []
for i, char_token in enumerate(computer_response_generator):
out_chars.append(chars[char_token])
#print(possibly_escaped_char(out_chars), end='', flush=True)
states = forward_text(net, sess, states, relevance, vocab, chars[char_token])
if i >= max_length: break
answer = ''.join(out_chars)
print('Bot:' + answer)
states = forward_text(net, sess, states, relevance, vocab, sanitize_text(vocab, "\n> "))
下面是index.html的HTML代码
<!DOCTYPE html>
<html>
<head>
<title>Friend Chatbot</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
</head>
<body>
<div class="container">
<div class="alert alert-primary" role="alert">
User: {{user_input}}
</div>
<div class="alert alert-dark" role="alert">
Freind: {{answer}}
</div>
<form action="/process" method="POST">
<div class="form-group">
<label for="exampleInputEmail1">Friend Chatbot</label>
<input type="text" name="user_input" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" placeholder="Talk to my friend"><br>
<button type="submit" class="btn btn-primary">Send</button>
</form>
</div>
</body>
</html>
我希望在POST请求中同时获取user_input和index.html网页的答案,而while循环中的每一次重复。我试图将POST烧瓶方法放入while循环内,但是它不起作用。我该如何实现?
答案 0 :(得分:0)
我可以在这里看到几个问题:
首先,它可能比将生成响应的责任和处理Web请求的任务混合在一起的方法更令人困惑。因此,我们将拆分聊天机器人部分:
def get_chatbot(net, sess, chars, vocab, max_length, beam_width, relevance, temperature, topn):
states = initial_state_with_relevance_masking(net, sess, relevance)
def get_response(user_input):
nonlocal states
if user_input == 'GoodBye':
# What do we expect to happen here?
return
user_command_entered, reset, states, relevance, temperature, topn, beam_width = process_user_command(
user_input, states, relevance, temperature, topn, beam_width)
if reset:
states = initial_state_with_relevance_masking(net, sess, relevance)
if not user_command_entered:
states = forward_text(net, sess, states, relevance, vocab, sanitize_text(vocab, "> " + user_input + "\n>"))
computer_response_generator = beam_search_generator(sess=sess, net=net,
initial_state=copy.deepcopy(states), initial_sample=vocab[' '],
early_term_token=vocab['\n'], beam_width=beam_width, forward_model_fn=forward_with_mask,
forward_args={'relevance':relevance, 'mask_reset_token':vocab['\n'], 'forbidden_token':vocab['>'],
'temperature':temperature, 'topn':topn})
out_chars = []
for i, char_token in enumerate(computer_response_generator):
out_chars.append(chars[char_token])
#print(possibly_escaped_char(out_chars), end='', flush=True)
states = forward_text(net, sess, states, relevance, vocab, chars[char_token])
if i >= max_length: break
states = forward_text(net, sess, states, relevance, vocab, sanitize_text(vocab, "\n> "))
return ''.join(out_chars)
return get_response
此函数返回一个函数,该函数将接受用户输入并提供答案。当它围绕状态和其他变量形成闭包时,它将记住所有的args和先前的状态。 (看起来确实如此,这似乎更像是class
的候选人)。
现在,我们可以担心需要单独提供Web内容:
app = Flask(__name__)
chatbot = get_chatbot(... args here ...)
@app.route('/home')
def index():
return render_template('index.html')
@app.route('/process', methods=['POST'])
def process():
user_input = request.form['user_input']
answer = chatbot(user_input)
if answer is None:
# Really do you want to bail out here?
exit()
return user_input, render_template(
'index.html', user_input=user_input, answer=answer)
if __name__ == '__main__':
app.run(debug=True)
请注意,process()
函数之外的所有代码现在都可以通过调用chatbot()
在其内部执行。这是您看不到任何输出的主要原因。
那么循环在哪里去了?运行良好的烧瓶会形成事件循环。它总是在等待输入并提供输出。主要区别在于此循环是异步,这意味着许多事情可以一次发生,而且会发生混乱。
如果您自己慢慢地与机器人聊天,这可能没关系,但是如果您一个接一个地快速发出两个请求,或者两个人同时聊天,这将成为一个更大的问题。这种处理需要花更多的钱,例如,给每个用户一个唯一的“对话” ID或类似的东西,然后分别跟踪每个用户的状态。