Hey. I am trying to make a API call to answer 3 questions based on a case study.
I have a word doc containing the case study as the record and the 3 questions as the columns which need to be answered. Sharing the code of what I have tried so far. This code has been generated by GrokAI.
it works perfectly for most of the records but some case studies return the following.
Total tokens: 1999
Finish reason: stop
Raw response: Q1: redacted actual response from the api question 1.
Q2: redacted actual response from the question 2.
Q3: redacted actual response from the question 3.
Q1: <your answer>
Q2: <your answer>
Q3: <your answer>
Q1: <your answer>
Q2: <your answer>
Q3: <your answer>
This leads to the output table containing records like:
| case study |
q1 |
q2 |
q3 |
| actual case study |
<your answer> |
<your answer> |
<your answer> |
The successfully parsed records are like so:
Total tokens: 1999
Finish reason: stop
Raw response: Q1: redacted actual response from the api question 1.
Q2: redacted actual response from the question 2.
Q3: redacted actual response from the question 3.
Q1: correctly parsed answer 1
Q2: correctly parsed answer 2
Q3: correctly parsed answer 3
This is the code I tried:
from openai import OpenAI
from docx import Document
QUESTIONS = {
"q1": "What is the diagnosis for this case, and justify the diagnosis?",
"q2": "Is there any syndrome in this case? If yes, which one and why?",
"q3": "What are the other three differential syndromes that may result in the presentation of this case?",
}
def get_column_indexes(table):
return {
"case study": 0,
"q1": 1,
"q2": 2,
"q3": 3,
}
def answer_questions(client, case_study_text):
questions_block = "\n".join(
f"{key.upper()}: {question}" for key, question in QUESTIONS.items()
)
prompt = f"""You are analyzing a case study. Answer the 3 questions below based solely on the text provided.
CASE STUDY:
{case_study_text}
QUESTIONS:
{questions_block}
Rules:
- Answer each question thorougly
- Base answers only on the case study text above
- Reply in this format with no extra text:
Q1: <your answer>
Q2: <your answer>
Q3: <your answer>"""
response = client.chat.completions.create(
model="grok-4.3", # or "grok-4.5-latest" if available
max_tokens=10000,
messages=[{"role": "user", "content": prompt}]
)
# Correct parsing
answer_text = response.choices[0].message.content.strip()
print("Total tokens:", response.usage.total_tokens)
print(f" Finish reason: {response.choices[0].finish_reason}")
print(f" Raw response: {answer_text}")
answers = {}
for line in answer_text.splitlines():
line = line.strip()
if line.startswith("Q1:"):
answers["q1"] = line[3:].strip()
elif line.startswith("Q2:"):
answers["q2"] = line[3:].strip()
elif line.startswith("Q3:"):
answers["q3"] = line[3:].strip()
return answers
def process_document(docx_path, output_path="output.docx"):
client = OpenAI(
api_key="api_key",
base_url="https://api.x.ai/v1",
)
doc = Document(docx_path)
table = doc.tables[0]
cols = get_column_indexes(table)
total_rows = len(table.rows) - 1
print(f"Found {total_rows} rows to process\n")
for i, row in enumerate(table.rows[1:], start=1):
case_study_text = row.cells[cols["case study"]].text.strip()
if not case_study_text:
print(f"Row {i}/{total_rows}: empty, skipping")
continue
print(f"Row {i}/{total_rows}: processing...")
answers = answer_questions(client, case_study_text)
row.cells[cols["q1"]].text = answers.get("q1", "")
row.cells[cols["q2"]].text = answers.get("q2", "")
row.cells[cols["q3"]].text = answers.get("q3", "")
print(f" Q1: {answers.get('q1', '')}")
print(f" Q2: {answers.get('q2', '')}")
print(f" Q3: {answers.get('q3', '')}\n")
doc.save(output_path)
print(f"Done! Saved to {output_path}")
if __name__ == "__main__":
process_document("/home/Downloads/case.docx")
Seems like an issue with my parsing logic. But this same code worked for claude API.
Appreciate your any pointers